Add offline cachine for file group elements and contents (not files, though)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -10,6 +10,7 @@ import {Codium} from './db/Codium';
|
||||
import {Database} from './db/Database';
|
||||
import {DatabaseColumn} from './db/DatabaseColumn';
|
||||
import {DatabaseEntry} from './db/DatabaseEntry';
|
||||
import {FileGroup} from "./db/FileGroup";
|
||||
|
||||
export class ResourceNotAvailableOfflineError extends Error {
|
||||
constructor(msg = 'This resource is not yet available offline on this device.') {
|
||||
@@ -703,4 +704,101 @@ export class ApiService {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public deleteFileGroup(PageId: string, NodeId: string, FileGroupId: string): Promise<void> {
|
||||
return new Promise(async (res, rej) => {
|
||||
const existingFileGroup = await this.db.fileGroups.where({ UUID: FileGroupId }).first() as FileGroup;
|
||||
|
||||
if ( this.isOffline ) {
|
||||
if ( existingFileGroup ) {
|
||||
existingFileGroup.deleted = true;
|
||||
existingFileGroup.needsServerUpdate = true;
|
||||
await existingFileGroup.save();
|
||||
return res();
|
||||
} else {
|
||||
return rej(new ResourceNotAvailableOfflineError());
|
||||
}
|
||||
}
|
||||
|
||||
this.post(`/files/${PageId}/${NodeId}/delete/${FileGroupId}`).subscribe({
|
||||
next: async result => {
|
||||
if ( existingFileGroup ) {
|
||||
await this.db.fileGroups.delete(existingFileGroup.id);
|
||||
res();
|
||||
}
|
||||
},
|
||||
error: rej,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public createFileGroup(PageId: string, NodeId: string): Promise<any> {
|
||||
return new Promise(async (res, rej) => {
|
||||
if ( this.isOffline ) {
|
||||
const newFileGroup = new FileGroup(
|
||||
NodeId,
|
||||
PageId,
|
||||
[],
|
||||
JSON.stringify([]),
|
||||
FileGroup.getUUID(),
|
||||
true
|
||||
);
|
||||
|
||||
await newFileGroup.save();
|
||||
return res(newFileGroup.inflateToRecord());
|
||||
}
|
||||
|
||||
this.post(`/files/${PageId}/${NodeId}/create`).subscribe({
|
||||
next: async result => {
|
||||
const newFileGroup = new FileGroup(
|
||||
result.data.NodeId,
|
||||
result.data.PageId,
|
||||
result.data.FileIds,
|
||||
JSON.stringify(result.data.files),
|
||||
result.data.UUID
|
||||
);
|
||||
|
||||
await newFileGroup.save();
|
||||
res(result.data);
|
||||
},
|
||||
error: rej,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public getFileGroup(PageId: string, NodeId: string, FileGroupId: string): Promise<any> {
|
||||
return new Promise(async (res, rej) => {
|
||||
const existingFileGroup = await this.db.fileGroups.where({ UUID: FileGroupId }).first() as FileGroup;
|
||||
if ( this.isOffline ) {
|
||||
if ( existingFileGroup ) {
|
||||
return res(existingFileGroup.inflateToRecord());
|
||||
} else {
|
||||
return rej(new ResourceNotAvailableOfflineError());
|
||||
}
|
||||
}
|
||||
|
||||
this.get(`/files/${PageId}/${NodeId}/get/${FileGroupId}`).subscribe({
|
||||
next: async result => {
|
||||
if ( existingFileGroup ) {
|
||||
existingFileGroup.fillFromRecord(result.data);
|
||||
existingFileGroup.needsServerUpdate = false;
|
||||
await existingFileGroup.save();
|
||||
} else {
|
||||
const newFileGroup = new FileGroup(
|
||||
result.data.NodeId,
|
||||
result.data.PageId,
|
||||
result.data.FileIds,
|
||||
JSON.stringify(result.data.files),
|
||||
result.data.UUID
|
||||
);
|
||||
|
||||
await newFileGroup.save();
|
||||
}
|
||||
|
||||
res(result.data);
|
||||
},
|
||||
error: rej,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
97
src/app/service/db/FileGroup.ts
Normal file
97
src/app/service/db/FileGroup.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import {Model} from './Model';
|
||||
|
||||
export interface IFileGroup {
|
||||
id?: number;
|
||||
NodeId: string;
|
||||
PageId: string;
|
||||
FileIds: string[];
|
||||
filesJSON: string;
|
||||
UUID: string;
|
||||
needsServerUpdate?: boolean;
|
||||
deleted?: boolean;
|
||||
}
|
||||
|
||||
export class FileGroup extends Model<IFileGroup> implements IFileGroup {
|
||||
id?: number;
|
||||
NodeId: string;
|
||||
PageId: string;
|
||||
FileIds: string[];
|
||||
filesJSON: string;
|
||||
UUID: string;
|
||||
needsServerUpdate?: boolean;
|
||||
deleted?: boolean;
|
||||
|
||||
public static getTableName() {
|
||||
return 'fileGroups';
|
||||
}
|
||||
|
||||
public static getSchema() {
|
||||
return '++id, NodeId, PageId, FileIds, filesJSON, UUID, needsServerUpdate, deleted';
|
||||
}
|
||||
|
||||
constructor(
|
||||
NodeId: string,
|
||||
PageId: string,
|
||||
FileIds: string[],
|
||||
filesJSON: string,
|
||||
UUID: string,
|
||||
needsServerUpdate?: boolean,
|
||||
deleted?: boolean,
|
||||
id?: number
|
||||
) {
|
||||
super();
|
||||
|
||||
this.NodeId = NodeId;
|
||||
this.PageId = PageId;
|
||||
this.FileIds = FileIds;
|
||||
this.filesJSON = filesJSON;
|
||||
this.UUID = UUID;
|
||||
|
||||
if ( typeof needsServerUpdate !== 'undefined' ) {
|
||||
this.needsServerUpdate = needsServerUpdate;
|
||||
}
|
||||
|
||||
if ( typeof deleted !== 'undefined' ) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
if ( id ) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
public fillFromRecord(record: any) {
|
||||
this.NodeId = record.NodeId;
|
||||
this.PageId = record.PageId;
|
||||
this.FileIds = record.FileIds;
|
||||
this.filesJSON = JSON.stringify(record.files);
|
||||
this.UUID = record.UUID;
|
||||
}
|
||||
|
||||
public inflateToRecord() {
|
||||
return {
|
||||
NodeId: this.NodeId,
|
||||
PageId: this.PageId,
|
||||
FileIds: this.FileIds,
|
||||
files: JSON.parse(this.filesJSON),
|
||||
UUID: this.UUID,
|
||||
};
|
||||
}
|
||||
|
||||
public getSaveRecord(): any {
|
||||
return {
|
||||
...(this.id ? { id: this.id } : {}),
|
||||
NodeId: this.NodeId,
|
||||
PageId: this.PageId,
|
||||
FileIds: this.FileIds,
|
||||
filesJSON: this.filesJSON,
|
||||
UUID: this.UUID,
|
||||
...(typeof this.needsServerUpdate === 'undefined' ? {} : { needsServerUpdate: this.needsServerUpdate }),
|
||||
...(typeof this.deleted === 'undefined' ? {} : { deleted: this.deleted }),
|
||||
};
|
||||
}
|
||||
|
||||
public getDatabase(): Dexie.Table<IFileGroup, number> {
|
||||
return this.staticClass().dbService.table('fileGroups') as Dexie.Table<IFileGroup, number>;
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,13 @@ import {Codium, ICodium} from './Codium';
|
||||
import {Database, IDatabase} from './Database';
|
||||
import {DatabaseColumn, IDatabaseColumn} from './DatabaseColumn';
|
||||
import {DatabaseEntry, IDatabaseEntry} from './DatabaseEntry';
|
||||
import {FileGroup, IFileGroup} from './FileGroup';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DatabaseService extends Dexie {
|
||||
protected static registeredModels = [Migration, MenuItem, KeyValue, Codium, Database, DatabaseColumn, DatabaseEntry];
|
||||
protected static registeredModels = [Migration, MenuItem, KeyValue, Codium, Database, DatabaseColumn, DatabaseEntry, FileGroup];
|
||||
protected initialized = false;
|
||||
|
||||
migrations!: Dexie.Table<IMigration, number>;
|
||||
@@ -22,6 +23,7 @@ export class DatabaseService extends Dexie {
|
||||
databases!: Dexie.Table<IDatabase, number>;
|
||||
databaseColumns!: Dexie.Table<IDatabaseColumn, number>;
|
||||
databaseEntries!: Dexie.Table<IDatabaseEntry, number>;
|
||||
fileGroups!: Dexie.Table<IFileGroup, number>;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
@@ -54,7 +56,7 @@ export class DatabaseService extends Dexie {
|
||||
schema[ModelClass.getTableName()] = ModelClass.getSchema();
|
||||
}
|
||||
|
||||
await this.version(9).stores(schema);
|
||||
await this.version(11).stores(schema);
|
||||
await this.open();
|
||||
|
||||
this.migrations = this.table('migrations');
|
||||
@@ -77,5 +79,23 @@ export class DatabaseService extends Dexie {
|
||||
|
||||
this.databaseEntries = this.table('databaseEntries');
|
||||
this.databaseEntries.mapToClass(DatabaseEntry);
|
||||
|
||||
this.fileGroups = this.table('fileGroups');
|
||||
this.fileGroups.mapToClass(FileGroup);
|
||||
}
|
||||
|
||||
public async purge() {
|
||||
console.warn('Purging all local data!');
|
||||
|
||||
await Promise.all([
|
||||
this.migrations.clear(),
|
||||
this.menuItems.clear(),
|
||||
this.keyValues.clear(),
|
||||
this.codiums.clear(),
|
||||
this.databases.clear(),
|
||||
this.databaseColumns.clear(),
|
||||
this.databaseEntries.clear(),
|
||||
this.fileGroups.clear(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user