mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-03-29 17:10:44 +02:00
restore crc32 checksum for the colelction and field ids
This commit is contained in:
parent
83d91b3dd5
commit
8d0e4a0460
@ -3,8 +3,10 @@ package core
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/tools/dbutils"
|
||||
"github.com/pocketbase/pocketbase/tools/hook"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
@ -309,6 +311,7 @@ type baseCollection struct {
|
||||
BaseModel
|
||||
|
||||
disableIntegrityChecks bool
|
||||
autogeneratedId string
|
||||
|
||||
ListRule *string `db:"listRule" json:"listRule" form:"listRule"`
|
||||
ViewRule *string `db:"viewRule" json:"viewRule" form:"viewRule"`
|
||||
@ -364,6 +367,7 @@ func NewBaseCollection(name string, optId ...string) *Collection {
|
||||
m.Name = name
|
||||
m.Type = CollectionTypeBase
|
||||
|
||||
// @todo consider removing once inferred composite literals are supported
|
||||
if len(optId) > 0 {
|
||||
m.Id = optId[0]
|
||||
}
|
||||
@ -383,6 +387,7 @@ func NewViewCollection(name string, optId ...string) *Collection {
|
||||
m.Name = name
|
||||
m.Type = CollectionTypeView
|
||||
|
||||
// @todo consider removing once inferred composite literals are supported
|
||||
if len(optId) > 0 {
|
||||
m.Id = optId[0]
|
||||
}
|
||||
@ -402,6 +407,7 @@ func NewAuthCollection(name string, optId ...string) *Collection {
|
||||
m.Name = name
|
||||
m.Type = CollectionTypeAuth
|
||||
|
||||
// @todo consider removing once inferred composite literals are supported
|
||||
if len(optId) > 0 {
|
||||
m.Id = optId[0]
|
||||
}
|
||||
@ -689,49 +695,82 @@ func onCollectionDeleteExecute(e *CollectionEvent) error {
|
||||
// save hook
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
func (c *Collection) initDefaultId() {
|
||||
if c.Id != "" {
|
||||
return // already set
|
||||
}
|
||||
func (c *Collection) idChecksum() string {
|
||||
return "pbc_" + crc32Checksum(c.Type+c.Name)
|
||||
}
|
||||
|
||||
if c.System && c.Name != "" {
|
||||
// for system collections we use crc32 checksum for consistency because they cannot be renamed
|
||||
c.Id = "pbc_" + crc32Checksum(c.Name)
|
||||
} else {
|
||||
c.Id = "pbc_" + security.RandomStringWithAlphabet(11, DefaultIdAlphabet)
|
||||
func (c *Collection) initDefaultId() {
|
||||
if c.Id == "" {
|
||||
c.Id = c.idChecksum()
|
||||
c.autogeneratedId = c.Id
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collection) savePrepare() error {
|
||||
if c.Type == "" {
|
||||
c.Type = CollectionTypeBase
|
||||
func (c *Collection) updateGeneratedIdIfExists(app App) {
|
||||
if !c.IsNew() ||
|
||||
// the id was explicitly cleared
|
||||
c.Id == "" ||
|
||||
// the id was manually set
|
||||
c.Id != c.autogeneratedId {
|
||||
return
|
||||
}
|
||||
|
||||
if c.IsNew() {
|
||||
c.initDefaultId()
|
||||
c.Created = types.NowDateTime()
|
||||
// generate an up-to-date checksum
|
||||
newId := c.idChecksum()
|
||||
|
||||
// add a number to the current id (if already exists)
|
||||
for i := 2; i < 1000; i++ {
|
||||
var exists bool
|
||||
_ = app.CollectionQuery().Select("(1)").AndWhere(dbx.HashExp{"id": newId}).Limit(1).Row(&exists)
|
||||
if !exists {
|
||||
break
|
||||
}
|
||||
newId = c.idChecksum() + strconv.Itoa(i)
|
||||
}
|
||||
|
||||
c.Updated = types.NowDateTime()
|
||||
|
||||
// recreate the fields list to ensure that all normalizations
|
||||
// like default field id are applied
|
||||
c.Fields = NewFieldsList(c.Fields...)
|
||||
|
||||
c.initDefaultFields()
|
||||
|
||||
if c.IsAuth() {
|
||||
c.unsetMissingOAuth2MappedFields()
|
||||
// no change
|
||||
if c.Id == newId {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
// replace the old id in the index names (if any)
|
||||
for i, idx := range c.Indexes {
|
||||
parsed := dbutils.ParseIndex(idx)
|
||||
original := parsed.IndexName
|
||||
parsed.IndexName = strings.ReplaceAll(parsed.IndexName, c.Id, newId)
|
||||
if parsed.IndexName != original {
|
||||
c.Indexes[i] = parsed.Build()
|
||||
}
|
||||
}
|
||||
|
||||
// update model id
|
||||
c.Id = newId
|
||||
}
|
||||
|
||||
func onCollectionSave(e *CollectionEvent) error {
|
||||
if err := e.Collection.savePrepare(); err != nil {
|
||||
return err
|
||||
if e.Collection.Type == "" {
|
||||
e.Collection.Type = CollectionTypeBase
|
||||
}
|
||||
|
||||
if e.Collection.IsNew() {
|
||||
e.Collection.initDefaultId()
|
||||
e.Collection.Created = types.NowDateTime()
|
||||
}
|
||||
|
||||
e.Collection.Updated = types.NowDateTime()
|
||||
|
||||
// recreate the fields list to ensure that all normalizations
|
||||
// like default field id are applied
|
||||
e.Collection.Fields = NewFieldsList(e.Collection.Fields...)
|
||||
|
||||
e.Collection.initDefaultFields()
|
||||
|
||||
if e.Collection.IsAuth() {
|
||||
e.Collection.unsetMissingOAuth2MappedFields()
|
||||
}
|
||||
|
||||
e.Collection.updateGeneratedIdIfExists(e.App)
|
||||
|
||||
return e.Next()
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,10 @@ type optionsValidator interface {
|
||||
}
|
||||
|
||||
func (validator *collectionValidator) run() error {
|
||||
if validator.original.IsNew() {
|
||||
validator.new.updateGeneratedIdIfExists(validator.app)
|
||||
}
|
||||
|
||||
// generate fields from the query (overwriting any explicit user defined fields)
|
||||
if validator.new.IsView() {
|
||||
validator.new.Fields, _ = validator.app.CreateViewFields(validator.new.ViewQuery)
|
||||
|
@ -4,8 +4,7 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// NewFieldsList creates a new FieldsList instance with the provided fields.
|
||||
@ -171,12 +170,16 @@ func (l *FieldsList) add(newField Field) {
|
||||
// set default id
|
||||
if newFieldId == "" {
|
||||
replaceByName = true
|
||||
if newField.GetSystem() && newField.GetName() != "" {
|
||||
// for system fields we use crc32 checksum for consistency because they cannot be renamed
|
||||
newFieldId = newField.Type() + crc32Checksum(newField.GetName())
|
||||
} else {
|
||||
newFieldId = newField.Type() + security.RandomString(7)
|
||||
|
||||
baseId := newField.Type() + crc32Checksum(newField.GetName())
|
||||
newFieldId = baseId
|
||||
for i := 2; i < 1000; i++ {
|
||||
if l.GetById(newFieldId) == nil {
|
||||
break // already unique
|
||||
}
|
||||
newFieldId = baseId + strconv.Itoa(i)
|
||||
}
|
||||
newField.SetId(newFieldId)
|
||||
}
|
||||
|
||||
// replace existing
|
||||
@ -196,7 +199,6 @@ func (l *FieldsList) add(newField Field) {
|
||||
}
|
||||
|
||||
// add new field
|
||||
newField.SetId(newFieldId)
|
||||
*l = append(fields, newField)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user