mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-21 13:35:49 +02:00
optimized multiple records cascade delete query
This commit is contained in:
parent
3013e0299a
commit
80d65a198b
@ -659,8 +659,6 @@ func (dao *Dao) DeleteRecord(record *models.Record) error {
|
||||
//
|
||||
// NB! This method is expected to be called inside a transaction.
|
||||
func (dao *Dao) cascadeRecordDelete(mainRecord *models.Record, refs map[*models.Collection][]*schema.SchemaField) error {
|
||||
uniqueJsonEachAlias := "__je__" + security.PseudorandomString(4)
|
||||
|
||||
// @todo consider changing refs to a slice
|
||||
//
|
||||
// Sort the refs keys to ensure that the cascade events firing order is always the same.
|
||||
@ -684,15 +682,17 @@ func (dao *Dao) cascadeRecordDelete(mainRecord *models.Record, refs map[*models.
|
||||
recordTableName := inflector.Columnify(refCollection.Name)
|
||||
prefixedFieldName := recordTableName + "." + inflector.Columnify(field.Name)
|
||||
|
||||
query := dao.RecordQuery(refCollection).Distinct(true)
|
||||
query := dao.RecordQuery(refCollection)
|
||||
|
||||
if opt, ok := field.Options.(schema.MultiValuer); !ok || !opt.IsMultiple() {
|
||||
query.AndWhere(dbx.HashExp{prefixedFieldName: mainRecord.Id})
|
||||
} else {
|
||||
query.InnerJoin(fmt.Sprintf(
|
||||
`json_each(CASE WHEN json_valid([[%s]]) THEN [[%s]] ELSE json_array([[%s]]) END) as {{%s}}`,
|
||||
prefixedFieldName, prefixedFieldName, prefixedFieldName, uniqueJsonEachAlias,
|
||||
), dbx.HashExp{uniqueJsonEachAlias + ".value": mainRecord.Id})
|
||||
query.AndWhere(dbx.Exists(dbx.NewExp(fmt.Sprintf(
|
||||
`SELECT 1 FROM json_each(CASE WHEN json_valid([[%s]]) THEN [[%s]] ELSE json_array([[%s]]) END) {{__je__}} WHERE [[__je__.value]]={:jevalue}`,
|
||||
prefixedFieldName, prefixedFieldName, prefixedFieldName,
|
||||
), dbx.Params{
|
||||
"jevalue": mainRecord.Id,
|
||||
})))
|
||||
}
|
||||
|
||||
if refCollection.Id == mainRecord.Collection().Id {
|
||||
|
@ -1205,11 +1205,11 @@ func TestDeleteRecord(t *testing.T) {
|
||||
}
|
||||
// ensure that the json rel fields were prefixed
|
||||
joinedQueries := strings.Join(calledQueries, " ")
|
||||
expectedRelManyPart := "`demo1` INNER JOIN json_each(CASE WHEN json_valid([[demo1.rel_many]]) THEN [[demo1.rel_many]] ELSE json_array([[demo1.rel_many]]) END)"
|
||||
expectedRelManyPart := "SELECT `demo1`.* FROM `demo1` WHERE EXISTS (SELECT 1 FROM json_each(CASE WHEN json_valid([[demo1.rel_many]]) THEN [[demo1.rel_many]] ELSE json_array([[demo1.rel_many]]) END) {{__je__}} WHERE [[__je__.value]]='"
|
||||
if !strings.Contains(joinedQueries, expectedRelManyPart) {
|
||||
t.Fatalf("(rec3) Expected the cascade delete to call the query \n%v, got \n%v", expectedRelManyPart, calledQueries)
|
||||
}
|
||||
expectedRelOnePart := "SELECT DISTINCT `demo1`.* FROM `demo1` WHERE (`demo1`.`rel_one`="
|
||||
expectedRelOnePart := "SELECT `demo1`.* FROM `demo1` WHERE (`demo1`.`rel_one`='"
|
||||
if !strings.Contains(joinedQueries, expectedRelOnePart) {
|
||||
t.Fatalf("(rec3) Expected the cascade delete to call the query \n%v, got \n%v", expectedRelOnePart, calledQueries)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user