package mysqladmin import ( "context" "database/sql" "errors" "time" "git.gocasts.ir/ebhomengo/niki/entity" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" "git.gocasts.ir/ebhomengo/niki/repository/mysql" ) func (d *DB) GetAdminByPhoneNumber(ctx context.Context, phoneNumber string) (entity.Admin, error) { const op = "mysqladmin.GetAdminByPhoneNumber" query := `select * from admins where phone_number = ?` //nolint stmt, err := d.conn.PrepareStatement(ctx, mysql.StatementKeyAdminGetByPhoneNumber, query) if err != nil { return entity.Admin{}, richerror.New(op).WithErr(err). WithMessage(errmsg.ErrorMsgCantPrepareStatement).WithKind(richerror.KindUnexpected) } row := stmt.QueryRowContext(ctx, phoneNumber) admin, err := scanAdmin(row) if err != nil { sErr := sql.ErrNoRows //TODO-errorsas: second argument to errors.As should not be *error //nolint if errors.As(err, &sErr) { return entity.Admin{}, richerror.New(op).WithErr(sErr). WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindNotFound) } // TODO - log unexpected error for better observability return entity.Admin{}, richerror.New(op).WithErr(err). WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) } return admin, nil } func scanAdmin(scanner mysql.Scanner) (entity.Admin, error) { var createdAt, updatedAt time.Time var admin entity.Admin var roleStr, statusStr, password string // TODO - use db model and mapper between entity and db model OR use this approach var adminNullableFields nullableFields err := scanner.Scan(&admin.ID, &adminNullableFields.firstName, &adminNullableFields.lastName, &password, &admin.PhoneNumber, &roleStr, &adminNullableFields.description, &adminNullableFields.email, &adminNullableFields.genderStr, &statusStr, &createdAt, &updatedAt) admin.Role = entity.MapToAdminRole(roleStr) admin.Status = entity.AdminStatus(statusStr) admin.Password = password mapNotNullToAdmin(adminNullableFields, &admin) return admin, err } type nullableFields struct { firstName sql.NullString lastName sql.NullString description sql.NullString email sql.NullString genderStr sql.NullString } // TODO - find the other solution. func mapNotNullToAdmin(data nullableFields, admin *entity.Admin) { if data.firstName.Valid { admin.FirstName = data.firstName.String } if data.lastName.Valid { admin.LastName = data.lastName.String } if data.description.Valid { admin.Description = data.description.String } if data.email.Valid { admin.Email = data.email.String } if data.genderStr.Valid { admin.Gender = entity.Gender(data.genderStr.String) } }