* MM_30475 : ADDED default schema * MM_30475 : ADDED todo for field 'value' of default/Global entity * MM_30476 : Created schema for SERVER DB * MM_30476 : Server model [ IN PROGRESS ] * MM_30476 : Including types for group, groups_in_channel and role * MM_30476 : ADDED models for Group - @typings absolute path has been added to the tsconfig.json * MM_30476 : ADDED typings to current models * MM_30476 : ADDED typings to current models * MM_30476 : ADDED models related to TEAM section of the ERD * MM_30476 : ADDED models for User section of the ERD * MM_30476 : ADDED models for POST section of the ERD * MM_30476 : ADDED models for Channel section of the ERD * MM_30475 : Updated typings and references to MM_TABLES * MM_30476 : Verified all field names * MM_30476 : Verified every table associations * MM_30476 : Verified all relation fields * MM_30476 : Updated primary id of the main models We will override the wdb id at component level when we create a new records. This involves the models : channel, group, post, team and user. * MM_30476 : Including 1:1 relationship amongs some entities * MM_30476 : ADDED Schema Managers * The migration array will hold all the migration steps. * The initial app release (e.g. v2 )will have an empty array and subsequent releases (e.g. v2.1 ) will have the steps listed in that array. * On initialization, the database will perform the migration to accomodate for new columns/tables creation and while it will conserve the mobile phone's data, it will also make it conform to this new schema. * If a migration fails, the migration process will rollback any changes. This migration will be thoroughly tested in development before pushing it live. * Revert "MM_30476 : ADDED Schema Managers" This reverts commit a505bd5e11124e8eb8f258ce8dbb8168a535f7ae. * MM_30478 : Converted schema_manager into a function * MM_30478 : Updated schema manager and included patch for wdb * MM_30478: Updated watermelondb patch package * MM_30478 : Update function create_schema_manager to createSqliteAdaptorOptions * MM_30476 : Update constant name to reflect directory name * MM_30476 : Updated msgCount from my_channel model to message_count in server schema * MM_30482 : Added tests for schema_manager * MM_30482 : Database Manager [ IN PROGRESS ] * MM_30478 : Returning an sqliteAdapter instead of an object * MM_30476 : Apply suggestions from code review Co-authored-by: Elias Nahum <nahumhbl@gmail.com> * MM_30476 : Updated all imports as per instruction. * MM_30476 : Shortening object chains by destructuring * MM_30476 : Updated schema file structure * MM_30476 : Prettifying @typings folder * MM_30476 : Removing useless ids * MM_30476 : Prettify imports for decorators * MM_30476 : ADDED documentations and lazy queries to Channel and Channel_Info * MM_30476 : ADDED documentations for default schema * MM_30476 : Documentation [ IN PROGRESS ] - Following JSDoc syntax for single line comment - Removed redundant fields in the 'membership' tables and left only the @relation records. * MM_30476 : Documentations [ IN PROGRESS ] * MM_30476 : Documentations [ IN PROGRESS ] * MM_30476 : Documentations [ IN PROGRESS ] * MM_30476 : Documentations [ IN PROGRESS] Updated 1) my_team and team, 2) my_channel and channel, to each have 1:1 relationship with one another * MM_30476 : Updated all Typescript definitions * MM_30476 :Updated @relation to @immutableRelation * MM_30476 : Updated description for previous_post_id * MM_30478 : Updated patch package for wdb module * MM_30478: DB Manager [IN PROGRESS ] * MM_30478: DB Manager [IN PROGRESS] * MM_30478: DB Manager [IN PROGRESS] * MM_30478 : DB Manager [IN PROGRESS] * MM_30478 : Deleting .db file on iOS * MM_30478: Successfully deleting .db files and directory on iOS side * MM_30478 : Update definition for default/global * MM_30478 : Updated all models * MM_30478 : Doing a bit of house cleaning * MM_30478: Record of new server connection added to default/servers db * TS Definitely Typed Assignment issue is now FIXED * MM_30478 : TS Definitely Typed Assignment \n Removed all the constructors but error still in editor tabs. But this time the app is not crashing * MM_30478 : Attempt 1 [SUCCESSFUL] * MM_30478 : Removing useDefineForClassFields * MM_30478 : Retrieving the servers in a list + Improved the DB Manager and Babel config * MM_30478 : Updated babel.config.js * MM_30478 : Minor UI correction * MM_30478 : Jest and Typescript configuration * MM_30478 : A bit of housekeeping * MM_30478 : Installed WDB on Android * MM_30478 : Deletes new server record from default DB * MM_30478 : Returns subset of server db instances * MM_30478 : Code clean up * MM_30478 : Code clean up on db manager * MM_30478 : House keeping + Patch for WDB * MM_30478 : Android - Saving & Deleting in FilesDir [COMPLETED] * MM_30478 : Code clean up * MM_30478 : Code clean up * MM_30478 : Code clean up * MM_30478 : Test successful on Android device * MM_30478 : Rolling back change to jest.config.js * MM_30478 : Updated test to test_integration * MM_30478 : Fix imports * MM_30478 : Refactored the manual testscript * MM_30478 : Renamed database manager test file * MM_30478 : Code clean up * MM_30478 : Updated manual test file with a note. * MM_30482 : DataOperator [ IN PROGRESS ] * MM_30482 : DataOperator - setting up the factory [ IN PROGRESS ] * MM_30482: Code refactoring * MM_30482 : DataOperator - setting up the factory [ IN PROGRESS ] * MM_30482 : DataOperator - code clean up [ IN PROGRESS ] * MM_30482 : Minor code clean up * MM_30478 : Fixed JEST issue with TS * MM_30478 : Fixed JEST issue with TS * MM_30478 : Fixed JEST issue with TS * MM_30478 : Implementing JEST test cases * MM_30478 : Implementing JEST last test cases * MM_30478 : Jest fixing ts errors * MM_30478 : Database Manager Jest testing [ IN PROGRESS ] * MM_30482 - Fixing DataOperator [ IN PROGRESS ] * MM_30482 : Code clean up * MM_30482 - Creates multiple records [ IN PROGRESS ] * MM_30482 - Creates multiple records [ IN PROGRESS ] * MM_30482 : Update operation [ COMPLETED ] * MM_30482 : Code clean up * MM_30482 : Updated TS for Data Operator * Update mobile v2 detox deps * MM_30482 : Added factories for all isolated tables * MM_30482 : Refactored TS * MM_30482 : Refactored base factory * MM_30482 : Updated JSDoc for operateBaseRecord - Delete CASE * MM_30482 : Implementing test for Data Operator * MM_30482 : Completed tests for all isolated tables * MM_30482 : Renamed entity_factory into operators * MM_30482 : Fix all imports * MM_30482 : Update multiple records * MM_30482 : Edge case for existing records ( update instead of create ) * MM_30482 : Edge case - create instead of update * MM_30482 : Code clean up * MM_30482 : Code clean up * MM_30482 : Code clean up * MM_30482 : Code clean up * Update app/database/admin/data_operator/operators.ts Co-authored-by: Joseph Baylon <joseph.baylon@mattermost.com> * Update app/database/admin/data_operator/operators.ts Co-authored-by: Joseph Baylon <joseph.baylon@mattermost.com> * Update app/database/admin/data_operator/operators.ts Co-authored-by: Joseph Baylon <joseph.baylon@mattermost.com> * MM_30482 : Imposing usage of correct table name for isolated entities * MM_30482 : Code improvement as per Joseph reviews * MM_30482 : Updated tests to validate choice of operator service wrt tableName * MM_30482 : Updated PR as per suggestions * MM_30482 : Updated comments to follow jsdoc conventions Co-authored-by: Elias Nahum <nahumhbl@gmail.com> Co-authored-by: Avinash Lingaloo <> Co-authored-by: Joseph Baylon <joseph.baylon@mattermost.com>
183 lines
5.6 KiB
TypeScript
183 lines
5.6 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import {MM_TABLES} from '@constants/database';
|
|
import {
|
|
BatchOperations,
|
|
DBInstance,
|
|
HandleBaseData,
|
|
HandleIsolatedEntityData,
|
|
RecordValue,
|
|
} from '@typings/database/database';
|
|
|
|
import DatabaseManager from '../database_manager';
|
|
|
|
import {
|
|
operateAppRecord,
|
|
operateCustomEmojiRecord,
|
|
operateGlobalRecord,
|
|
operateRoleRecord,
|
|
operateServersRecord,
|
|
operateSystemRecord,
|
|
operateTermsOfServiceRecord,
|
|
} from './operators';
|
|
|
|
export enum OperationType {
|
|
CREATE = 'CREATE',
|
|
UPDATE = 'UPDATE',
|
|
DELETE = 'DELETE'
|
|
}
|
|
|
|
export enum IsolatedEntities {
|
|
APP= 'app',
|
|
GLOBAL = 'global',
|
|
SERVERS = 'servers',
|
|
CUSTOM_EMOJI = 'CustomEmoji',
|
|
ROLE = 'Role',
|
|
SYSTEM = 'System',
|
|
TERMS_OF_SERVICE = 'TermsOfService'
|
|
}
|
|
|
|
class DataOperator {
|
|
private defaultDatabase: DBInstance;
|
|
private serverDatabase: DBInstance;
|
|
|
|
/**
|
|
* handleIsolatedEntityData: Operator that handles Create/Update operations on the isolated entities as
|
|
* described by the IsolatedTables type
|
|
* @param {HandleIsolatedEntityData} entityData
|
|
* @param {OperationType} entityData.optType
|
|
* @param {IsolatedEntities} entityData.tableName
|
|
* @param {Records} entityData.values
|
|
* @returns {Promise<void>}
|
|
*/
|
|
handleIsolatedEntityData = async ({optType, tableName, values}: HandleIsolatedEntityData): Promise<void> => {
|
|
let recordOperator;
|
|
|
|
switch (tableName) {
|
|
case IsolatedEntities.APP : {
|
|
recordOperator = operateAppRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.GLOBAL : {
|
|
recordOperator = operateGlobalRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.SERVERS : {
|
|
recordOperator = operateServersRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.CUSTOM_EMOJI : {
|
|
recordOperator = operateCustomEmojiRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.ROLE : {
|
|
recordOperator = operateRoleRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.SYSTEM : {
|
|
recordOperator = operateSystemRecord;
|
|
break;
|
|
}
|
|
case IsolatedEntities.TERMS_OF_SERVICE : {
|
|
recordOperator = operateTermsOfServiceRecord;
|
|
break;
|
|
}
|
|
default: {
|
|
recordOperator = null;
|
|
break;
|
|
}
|
|
}
|
|
if (recordOperator) {
|
|
await this.handleBaseData({optType, values, tableName, recordOperator});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* batchOperations: Accepts an instance of Database (either Default or Server) and an array of
|
|
* prepareCreate/prepareUpdate values and executes the actions on the database.
|
|
* @param {BatchOperations} operation
|
|
* @param {Database} operation.db
|
|
* @param {Array} operation.models
|
|
* @returns {Promise<void>}
|
|
*/
|
|
private batchOperations = async ({db, models}: BatchOperations) => {
|
|
if (models.length > 0) {
|
|
await db.action(async () => {
|
|
await db.batch(...models);
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* handleBaseData: Handles the Create/Update operations on an entity.
|
|
* @param {HandleBaseData} opsBase
|
|
* @param {OperationType} opsBase.optType
|
|
* @param {string} opsBase.tableName
|
|
* @param {Records} opsBase.values
|
|
* @param {(recordOperator: DataFactory) => void} opsBase.recordOperator
|
|
* @returns {Promise<void>}
|
|
*/
|
|
private handleBaseData = async ({optType, tableName, values, recordOperator}: HandleBaseData) => {
|
|
const db = await this.getDatabase(tableName);
|
|
if (!db) {
|
|
return;
|
|
}
|
|
|
|
let results;
|
|
const config = {db, optType, tableName};
|
|
|
|
if (Array.isArray(values) && values.length) {
|
|
const recordPromises = await values.map(async (value) => {
|
|
const record = await recordOperator({...config, value});
|
|
return record;
|
|
});
|
|
|
|
results = await Promise.all(recordPromises);
|
|
} else {
|
|
results = await recordOperator({...config, value: values as RecordValue});
|
|
}
|
|
|
|
if (results) {
|
|
await this.batchOperations({db, models: Array.isArray(results) ? results : Array(results)});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* getDatabase: Based on the table's name, it will return a database instance either from the 'DEFAULT' database or
|
|
* the 'SERVER' database.
|
|
* @param {string} tableName
|
|
* @returns {Promise<DBInstance>}
|
|
*/
|
|
private getDatabase = async (tableName: string): Promise<DBInstance> => {
|
|
const isInDefaultDB = Object.values(MM_TABLES.DEFAULT).some((tbName) => {
|
|
return tableName === tbName;
|
|
});
|
|
|
|
if (isInDefaultDB) {
|
|
return this.defaultDatabase || this.getDefaultDatabase();
|
|
}
|
|
|
|
return this.serverDatabase || this.getServerDatabase();
|
|
};
|
|
|
|
/**
|
|
* getDefaultDatabase: Returns the default database
|
|
* @returns {Promise<DBInstance>}
|
|
*/
|
|
private getDefaultDatabase = async () => {
|
|
this.defaultDatabase = await DatabaseManager.getDefaultDatabase();
|
|
return this.defaultDatabase;
|
|
};
|
|
|
|
/**
|
|
* getServerDatabase: Returns the current active server database (multi-server support)
|
|
* @returns {Promise<DBInstance>}
|
|
*/
|
|
private getServerDatabase = async () => {
|
|
this.serverDatabase = await DatabaseManager.getActiveServerDatabase();
|
|
return this.serverDatabase;
|
|
};
|
|
}
|
|
|
|
export default new DataOperator();
|