ValidateValue implements [Field.ValidateValue] interface method.
(ctx context.Context, app App, record *Record)
| 177 | |
| 178 | // ValidateValue implements [Field.ValidateValue] interface method. |
| 179 | func (f *TextField) ValidateValue(ctx context.Context, app App, record *Record) error { |
| 180 | newVal, ok := record.GetRaw(f.Name).(string) |
| 181 | if !ok { |
| 182 | return validators.ErrUnsupportedValueType |
| 183 | } |
| 184 | |
| 185 | if f.PrimaryKey { |
| 186 | // disallow PK change |
| 187 | if !record.IsNew() { |
| 188 | oldVal := record.LastSavedPK() |
| 189 | if oldVal != newVal { |
| 190 | return validation.NewError("validation_pk_change", "The record primary key cannot be changed.") |
| 191 | } |
| 192 | if oldVal != "" { |
| 193 | // no need to further validate because the id can't be updated |
| 194 | // and because the id could have been inserted manually by migration from another system |
| 195 | // that may not comply with the user defined PocketBase validations |
| 196 | return nil |
| 197 | } |
| 198 | } else { |
| 199 | // this technically shouldn't be necessarily but again to |
| 200 | // minimize misuse of the Pattern validator that could cause |
| 201 | // side-effects on some platforms check for duplicates in a case-insensitive manner |
| 202 | // |
| 203 | // (@todo eventually may get replaced in the future with a system unique constraint to avoid races or wrapping the request in a transaction) |
| 204 | if f.Pattern != defaultLowercaseRecordIdPattern { |
| 205 | var exists int |
| 206 | err := app.ConcurrentDB(). |
| 207 | Select("(1)"). |
| 208 | From(record.TableName()). |
| 209 | Where(dbx.NewExp("id = {:id} COLLATE NOCASE", dbx.Params{"id": newVal})). |
| 210 | Limit(1). |
| 211 | Row(&exists) |
| 212 | if exists > 0 || (err != nil && !errors.Is(err, sql.ErrNoRows)) { |
| 213 | return validation.NewError("validation_pk_invalid", "The record primary key is invalid or already exists.") |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | return f.ValidatePlainValue(newVal) |
| 220 | } |
| 221 | |
| 222 | // ValidatePlainValue validates the provided string against the field options. |
| 223 | func (f *TextField) ValidatePlainValue(value string) error { |
nothing calls this directly
no test coverage detected