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.
|
// 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 {
|
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
|
// @todo consider changing refs to a slice
|
||||||
//
|
//
|
||||||
// Sort the refs keys to ensure that the cascade events firing order is always the same.
|
// 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)
|
recordTableName := inflector.Columnify(refCollection.Name)
|
||||||
prefixedFieldName := recordTableName + "." + inflector.Columnify(field.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() {
|
if opt, ok := field.Options.(schema.MultiValuer); !ok || !opt.IsMultiple() {
|
||||||
query.AndWhere(dbx.HashExp{prefixedFieldName: mainRecord.Id})
|
query.AndWhere(dbx.HashExp{prefixedFieldName: mainRecord.Id})
|
||||||
} else {
|
} else {
|
||||||
query.InnerJoin(fmt.Sprintf(
|
query.AndWhere(dbx.Exists(dbx.NewExp(fmt.Sprintf(
|
||||||
`json_each(CASE WHEN json_valid([[%s]]) THEN [[%s]] ELSE json_array([[%s]]) END) as {{%s}}`,
|
`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, uniqueJsonEachAlias,
|
prefixedFieldName, prefixedFieldName, prefixedFieldName,
|
||||||
), dbx.HashExp{uniqueJsonEachAlias + ".value": mainRecord.Id})
|
), dbx.Params{
|
||||||
|
"jevalue": mainRecord.Id,
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
if refCollection.Id == mainRecord.Collection().Id {
|
if refCollection.Id == mainRecord.Collection().Id {
|
||||||
|
|
|
@ -1205,11 +1205,11 @@ func TestDeleteRecord(t *testing.T) {
|
||||||
}
|
}
|
||||||
// ensure that the json rel fields were prefixed
|
// ensure that the json rel fields were prefixed
|
||||||
joinedQueries := strings.Join(calledQueries, " ")
|
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) {
|
if !strings.Contains(joinedQueries, expectedRelManyPart) {
|
||||||
t.Fatalf("(rec3) Expected the cascade delete to call the query \n%v, got \n%v", expectedRelManyPart, calledQueries)
|
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) {
|
if !strings.Contains(joinedQueries, expectedRelOnePart) {
|
||||||
t.Fatalf("(rec3) Expected the cascade delete to call the query \n%v, got \n%v", expectedRelOnePart, calledQueries)
|
t.Fatalf("(rec3) Expected the cascade delete to call the query \n%v, got \n%v", expectedRelOnePart, calledQueries)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue