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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
"github.com/pocketbase/pocketbase/tools/dbutils"
|
"github.com/pocketbase/pocketbase/tools/dbutils"
|
||||||
"github.com/pocketbase/pocketbase/tools/hook"
|
"github.com/pocketbase/pocketbase/tools/hook"
|
||||||
"github.com/pocketbase/pocketbase/tools/security"
|
"github.com/pocketbase/pocketbase/tools/security"
|
||||||
|
@ -309,6 +311,7 @@ type baseCollection struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
disableIntegrityChecks bool
|
disableIntegrityChecks bool
|
||||||
|
autogeneratedId string
|
||||||
|
|
||||||
ListRule *string `db:"listRule" json:"listRule" form:"listRule"`
|
ListRule *string `db:"listRule" json:"listRule" form:"listRule"`
|
||||||
ViewRule *string `db:"viewRule" json:"viewRule" form:"viewRule"`
|
ViewRule *string `db:"viewRule" json:"viewRule" form:"viewRule"`
|
||||||
|
@ -364,6 +367,7 @@ func NewBaseCollection(name string, optId ...string) *Collection {
|
||||||
m.Name = name
|
m.Name = name
|
||||||
m.Type = CollectionTypeBase
|
m.Type = CollectionTypeBase
|
||||||
|
|
||||||
|
// @todo consider removing once inferred composite literals are supported
|
||||||
if len(optId) > 0 {
|
if len(optId) > 0 {
|
||||||
m.Id = optId[0]
|
m.Id = optId[0]
|
||||||
}
|
}
|
||||||
|
@ -383,6 +387,7 @@ func NewViewCollection(name string, optId ...string) *Collection {
|
||||||
m.Name = name
|
m.Name = name
|
||||||
m.Type = CollectionTypeView
|
m.Type = CollectionTypeView
|
||||||
|
|
||||||
|
// @todo consider removing once inferred composite literals are supported
|
||||||
if len(optId) > 0 {
|
if len(optId) > 0 {
|
||||||
m.Id = optId[0]
|
m.Id = optId[0]
|
||||||
}
|
}
|
||||||
|
@ -402,6 +407,7 @@ func NewAuthCollection(name string, optId ...string) *Collection {
|
||||||
m.Name = name
|
m.Name = name
|
||||||
m.Type = CollectionTypeAuth
|
m.Type = CollectionTypeAuth
|
||||||
|
|
||||||
|
// @todo consider removing once inferred composite literals are supported
|
||||||
if len(optId) > 0 {
|
if len(optId) > 0 {
|
||||||
m.Id = optId[0]
|
m.Id = optId[0]
|
||||||
}
|
}
|
||||||
|
@ -689,49 +695,82 @@ func onCollectionDeleteExecute(e *CollectionEvent) error {
|
||||||
// save hook
|
// save hook
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func (c *Collection) initDefaultId() {
|
func (c *Collection) idChecksum() string {
|
||||||
if c.Id != "" {
|
return "pbc_" + crc32Checksum(c.Type+c.Name)
|
||||||
return // already set
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if c.System && c.Name != "" {
|
func (c *Collection) initDefaultId() {
|
||||||
// for system collections we use crc32 checksum for consistency because they cannot be renamed
|
if c.Id == "" {
|
||||||
c.Id = "pbc_" + crc32Checksum(c.Name)
|
c.Id = c.idChecksum()
|
||||||
} else {
|
c.autogeneratedId = c.Id
|
||||||
c.Id = "pbc_" + security.RandomStringWithAlphabet(11, DefaultIdAlphabet)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection) savePrepare() error {
|
func (c *Collection) updateGeneratedIdIfExists(app App) {
|
||||||
if c.Type == "" {
|
if !c.IsNew() ||
|
||||||
c.Type = CollectionTypeBase
|
// the id was explicitly cleared
|
||||||
|
c.Id == "" ||
|
||||||
|
// the id was manually set
|
||||||
|
c.Id != c.autogeneratedId {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.IsNew() {
|
// generate an up-to-date checksum
|
||||||
c.initDefaultId()
|
newId := c.idChecksum()
|
||||||
c.Created = types.NowDateTime()
|
|
||||||
|
// 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()
|
// no change
|
||||||
|
if c.Id == newId {
|
||||||
// recreate the fields list to ensure that all normalizations
|
return
|
||||||
// like default field id are applied
|
|
||||||
c.Fields = NewFieldsList(c.Fields...)
|
|
||||||
|
|
||||||
c.initDefaultFields()
|
|
||||||
|
|
||||||
if c.IsAuth() {
|
|
||||||
c.unsetMissingOAuth2MappedFields()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
func onCollectionSave(e *CollectionEvent) error {
|
||||||
if err := e.Collection.savePrepare(); err != nil {
|
if e.Collection.Type == "" {
|
||||||
return err
|
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()
|
return e.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,10 @@ type optionsValidator interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (validator *collectionValidator) run() error {
|
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)
|
// generate fields from the query (overwriting any explicit user defined fields)
|
||||||
if validator.new.IsView() {
|
if validator.new.IsView() {
|
||||||
validator.new.Fields, _ = validator.app.CreateViewFields(validator.new.ViewQuery)
|
validator.new.Fields, _ = validator.app.CreateViewFields(validator.new.ViewQuery)
|
||||||
|
|
|
@ -4,8 +4,7 @@ import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"github.com/pocketbase/pocketbase/tools/security"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFieldsList creates a new FieldsList instance with the provided fields.
|
// NewFieldsList creates a new FieldsList instance with the provided fields.
|
||||||
|
@ -171,12 +170,16 @@ func (l *FieldsList) add(newField Field) {
|
||||||
// set default id
|
// set default id
|
||||||
if newFieldId == "" {
|
if newFieldId == "" {
|
||||||
replaceByName = true
|
replaceByName = true
|
||||||
if newField.GetSystem() && newField.GetName() != "" {
|
|
||||||
// for system fields we use crc32 checksum for consistency because they cannot be renamed
|
baseId := newField.Type() + crc32Checksum(newField.GetName())
|
||||||
newFieldId = newField.Type() + crc32Checksum(newField.GetName())
|
newFieldId = baseId
|
||||||
} else {
|
for i := 2; i < 1000; i++ {
|
||||||
newFieldId = newField.Type() + security.RandomString(7)
|
if l.GetById(newFieldId) == nil {
|
||||||
|
break // already unique
|
||||||
|
}
|
||||||
|
newFieldId = baseId + strconv.Itoa(i)
|
||||||
}
|
}
|
||||||
|
newField.SetId(newFieldId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace existing
|
// replace existing
|
||||||
|
@ -196,7 +199,6 @@ func (l *FieldsList) add(newField Field) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new field
|
// add new field
|
||||||
newField.SetId(newFieldId)
|
|
||||||
*l = append(fields, newField)
|
*l = append(fields, newField)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue