Finish basic offline sync logic
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Garrett Mills 2020-10-30 21:59:42 -05:00
parent 135f55f9c2
commit dffb3d9efa
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
4 changed files with 147 additions and 6 deletions

View File

@ -32,6 +32,13 @@ class File extends Controller {
FileIds: [], FileIds: [],
}) })
if ( req.body.UUID ) {
const existingUUID = await FileGroup.findOne({ UUID: req.body.UUID })
if ( !existingUUID ) {
group.UUID = req.body.UUID
}
}
await group.save() await group.save()
req.user.allow(`files:${group.UUID}`) req.user.allow(`files:${group.UUID}`)
await req.user.save() await req.user.save()

View File

@ -25,11 +25,18 @@ class FormDatabase extends Controller {
if ( !node ) return res.status(404).message('Node not found with that ID.').api({}) if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const db = new Database({ const db = new Database({
Name: req.body.name ? req.body.name : 'New Database', Name: req.body.name || req.body.Name || 'New Database',
NodeId: node.UUID, NodeId: node.UUID,
PageId: page.UUID, PageId: page.UUID,
}) })
if ( req.body.UUID ) {
const existingUUID = await Database.findOne({ UUID: req.body.UUID })
if ( !existingUUID ) {
db.UUID = req.body.UUID
}
}
await db.save() await db.save()
req.user.allow(`database:${db.UUID}`); req.user.allow(`database:${db.UUID}`);
@ -162,6 +169,13 @@ class FormDatabase extends Controller {
additionalData: JSON.stringify(col.additionalData), additionalData: JSON.stringify(col.additionalData),
}) })
if ( col.UUID ) {
const existingUUID = await ColumnDef.findOne({ UUID: col.UUID })
if ( !existingUUID ) {
new_col.UUID = col.UUID
}
}
await new_col.save() await new_col.save()
update_columns.push(new_col) update_columns.push(new_col)
} }

View File

@ -52,9 +52,6 @@ class OfflineController extends Controller {
const OfflineDataSync = this.models.get('api:OfflineDataSync') const OfflineDataSync = this.models.get('api:OfflineDataSync')
const record = await OfflineDataSync.from_request(req) const record = await OfflineDataSync.from_request(req)
console.log('sync data', record)
const return_maps = {} const return_maps = {}
// pages // pages
@ -73,13 +70,136 @@ class OfflineController extends Controller {
} }
// databases // databases
if ( Array.isArray(record.databases) ) {
return_maps.databases = await this.do_sync_databases(req, record.databases)
}
// databaseColumns // databaseColumns
if ( Array.isArray(record.databaseColumns) ) {
return_maps.databaseColumns = await this.do_sync_database_columns(req, record.databases, record.databaseColumns)
}
// databaseEntries // databaseEntries
if ( Array.isArray(record.databaseEntries) ) {
return_maps.databaseEntries = await this.do_sync_database_entries(req, record.databases, record.databaseEntries)
}
// fileGroups // fileGroups
if ( Array.isArray(record.fileGroups) ) {
return_maps.fileGroups = await this.do_sync_file_groups(req, record.fileGroups)
}
return res.api(return_maps) return res.api(return_maps)
} }
async do_sync_file_groups(req, file_recs) {
const FileController = this.controllers.get('api:v1:File')
const FileGroup = this.models.get('api:FileGroup')
const uuid_mapping = {}
for ( const rec of file_recs ) {
const existing_rec = await FileGroup.findOne({ UUID: rec.UUID })
const fake_req = this.app.di().make(FakeRequest)
await fake_req.inflate(req)
fake_req.params = { PageId: rec.PageId, NodeId: rec.NodeId, FilesId: rec.UUID }
fake_req.body = rec
if ( existing_rec && rec.deleted ) {
await FileController.delete_group(fake_req, fake_req.response)
uuid_mapping[rec.UUID] = false
} else if ( !existing_rec ) {
await FileController.create_config(fake_req, fake_req.response)
uuid_mapping[rec.UUID] = fake_req.response?._api_data?.UUID
}
// Currently, there's no reason to update a file group, since they have no internal metadata
}
return uuid_mapping
}
async do_sync_database_entries(req, database_recs, database_row_recs) {
const FormDatabaseController = this.controllers.get('api:v1:FormDatabase')
const uuid_mapping = {}
for ( const rec of database_recs ) {
const entries = database_row_recs.filter(x => !x.deleted && x.DatabaseId === rec.UUID)
const fake_req = this.app.di().make(FakeRequest)
await fake_req.inflate(req)
fake_req.params = { PageId: rec.PageId, NodeId: rec.NodeId, DatabaseId: rec.UUID }
fake_req.body = entries.map(x => JSON.parse(x.RowDataJSON || '{}'))
await FormDatabaseController.set_data(fake_req, fake_req.response)
entries.forEach((rec, i) => {
uuid_mapping[rec.UUID] = fake_req.response?._api_data?.[i]?.UUID
})
}
return uuid_mapping
}
async do_sync_database_columns(req, database_recs, database_col_recs) {
const FormDatabaseController = this.controllers.get('api:v1:FormDatabase')
const uuid_mapping = {}
for ( const rec of database_recs ) {
const col_recs = database_col_recs.filter(x => rec.ColumnIds.includes(x.UUID) && !x.deleted)
const fake_req = this.app.di().make(FakeRequest)
await fake_req.inflate(req)
fake_req.params = { PageId: rec.PageId, NodeId: rec.NodeId, DatabaseId: rec.UUID }
fake_req.body = { columns: col_recs }
await FormDatabaseController.set_columns(fake_req, fake_req.response)
col_recs.forEach((rec, i) => {
uuid_mapping[rec.UUID] = fake_req.response?._api_data?.[i]?.UUID
})
}
return uuid_mapping
}
async do_sync_databases(req, database_recs) {
const FormDatabaseController = this.controllers.get('api:v1:FormDatabase')
const Database = this.models.get('api:db:Database')
const uuid_mapping = {}
for ( const rec of database_recs ) {
const existing_db = await Database.findOne({ UUID: rec.UUID })
const fake_req = this.app.di().make(FakeRequest)
await fake_req.inflate(req)
fake_req.params = { PageId: rec.PageId, NodeId: rec.NodeId, DatabaseId: rec.UUID }
fake_req.body = rec
if ( !existing_db && !rec.deleted ) {
// this was created on the client side
await FormDatabaseController.create_new(fake_req, fake_req.response)
uuid_mapping[rec.UUID] = fake_req.response?._api_data?.UUID
} else {
if ( rec.deleted ) {
// the database was deleted
await FormDatabaseController.drop_database(fake_req, fake_req.response)
uuid_mapping[rec.UUID] = false
} else {
// the database was updated
await FormDatabaseController.set_name(fake_req, fake_req.response)
uuid_mapping[rec.UUID] = fake_req.response?._api_data?.UUID
}
}
}
return uuid_mapping
}
async do_sync_codiums(req, codium_recs) { async do_sync_codiums(req, codium_recs) {
const FormCodeController = this.controllers.get('api:v1:FormCode') const FormCodeController = this.controllers.get('api:v1:FormCode')
const Codium = this.models.get('api:Codium') const Codium = this.models.get('api:Codium')

View File

@ -8,7 +8,7 @@ class OfflineDataSyncModel extends Model {
sync_timestamp: { type: Date, default: () => new Date() }, sync_timestamp: { type: Date, default: () => new Date() },
UUID: { type: String, default: uuid }, UUID: { type: String, default: uuid },
codiums: [Object], codiums: [Object],
database: [Object], databases: [Object],
databaseColumns: [Object], databaseColumns: [Object],
databaseEntries: [Object], databaseEntries: [Object],
fileGroups: [Object], fileGroups: [Object],
@ -21,7 +21,7 @@ class OfflineDataSyncModel extends Model {
const rec = new this({ const rec = new this({
user_id: req.user.id, user_id: req.user.id,
codiums: req.body?.dirtyRecords.codiums, codiums: req.body?.dirtyRecords.codiums,
database: req.body?.dirtyRecords.database, databases: req.body?.dirtyRecords.databases,
databaseColumns: req.body?.dirtyRecords.databaseColumns, databaseColumns: req.body?.dirtyRecords.databaseColumns,
databaseEntries: req.body?.dirtyRecords.databaseEntries, databaseEntries: req.body?.dirtyRecords.databaseEntries,
fileGroups: req.body?.dirtyRecords.fileGroups, fileGroups: req.body?.dirtyRecords.fileGroups,