From 94d2f296b22f9fff816dedb25f42b56ce200d784 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Sun, 12 Mar 2023 16:43:27 +0200 Subject: [PATCH] [#2044] fixed view collections import --- daos/collection.go | 65 +++++++++++++++++--------------- forms/collections_import.go | 6 +-- forms/collections_import_test.go | 46 ++++++++++++++++++++++ 3 files changed, 83 insertions(+), 34 deletions(-) diff --git a/daos/collection.go b/daos/collection.go index f565c37f..779e9a0e 100644 --- a/daos/collection.go +++ b/daos/collection.go @@ -198,7 +198,7 @@ func (dao *Dao) SaveCollection(collection *models.Collection) error { func (dao *Dao) ImportCollections( importedCollections []*models.Collection, deleteMissing bool, - beforeRecordsSync func(txDao *Dao, mappedImported, mappedExisting map[string]*models.Collection) error, + afterSync func(txDao *Dao, mappedImported, mappedExisting map[string]*models.Collection) error, ) error { if len(importedCollections) == 0 { return errors.New("No collections to import") @@ -206,7 +206,7 @@ func (dao *Dao) ImportCollections( return dao.RunInTransaction(func(txDao *Dao) error { existingCollections := []*models.Collection{} - if err := txDao.CollectionQuery().OrderBy("created ASC").All(&existingCollections); err != nil { + if err := txDao.CollectionQuery().OrderBy("updated ASC").All(&existingCollections); err != nil { return err } mappedExisting := make(map[string]*models.Collection, len(existingCollections)) @@ -262,6 +262,17 @@ func (dao *Dao) ImportCollections( return fmt.Errorf("System collection %q cannot be deleted.", existing.Name) } + // delete the related records table or view + if existing.IsView() { + if err := txDao.DeleteView(existing.Name); err != nil { + return err + } + } else { + if err := txDao.DeleteTable(existing.Name); err != nil { + return err + } + } + // delete the collection if err := txDao.Delete(existing); err != nil { return err @@ -276,43 +287,35 @@ func (dao *Dao) ImportCollections( } } - if beforeRecordsSync != nil { - if err := beforeRecordsSync(txDao, mappedImported, mappedExisting); err != nil { + // sync record tables + for _, imported := range importedCollections { + if imported.IsView() { + continue + } + + existing := mappedExisting[imported.GetId()] + + if err := txDao.SyncRecordTableSchema(imported, existing); err != nil { return err } } - // delete the record tables of the deleted collections - if deleteMissing { - for _, existing := range existingCollections { - if mappedImported[existing.GetId()] != nil { - continue // exist - } + // sync views + for _, imported := range importedCollections { + if !imported.IsView() { + continue + } - if existing.IsView() { - if err := txDao.DeleteView(existing.Name); err != nil { - return err - } - } else { - if err := txDao.DeleteTable(existing.Name); err != nil { - return err - } - } + existing := mappedExisting[imported.GetId()] + + if err := txDao.saveViewCollection(imported, existing); err != nil { + return err } } - // sync the upserted collections with the related records table - for _, imported := range importedCollections { - existing := mappedExisting[imported.GetId()] - - if imported.IsView() { - if err := txDao.saveViewCollection(imported, existing); err != nil { - return err - } - } else { - if err := txDao.SyncRecordTableSchema(imported, existing); err != nil { - return err - } + if afterSync != nil { + if err := afterSync(txDao, mappedImported, mappedExisting); err != nil { + return err } } diff --git a/forms/collections_import.go b/forms/collections_import.go index b6618c66..70d8be82 100644 --- a/forms/collections_import.go +++ b/forms/collections_import.go @@ -66,7 +66,7 @@ func (form *CollectionsImport) Submit(interceptors ...InterceptorFunc[[]*models. importErr := txDao.ImportCollections( collections, form.DeleteMissing, - form.beforeRecordsSync, + form.afterSync, ) if importErr == nil { return nil @@ -89,10 +89,10 @@ func (form *CollectionsImport) Submit(interceptors ...InterceptorFunc[[]*models. }, interceptors...) } -func (form *CollectionsImport) beforeRecordsSync(txDao *daos.Dao, mappedNew, mappedOld map[string]*models.Collection) error { +func (form *CollectionsImport) afterSync(txDao *daos.Dao, mappedNew, mappedOld map[string]*models.Collection) error { // refresh the actual persisted collections list refreshedCollections := []*models.Collection{} - if err := txDao.CollectionQuery().OrderBy("created ASC").All(&refreshedCollections); err != nil { + if err := txDao.CollectionQuery().OrderBy("updated ASC").All(&refreshedCollections); err != nil { return err } diff --git a/forms/collections_import_test.go b/forms/collections_import_test.go index 945812b7..1fcf5b05 100644 --- a/forms/collections_import_test.go +++ b/forms/collections_import_test.go @@ -347,6 +347,52 @@ func TestCollectionsImportSubmit(t *testing.T) { "OnModelAfterDelete": totalCollections - 2, }, }, + { + name: "lazy view evaluation", + jsonData: `{ + "collections": [ + { + "name": "view_before", + "type": "view", + "options": { + "query": "select id, active from base_test" + } + }, + { + "name": "base_test", + "schema": [ + { + "id":"fz6iql2m", + "name":"active", + "type":"bool" + } + ] + }, + { + "name": "view_after_new", + "type": "view", + "options": { + "query": "select id, active from base_test" + } + }, + { + "name": "view_after_old", + "type": "view", + "options": { + "query": "select id from demo1" + } + } + ] + }`, + expectError: false, + expectCollectionsCount: totalCollections + 4, + expectEvents: map[string]int{ + "OnModelBeforeUpdate": 3, + "OnModelAfterUpdate": 3, + "OnModelBeforeCreate": 4, + "OnModelAfterCreate": 4, + }, + }, } for _, s := range scenarios {