added unique id validator error
This commit is contained in:
		
							parent
							
								
									1f46b30895
								
							
						
					
					
						commit
						59e4939e1d
					
				| 
						 | 
					@ -57,6 +57,7 @@ func (form *AdminUpsert) Validate() error {
 | 
				
			||||||
				form.admin.IsNew(),
 | 
									form.admin.IsNew(),
 | 
				
			||||||
				validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
									validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
				
			||||||
				validation.Match(idRegex),
 | 
									validation.Match(idRegex),
 | 
				
			||||||
 | 
									validation.By(validators.UniqueId(form.dao, form.admin.TableName())),
 | 
				
			||||||
			).Else(validation.In(form.admin.Id)),
 | 
								).Else(validation.In(form.admin.Id)),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
		validation.Field(
 | 
							validation.Field(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import (
 | 
				
			||||||
	validation "github.com/go-ozzo/ozzo-validation/v4"
 | 
						validation "github.com/go-ozzo/ozzo-validation/v4"
 | 
				
			||||||
	"github.com/pocketbase/pocketbase/core"
 | 
						"github.com/pocketbase/pocketbase/core"
 | 
				
			||||||
	"github.com/pocketbase/pocketbase/daos"
 | 
						"github.com/pocketbase/pocketbase/daos"
 | 
				
			||||||
 | 
						"github.com/pocketbase/pocketbase/forms/validators"
 | 
				
			||||||
	"github.com/pocketbase/pocketbase/models"
 | 
						"github.com/pocketbase/pocketbase/models"
 | 
				
			||||||
	"github.com/pocketbase/pocketbase/models/schema"
 | 
						"github.com/pocketbase/pocketbase/models/schema"
 | 
				
			||||||
	"github.com/pocketbase/pocketbase/resolvers"
 | 
						"github.com/pocketbase/pocketbase/resolvers"
 | 
				
			||||||
| 
						 | 
					@ -93,6 +94,7 @@ func (form *CollectionUpsert) Validate() error {
 | 
				
			||||||
				form.collection.IsNew(),
 | 
									form.collection.IsNew(),
 | 
				
			||||||
				validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
									validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
				
			||||||
				validation.Match(idRegex),
 | 
									validation.Match(idRegex),
 | 
				
			||||||
 | 
									validation.By(validators.UniqueId(form.dao, form.collection.TableName())),
 | 
				
			||||||
			).Else(validation.In(form.collection.Id)),
 | 
								).Else(validation.In(form.collection.Id)),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
		validation.Field(
 | 
							validation.Field(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,6 +455,7 @@ func (form *RecordUpsert) Validate() error {
 | 
				
			||||||
				form.record.IsNew(),
 | 
									form.record.IsNew(),
 | 
				
			||||||
				validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
									validation.Length(models.DefaultIdLength, models.DefaultIdLength),
 | 
				
			||||||
				validation.Match(idRegex),
 | 
									validation.Match(idRegex),
 | 
				
			||||||
 | 
									validation.By(validators.UniqueId(form.dao, form.record.TableName())),
 | 
				
			||||||
			).Else(validation.In(form.record.Id)),
 | 
								).Else(validation.In(form.record.Id)),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					package validators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"database/sql"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validation "github.com/go-ozzo/ozzo-validation/v4"
 | 
				
			||||||
 | 
						"github.com/pocketbase/dbx"
 | 
				
			||||||
 | 
						"github.com/pocketbase/pocketbase/daos"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compare checks whether the provided model id exists.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example:
 | 
				
			||||||
 | 
					//	validation.Field(&form.Id, validation.By(validators.UniqueId(form.dao, tableName)))
 | 
				
			||||||
 | 
					func UniqueId(dao *daos.Dao, tableName string) validation.RuleFunc {
 | 
				
			||||||
 | 
						return func(value any) error {
 | 
				
			||||||
 | 
							v, _ := value.(string)
 | 
				
			||||||
 | 
							if v == "" {
 | 
				
			||||||
 | 
								return nil // nothing to check
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var foundId string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err := dao.DB().
 | 
				
			||||||
 | 
								Select("id").
 | 
				
			||||||
 | 
								From(tableName).
 | 
				
			||||||
 | 
								Where(dbx.HashExp{"id": v}).
 | 
				
			||||||
 | 
								Limit(1).
 | 
				
			||||||
 | 
								Row(&foundId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !errors.Is(err, sql.ErrNoRows) || foundId != "" {
 | 
				
			||||||
 | 
								return validation.NewError("validation_invalid_id", "The model id is invalid or already exists.")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					package validators_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/pocketbase/pocketbase/forms/validators"
 | 
				
			||||||
 | 
						"github.com/pocketbase/pocketbase/tests"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestUniqueId(t *testing.T) {
 | 
				
			||||||
 | 
						app, _ := tests.NewTestApp()
 | 
				
			||||||
 | 
						defer app.Cleanup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scenarios := []struct {
 | 
				
			||||||
 | 
							id          string
 | 
				
			||||||
 | 
							tableName   string
 | 
				
			||||||
 | 
							expectError bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"", "", false},
 | 
				
			||||||
 | 
							{"test", "", true},
 | 
				
			||||||
 | 
							{"wsmn24bux7wo113", "_collections", true},
 | 
				
			||||||
 | 
							{"test_unique_id", "unknown_table", true},
 | 
				
			||||||
 | 
							{"test_unique_id", "_collections", false},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, s := range scenarios {
 | 
				
			||||||
 | 
							err := validators.UniqueId(app.Dao(), s.tableName)(s.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hasErr := err != nil
 | 
				
			||||||
 | 
							if hasErr != s.expectError {
 | 
				
			||||||
 | 
								t.Errorf("(%d) Expected hasErr to be %v, got %v (%v)", i, s.expectError, hasErr, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue