forked from Ivasoft/mattermost-mobile
[Gekidou] various fixes (#6022)
* remove empty roles before fetching * Fix prepare delete teams, channels and posts so they don't throw * Fix reaction operator and moved some handlers to their correct file * include delete categories when teams or channels are deleted * Remove unused array in fetchRoles * fix param comment for reactions handler * don't sync preferences when getting the WS event
This commit is contained in:
@@ -61,11 +61,9 @@ export const fetchRoles = async (serverUrl: string, teamMembership?: TeamMembers
|
||||
|
||||
if (teamMembership?.length) {
|
||||
const teamRoles: string[] = [];
|
||||
const teamMembers: string[] = [];
|
||||
|
||||
teamMembership?.forEach((tm) => {
|
||||
teamRoles.push(...tm.roles.split(' '));
|
||||
teamMembers.push(tm.team_id);
|
||||
});
|
||||
|
||||
teamRoles.forEach(rolesToFetch.add, rolesToFetch);
|
||||
@@ -78,6 +76,7 @@ export const fetchRoles = async (serverUrl: string, teamMembership?: TeamMembers
|
||||
}
|
||||
}
|
||||
|
||||
rolesToFetch.delete('');
|
||||
if (rolesToFetch.size > 0) {
|
||||
return fetchRolesIfNeeded(serverUrl, Array.from(rolesToFetch), fetchOnly);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ export async function handlePreferenceChangedEvent(serverUrl: string, msg: WebSo
|
||||
operator.handlePreferences({
|
||||
prepareRecordsOnly: false,
|
||||
preferences: [preference],
|
||||
sync: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -38,7 +37,6 @@ export async function handlePreferencesChangedEvent(serverUrl: string, msg: WebS
|
||||
operator.handlePreferences({
|
||||
prepareRecordsOnly: false,
|
||||
preferences,
|
||||
sync: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
|
||||
import type CategoryChannelModel from '@typings/database/models/servers/category_channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
@@ -127,6 +128,9 @@ export default class ChannelModel extends Model {
|
||||
/** settings: User specific settings/preferences for this channel */
|
||||
@immutableRelation(MY_CHANNEL_SETTINGS, 'id') settings!: Relation<MyChannelSettingsModel>;
|
||||
|
||||
/** categoryChannel : Query returning the membership data for the current user if it belongs to this channel */
|
||||
@immutableRelation(CATEGORY_CHANNEL, 'channel_id') categoryChannel!: Relation<CategoryChannelModel>;
|
||||
|
||||
toApi = (): Channel => {
|
||||
return {
|
||||
id: this.id,
|
||||
|
||||
@@ -7,6 +7,7 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
@@ -15,6 +16,7 @@ import type TeamMembershipModel from '@typings/database/models/servers/team_memb
|
||||
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
|
||||
|
||||
const {
|
||||
CATEGORY,
|
||||
CHANNEL,
|
||||
TEAM,
|
||||
MY_TEAM,
|
||||
@@ -34,6 +36,9 @@ export default class TeamModel extends Model {
|
||||
/** associations : Describes every relationship to this table. */
|
||||
static associations: Associations = {
|
||||
|
||||
/** A TEAM has a 1:N relationship with CATEGORY. A TEAM can possess multiple categories */
|
||||
[CATEGORY]: {type: 'has_many', foreignKey: 'team_id'},
|
||||
|
||||
/** A TEAM has a 1:N relationship with CHANNEL. A TEAM can possess multiple channels */
|
||||
[CHANNEL]: {type: 'has_many', foreignKey: 'team_id'},
|
||||
|
||||
@@ -77,6 +82,9 @@ export default class TeamModel extends Model {
|
||||
/** allowed_domains : List of domains that can join this team */
|
||||
@field('allowed_domains') allowedDomains!: string;
|
||||
|
||||
/** categories : All the categories associated with this team */
|
||||
@children(CATEGORY) categories!: CategoryModel[];
|
||||
|
||||
/** channels : All the channels associated with this team */
|
||||
@children(CHANNEL) channels!: ChannelModel[];
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@ import DatabaseManager from '@database/manager';
|
||||
import {
|
||||
isRecordChannelEqualToRaw,
|
||||
isRecordChannelInfoEqualToRaw,
|
||||
isRecordChannelMembershipEqualToRaw,
|
||||
isRecordMyChannelEqualToRaw,
|
||||
isRecordMyChannelSettingsEqualToRaw,
|
||||
} from '@database/operator/server_data_operator/comparators';
|
||||
import {
|
||||
transformChannelInfoRecord,
|
||||
transformChannelMembershipRecord,
|
||||
transformChannelRecord,
|
||||
transformMyChannelRecord,
|
||||
transformMyChannelSettingsRecord,
|
||||
@@ -198,4 +200,65 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
transformer: transformMyChannelRecord,
|
||||
});
|
||||
});
|
||||
|
||||
it('=> HandleChannelMembership: should write to the CHANNEL_MEMBERSHIP table', async () => {
|
||||
expect.assertions(2);
|
||||
const channelMemberships: ChannelMembership[] = [
|
||||
{
|
||||
id: '17bfnb1uwb8epewp4q3x3rx9go-9ciscaqbrpd6d8s68k76xb9bte',
|
||||
channel_id: '17bfnb1uwb8epewp4q3x3rx9go',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'wqyby5r5pinxxdqhoaomtacdhc',
|
||||
last_viewed_at: 1613667352029,
|
||||
msg_count: 3864,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
{
|
||||
id: '1yw6gxfr4bn1jbyp9nr7d53yew-9ciscaqbrpd6d8s68k76xb9bte',
|
||||
channel_id: '1yw6gxfr4bn1jbyp9nr7d53yew',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'channel_user',
|
||||
last_viewed_at: 1615300540549,
|
||||
msg_count: 16,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'all',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1615300540549,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
];
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
|
||||
await operator.handleChannelMembership({
|
||||
channelMemberships,
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
|
||||
expect(spyOnHandleRecords).toHaveBeenCalledWith({
|
||||
fieldName: 'user_id',
|
||||
createOrUpdateRawValues: channelMemberships,
|
||||
tableName: 'ChannelMembership',
|
||||
prepareRecordsOnly: false,
|
||||
findMatchingRecordBy: isRecordChannelMembershipEqualToRaw,
|
||||
transformer: transformChannelMembershipRecord,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,32 +6,37 @@ import DataOperatorException from '@database/exceptions/data_operator_exception'
|
||||
import {
|
||||
isRecordChannelEqualToRaw,
|
||||
isRecordChannelInfoEqualToRaw,
|
||||
isRecordChannelMembershipEqualToRaw,
|
||||
isRecordMyChannelEqualToRaw,
|
||||
isRecordMyChannelSettingsEqualToRaw,
|
||||
} from '@database/operator/server_data_operator/comparators';
|
||||
import {
|
||||
transformChannelInfoRecord,
|
||||
transformChannelMembershipRecord,
|
||||
transformChannelRecord,
|
||||
transformMyChannelRecord,
|
||||
transformMyChannelSettingsRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/channel';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
|
||||
import type {HandleChannelArgs, HandleChannelInfoArgs, HandleMyChannelArgs, HandleMyChannelSettingsArgs} from '@typings/database/database';
|
||||
import type {HandleChannelArgs, HandleChannelInfoArgs, HandleChannelMembershipArgs, HandleMyChannelArgs, HandleMyChannelSettingsArgs} from '@typings/database/database';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
CHANNEL_INFO,
|
||||
CHANNEL_MEMBERSHIP,
|
||||
MY_CHANNEL,
|
||||
MY_CHANNEL_SETTINGS,
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface ChannelHandlerMix {
|
||||
handleChannel: ({channels, prepareRecordsOnly}: HandleChannelArgs) => Promise<ChannelModel[]>;
|
||||
handleChannelMembership: ({channelMemberships, prepareRecordsOnly}: HandleChannelMembershipArgs) => Promise<ChannelMembershipModel[]>;
|
||||
handleMyChannelSettings: ({settings, prepareRecordsOnly}: HandleMyChannelSettingsArgs) => Promise<MyChannelSettingsModel[]>;
|
||||
handleChannelInfo: ({channelInfos, prepareRecordsOnly}: HandleChannelInfoArgs) => Promise<ChannelInfoModel[]>;
|
||||
handleMyChannel: ({channels, myChannels, prepareRecordsOnly}: HandleMyChannelArgs) => Promise<MyChannelModel[]>;
|
||||
@@ -160,6 +165,38 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
tableName: MY_CHANNEL,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* handleChannelMembership: Handler responsible for the Create/Update operations occurring on the CHANNEL_MEMBERSHIP table from the 'Server' schema
|
||||
* @param {HandleChannelMembershipArgs} channelMembershipsArgs
|
||||
* @param {ChannelMembership[]} channelMembershipsArgs.channelMemberships
|
||||
* @param {boolean} channelMembershipsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<ChannelMembershipModel[]>}
|
||||
*/
|
||||
handleChannelMembership = ({channelMemberships, prepareRecordsOnly = true}: HandleChannelMembershipArgs): Promise<ChannelMembershipModel[]> => {
|
||||
if (!channelMemberships.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "channelMemberships" array has been passed to the handleChannelMembership method',
|
||||
);
|
||||
}
|
||||
|
||||
const memberships: ChannelMember[] = channelMemberships.map((m) => ({
|
||||
id: `${m.channel_id}-${m.user_id}`,
|
||||
...m,
|
||||
}));
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: memberships, key: 'id'});
|
||||
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordChannelMembershipEqualToRaw,
|
||||
transformer: transformChannelMembershipRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues,
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export default ChannelHandler;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import DatabaseManager from '@database/manager';
|
||||
import ServerDataOperator from '@database/operator/server_data_operator';
|
||||
|
||||
describe('*** Operator: User Handlers tests ***', () => {
|
||||
let operator: ServerDataOperator;
|
||||
|
||||
beforeAll(async () => {
|
||||
await DatabaseManager.init(['baseHandler.test.com']);
|
||||
operator = DatabaseManager.serverDatabases['baseHandler.test.com'].operator;
|
||||
});
|
||||
|
||||
it('=> HandleReactions: should write to Reactions table', async () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnPrepareRecords = jest.spyOn(operator, 'prepareRecords');
|
||||
const spyOnBatchOperation = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await operator.handleReactions({
|
||||
postsReactions: [{
|
||||
post_id: '4r9jmr7eqt8dxq3f9woypzurry',
|
||||
reactions: [
|
||||
{
|
||||
create_at: 1608263728086,
|
||||
emoji_name: 'p4p1',
|
||||
post_id: '4r9jmr7eqt8dxq3f9woypzurry',
|
||||
user_id: 'ooumoqgq3bfiijzwbn8badznwc',
|
||||
},
|
||||
],
|
||||
}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
// Called twice: Once for Reaction record
|
||||
expect(spyOnPrepareRecords).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Only one batch operation for both tables
|
||||
expect(spyOnBatchOperation).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import DataOperatorException from '@database/exceptions/data_operator_exception';
|
||||
import {transformReactionRecord} from '@database/operator/server_data_operator/transformers/user';
|
||||
import {sanitizeReactions} from '@database/operator/utils/reaction';
|
||||
|
||||
import type {HandleReactionsArgs} from '@typings/database/database';
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
|
||||
const {REACTION} = MM_TABLES.SERVER;
|
||||
|
||||
export interface ReactionHandlerMix {
|
||||
handleReactions: ({postsReactions, prepareRecordsOnly}: HandleReactionsArgs) => Promise<Array<ReactionModel | CustomEmojiModel>>;
|
||||
}
|
||||
|
||||
const ReactionHandler = (superclass: any) => class extends superclass {
|
||||
/**
|
||||
* handleReactions: Handler responsible for the Create/Update operations occurring on the Reaction table from the 'Server' schema
|
||||
* @param {HandleReactionsArgs} handleReactions
|
||||
* @param {ReactionsPerPost[]} handleReactions.postsReactions
|
||||
* @param {boolean} handleReactions.prepareRecordsOnly
|
||||
* @param {boolean} handleReactions.skipSync
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<Array<(ReactionModel | CustomEmojiModel)>>}
|
||||
*/
|
||||
handleReactions = async ({postsReactions, prepareRecordsOnly, skipSync}: HandleReactionsArgs): Promise<ReactionModel[]> => {
|
||||
const batchRecords: ReactionModel[] = [];
|
||||
|
||||
if (!postsReactions.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "reactions" array has been passed to the handleReactions method',
|
||||
);
|
||||
}
|
||||
|
||||
for await (const postReactions of postsReactions) {
|
||||
const {post_id, reactions} = postReactions;
|
||||
const {
|
||||
createReactions,
|
||||
deleteReactions,
|
||||
} = await sanitizeReactions({
|
||||
database: this.database,
|
||||
post_id,
|
||||
rawReactions: reactions,
|
||||
skipSync,
|
||||
});
|
||||
|
||||
if (createReactions?.length) {
|
||||
// Prepares record for model Reactions
|
||||
const reactionsRecords = (await this.prepareRecords({
|
||||
createRaws: createReactions,
|
||||
transformer: transformReactionRecord,
|
||||
tableName: REACTION,
|
||||
})) as ReactionModel[];
|
||||
batchRecords.push(...reactionsRecords);
|
||||
}
|
||||
|
||||
if (deleteReactions?.length && !skipSync) {
|
||||
deleteReactions.forEach((outCast) => outCast.prepareDestroyPermanently());
|
||||
batchRecords.push(...deleteReactions);
|
||||
}
|
||||
}
|
||||
|
||||
if (prepareRecordsOnly) {
|
||||
return batchRecords;
|
||||
}
|
||||
|
||||
if (batchRecords?.length) {
|
||||
await this.batchRecords(batchRecords);
|
||||
}
|
||||
|
||||
return batchRecords;
|
||||
};
|
||||
};
|
||||
|
||||
export default ReactionHandler;
|
||||
@@ -4,12 +4,10 @@
|
||||
import DatabaseManager from '@database/manager';
|
||||
import ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import {
|
||||
isRecordChannelMembershipEqualToRaw,
|
||||
isRecordPreferenceEqualToRaw,
|
||||
isRecordUserEqualToRaw,
|
||||
} from '@database/operator/server_data_operator/comparators';
|
||||
import {
|
||||
transformChannelMembershipRecord,
|
||||
transformPreferenceRecord,
|
||||
transformUserRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/user';
|
||||
@@ -157,65 +155,4 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
transformer: transformPreferenceRecord,
|
||||
});
|
||||
});
|
||||
|
||||
it('=> HandleChannelMembership: should write to the CHANNEL_MEMBERSHIP table', async () => {
|
||||
expect.assertions(2);
|
||||
const channelMemberships: ChannelMembership[] = [
|
||||
{
|
||||
id: '17bfnb1uwb8epewp4q3x3rx9go-9ciscaqbrpd6d8s68k76xb9bte',
|
||||
channel_id: '17bfnb1uwb8epewp4q3x3rx9go',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'wqyby5r5pinxxdqhoaomtacdhc',
|
||||
last_viewed_at: 1613667352029,
|
||||
msg_count: 3864,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
{
|
||||
id: '1yw6gxfr4bn1jbyp9nr7d53yew-9ciscaqbrpd6d8s68k76xb9bte',
|
||||
channel_id: '1yw6gxfr4bn1jbyp9nr7d53yew',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'channel_user',
|
||||
last_viewed_at: 1615300540549,
|
||||
msg_count: 16,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'all',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1615300540549,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
];
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
|
||||
await operator.handleChannelMembership({
|
||||
channelMemberships,
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
|
||||
expect(spyOnHandleRecords).toHaveBeenCalledWith({
|
||||
fieldName: 'user_id',
|
||||
createOrUpdateRawValues: channelMemberships,
|
||||
tableName: 'ChannelMembership',
|
||||
prepareRecordsOnly: false,
|
||||
findMatchingRecordBy: isRecordChannelMembershipEqualToRaw,
|
||||
transformer: transformChannelMembershipRecord,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,78 +4,30 @@
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import DataOperatorException from '@database/exceptions/data_operator_exception';
|
||||
import {
|
||||
isRecordChannelMembershipEqualToRaw,
|
||||
isRecordPreferenceEqualToRaw,
|
||||
isRecordUserEqualToRaw,
|
||||
} from '@database/operator/server_data_operator/comparators';
|
||||
import {
|
||||
transformChannelMembershipRecord,
|
||||
transformPreferenceRecord,
|
||||
transformReactionRecord,
|
||||
transformUserRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/user';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {sanitizeReactions} from '@database/operator/utils/reaction';
|
||||
|
||||
import type {
|
||||
HandleChannelMembershipArgs,
|
||||
HandlePreferencesArgs,
|
||||
HandleReactionsArgs,
|
||||
HandleUsersArgs,
|
||||
} from '@typings/database/database';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {
|
||||
CHANNEL_MEMBERSHIP,
|
||||
PREFERENCE,
|
||||
REACTION,
|
||||
USER,
|
||||
} = MM_TABLES.SERVER;
|
||||
const {PREFERENCE, USER} = MM_TABLES.SERVER;
|
||||
|
||||
export interface UserHandlerMix {
|
||||
handleChannelMembership: ({channelMemberships, prepareRecordsOnly}: HandleChannelMembershipArgs) => Promise<ChannelMembershipModel[]>;
|
||||
handlePreferences: ({preferences, prepareRecordsOnly}: HandlePreferencesArgs) => Promise<PreferenceModel[]>;
|
||||
handleReactions: ({postsReactions, prepareRecordsOnly}: HandleReactionsArgs) => Promise<Array<ReactionModel | CustomEmojiModel>>;
|
||||
handleUsers: ({users, prepareRecordsOnly}: HandleUsersArgs) => Promise<UserModel[]>;
|
||||
}
|
||||
|
||||
const UserHandler = (superclass: any) => class extends superclass {
|
||||
/**
|
||||
* handleChannelMembership: Handler responsible for the Create/Update operations occurring on the CHANNEL_MEMBERSHIP table from the 'Server' schema
|
||||
* @param {HandleChannelMembershipArgs} channelMembershipsArgs
|
||||
* @param {ChannelMembership[]} channelMembershipsArgs.channelMemberships
|
||||
* @param {boolean} channelMembershipsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<ChannelMembershipModel[]>}
|
||||
*/
|
||||
handleChannelMembership = ({channelMemberships, prepareRecordsOnly = true}: HandleChannelMembershipArgs): Promise<ChannelMembershipModel[]> => {
|
||||
if (!channelMemberships.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "channelMemberships" array has been passed to the handleChannelMembership method',
|
||||
);
|
||||
}
|
||||
|
||||
const memberships: ChannelMember[] = channelMemberships.map((m) => ({
|
||||
id: `${m.channel_id}-${m.user_id}`,
|
||||
...m,
|
||||
}));
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: memberships, key: 'id'});
|
||||
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordChannelMembershipEqualToRaw,
|
||||
transformer: transformChannelMembershipRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues,
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* handlePreferences: Handler responsible for the Create/Update operations occurring on the PREFERENCE table from the 'Server' schema
|
||||
* @param {HandlePreferencesArgs} preferencesArgs
|
||||
@@ -124,64 +76,6 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleReactions: Handler responsible for the Create/Update operations occurring on the Reaction table from the 'Server' schema
|
||||
* @param {HandleReactionsArgs} handleReactions
|
||||
* @param {ReactionsPerPost[]} handleReactions.reactions
|
||||
* @param {boolean} handleReactions.prepareRecordsOnly
|
||||
* @param {boolean} handleReactions.skipSync
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<Array<(ReactionModel | CustomEmojiModel)>>}
|
||||
*/
|
||||
handleReactions = async ({postsReactions, prepareRecordsOnly, skipSync}: HandleReactionsArgs): Promise<ReactionModel[]> => {
|
||||
const batchRecords: ReactionModel[] = [];
|
||||
|
||||
if (!postsReactions.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "reactions" array has been passed to the handleReactions method',
|
||||
);
|
||||
}
|
||||
|
||||
for await (const postReactions of postsReactions) {
|
||||
const {post_id, reactions} = postReactions;
|
||||
const rawValues = getUniqueRawsBy({raws: reactions, key: 'emoji_name'}) as Reaction[];
|
||||
const {
|
||||
createReactions,
|
||||
deleteReactions,
|
||||
} = await sanitizeReactions({
|
||||
database: this.database,
|
||||
post_id,
|
||||
rawReactions: rawValues,
|
||||
skipSync,
|
||||
});
|
||||
|
||||
if (createReactions?.length) {
|
||||
// Prepares record for model Reactions
|
||||
const reactionsRecords = (await this.prepareRecords({
|
||||
createRaws: createReactions,
|
||||
transformer: transformReactionRecord,
|
||||
tableName: REACTION,
|
||||
})) as ReactionModel[];
|
||||
batchRecords.push(...reactionsRecords);
|
||||
}
|
||||
|
||||
if (deleteReactions?.length && !skipSync) {
|
||||
deleteReactions.forEach((outCast) => outCast.prepareDestroyPermanently());
|
||||
batchRecords.push(...deleteReactions);
|
||||
}
|
||||
}
|
||||
|
||||
if (prepareRecordsOnly) {
|
||||
return batchRecords;
|
||||
}
|
||||
|
||||
if (batchRecords?.length) {
|
||||
await this.batchRecords(batchRecords);
|
||||
}
|
||||
|
||||
return batchRecords;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleUsers: Handler responsible for the Create/Update operations occurring on the User table from the 'Server' schema
|
||||
* @param {HandleUsersArgs} usersArgs
|
||||
|
||||
@@ -7,6 +7,7 @@ import ChannelHandler, {ChannelHandlerMix} from '@database/operator/server_data_
|
||||
import PostHandler, {PostHandlerMix} from '@database/operator/server_data_operator/handlers/post';
|
||||
import PostsInChannelHandler, {PostsInChannelHandlerMix} from '@database/operator/server_data_operator/handlers/posts_in_channel';
|
||||
import PostsInThreadHandler, {PostsInThreadHandlerMix} from '@database/operator/server_data_operator/handlers/posts_in_thread';
|
||||
import ReactionHander, {ReactionHandlerMix} from '@database/operator/server_data_operator/handlers/reaction';
|
||||
import TeamHandler, {TeamHandlerMix} from '@database/operator/server_data_operator/handlers/team';
|
||||
import UserHandler, {UserHandlerMix} from '@database/operator/server_data_operator/handlers/user';
|
||||
import mix from '@utils/mix';
|
||||
@@ -14,7 +15,7 @@ import mix from '@utils/mix';
|
||||
import type {Database} from '@nozbe/watermelondb';
|
||||
|
||||
interface ServerDataOperator extends ServerDataOperatorBase, PostHandlerMix, PostsInChannelHandlerMix,
|
||||
PostsInThreadHandlerMix, UserHandlerMix, ChannelHandlerMix, CategoryHandlerMix, TeamHandlerMix {}
|
||||
PostsInThreadHandlerMix, ReactionHandlerMix, UserHandlerMix, ChannelHandlerMix, CategoryHandlerMix, TeamHandlerMix {}
|
||||
|
||||
class ServerDataOperator extends mix(ServerDataOperatorBase).with(
|
||||
CategoryHandler,
|
||||
@@ -22,6 +23,7 @@ class ServerDataOperator extends mix(ServerDataOperatorBase).with(
|
||||
PostHandler,
|
||||
PostsInChannelHandler,
|
||||
PostsInThreadHandler,
|
||||
ReactionHander,
|
||||
TeamHandler,
|
||||
UserHandler,
|
||||
) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
transformChannelRecord,
|
||||
transformMyChannelRecord,
|
||||
transformMyChannelSettingsRecord,
|
||||
transformChannelMembershipRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/channel';
|
||||
import {createTestConnection} from '@database/operator/utils/create_test_connection';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
@@ -139,4 +140,40 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelModel');
|
||||
});
|
||||
|
||||
it('=> transformChannelMembershipRecord: should return an array of type ChannelMembership', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
const database = await createTestConnection({databaseName: 'user_prepare_records', setActive: true});
|
||||
expect(database).toBeTruthy();
|
||||
|
||||
const preparedRecords = await transformChannelMembershipRecord({
|
||||
action: OperationType.CREATE,
|
||||
database: database!,
|
||||
value: {
|
||||
record: undefined,
|
||||
raw: {
|
||||
channel_id: '17bfnb1uwb8epewp4q3x3rx9go',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'wqyby5r5pinxxdqhoaomtacdhc',
|
||||
last_viewed_at: 1613667352029,
|
||||
msg_count: 3864,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelMembershipModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {General} from '@constants';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
@@ -8,12 +9,14 @@ import {OperationType} from '@typings/database/enums';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
CHANNEL_INFO,
|
||||
CHANNEL_MEMBERSHIP,
|
||||
MY_CHANNEL,
|
||||
MY_CHANNEL_SETTINGS,
|
||||
} = MM_TABLES.SERVER;
|
||||
@@ -37,9 +40,25 @@ export const transformChannelRecord = ({action, database, value}: TransformerArg
|
||||
channel.creatorId = raw.creator_id;
|
||||
channel.deleteAt = raw.delete_at;
|
||||
|
||||
// for DM channels do not override the display name
|
||||
// for DM & GM's channels do not override the display name
|
||||
// until we get the new info if there is any
|
||||
channel.displayName = raw.display_name || record?.displayName || '';
|
||||
let displayName;
|
||||
if (raw.type === General.DM_CHANNEL && record?.displayName) {
|
||||
displayName = raw.display_name || record?.displayName;
|
||||
} else if (raw.type === General.GM_CHANNEL) {
|
||||
const rawMembers = raw.display_name.split(',').length;
|
||||
const recordMembers = record?.displayName.split(',').length || rawMembers;
|
||||
|
||||
if (recordMembers < rawMembers) {
|
||||
displayName = record.displayName;
|
||||
} else {
|
||||
displayName = raw.display_name;
|
||||
}
|
||||
} else {
|
||||
displayName = raw.display_name;
|
||||
}
|
||||
|
||||
channel.displayName = displayName;
|
||||
channel.isGroupConstrained = Boolean(raw.group_constrained);
|
||||
channel.name = raw.name;
|
||||
channel.shared = Boolean(raw.shared);
|
||||
@@ -144,3 +163,30 @@ export const transformMyChannelRecord = ({action, database, value}: TransformerA
|
||||
}) as Promise<MyChannelModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
* transformChannelMembershipRecord: Prepares a record of the SERVER database 'ChannelMembership' table for update or create actions.
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<ChannelMembershipModel>}
|
||||
*/
|
||||
export const transformChannelMembershipRecord = ({action, database, value}: TransformerArgs): Promise<ChannelMembershipModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as ChannelMembershipModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (channelMember: ChannelMembershipModel) => {
|
||||
channelMember._raw.id = isCreateAction ? (raw?.id ?? channelMember.id) : record.id;
|
||||
channelMember.channelId = raw.channel_id;
|
||||
channelMember.userId = raw.user_id;
|
||||
};
|
||||
|
||||
return prepareBaseRecord({
|
||||
action,
|
||||
database,
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
}) as Promise<ChannelMembershipModel>;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {
|
||||
transformChannelMembershipRecord,
|
||||
transformPreferenceRecord,
|
||||
transformReactionRecord,
|
||||
transformUserRecord,
|
||||
@@ -11,42 +10,6 @@ import {createTestConnection} from '@database/operator/utils/create_test_connect
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
|
||||
describe('*** USER Prepare Records Test ***', () => {
|
||||
it('=> transformChannelMembershipRecord: should return an array of type ChannelMembership', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
const database = await createTestConnection({databaseName: 'user_prepare_records', setActive: true});
|
||||
expect(database).toBeTruthy();
|
||||
|
||||
const preparedRecords = await transformChannelMembershipRecord({
|
||||
action: OperationType.CREATE,
|
||||
database: database!,
|
||||
value: {
|
||||
record: undefined,
|
||||
raw: {
|
||||
channel_id: '17bfnb1uwb8epewp4q3x3rx9go',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
roles: 'wqyby5r5pinxxdqhoaomtacdhc',
|
||||
last_viewed_at: 1613667352029,
|
||||
msg_count: 3864,
|
||||
mention_count: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelMembershipModel');
|
||||
});
|
||||
|
||||
it('=> transformPreferenceRecord: should return an array of type Preference', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
|
||||
@@ -6,13 +6,11 @@ import {prepareBaseRecord} from '@database/operator/server_data_operator/transfo
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {
|
||||
CHANNEL_MEMBERSHIP,
|
||||
PREFERENCE,
|
||||
REACTION,
|
||||
USER,
|
||||
@@ -124,30 +122,3 @@ export const transformPreferenceRecord = ({action, database, value}: Transformer
|
||||
}) as Promise<PreferenceModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
* transformChannelMembershipRecord: Prepares a record of the SERVER database 'ChannelMembership' table for update or create actions.
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<ChannelMembershipModel>}
|
||||
*/
|
||||
export const transformChannelMembershipRecord = ({action, database, value}: TransformerArgs): Promise<ChannelMembershipModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as ChannelMembershipModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (channelMember: ChannelMembershipModel) => {
|
||||
channelMember._raw.id = isCreateAction ? (raw?.id ?? channelMember.id) : record.id;
|
||||
channelMember.channelId = raw.channel_id;
|
||||
channelMember.userId = raw.user_id;
|
||||
};
|
||||
|
||||
return prepareBaseRecord({
|
||||
action,
|
||||
database,
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
}) as Promise<ChannelMembershipModel>;
|
||||
};
|
||||
|
||||
@@ -20,19 +20,17 @@ const {REACTION} = MM_TABLES.SERVER;
|
||||
* @returns {Promise<{createReactions: RawReaction[], deleteReactions: Reaction[]}>}
|
||||
*/
|
||||
export const sanitizeReactions = async ({database, post_id, rawReactions, skipSync}: SanitizeReactionsArgs) => {
|
||||
const reactions = (await database.collections.
|
||||
get(REACTION).
|
||||
const reactions = (await database.
|
||||
get<ReactionModel>(REACTION).
|
||||
query(Q.where('post_id', post_id)).
|
||||
fetch()) as ReactionModel[];
|
||||
fetch());
|
||||
|
||||
// similarObjects: Contains objects that are in both the RawReaction array and in the Reaction table
|
||||
const similarObjects: ReactionModel[] = [];
|
||||
|
||||
const createReactions: RecordPair[] = [];
|
||||
|
||||
for (let i = 0; i < rawReactions.length; i++) {
|
||||
const raw = rawReactions[i];
|
||||
|
||||
for (const raw of rawReactions) {
|
||||
// If the reaction is not present let's add it to the db
|
||||
const exists = reactions.find((r) => (
|
||||
r.userId === raw.user_id &&
|
||||
@@ -49,7 +47,7 @@ export const sanitizeReactions = async ({database, post_id, rawReactions, skipSy
|
||||
return {createReactions, deleteReactions: []};
|
||||
}
|
||||
|
||||
// finding out elements to delete using array subtract
|
||||
// finding out elements to delete
|
||||
const deleteReactions = reactions.
|
||||
filter((reaction) => !similarObjects.includes(reaction));
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Q} from '@nozbe/watermelondb';
|
||||
import {Database, Model, Q, Query} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
|
||||
@@ -113,3 +113,17 @@ export const prepareCategoryChannels = (
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const prepareDeleteCategory = async (category: CategoryModel): Promise<Model[]> => {
|
||||
const preparedModels: Model[] = [category.prepareDestroyPermanently()];
|
||||
|
||||
const associatedChildren: Array<Query<any>> = [
|
||||
category.categoryChannels,
|
||||
];
|
||||
for await (const children of associatedChildren) {
|
||||
const models = await children?.fetch?.() as Model[] | undefined;
|
||||
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
}
|
||||
|
||||
return preparedModels;
|
||||
};
|
||||
|
||||
@@ -96,10 +96,10 @@ export const prepareMyChannelsForTeam = async (operator: ServerDataOperator, tea
|
||||
export const prepareDeleteChannel = async (channel: ChannelModel): Promise<Model[]> => {
|
||||
const preparedModels: Model[] = [channel.prepareDestroyPermanently()];
|
||||
|
||||
const relations: Array<Relation<Model>> = [channel.membership, channel.info, channel.settings];
|
||||
const relations: Array<Relation<Model>> = [channel.membership, channel.info, channel.settings, channel.categoryChannel];
|
||||
for await (const relation of relations) {
|
||||
try {
|
||||
const model = await relation.fetch();
|
||||
const model = await relation?.fetch?.();
|
||||
if (model) {
|
||||
preparedModels.push(model.prepareDestroyPermanently());
|
||||
}
|
||||
@@ -114,14 +114,16 @@ export const prepareDeleteChannel = async (channel: ChannelModel): Promise<Model
|
||||
channel.postsInChannel,
|
||||
];
|
||||
for await (const children of associatedChildren) {
|
||||
const models = await children.fetch() as Model[];
|
||||
models.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
const models = await children?.fetch?.() as Model[] | undefined;
|
||||
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
}
|
||||
|
||||
const posts = await channel.posts.fetch() as PostModel[];
|
||||
for await (const post of posts) {
|
||||
const preparedPost = await prepareDeletePost(post);
|
||||
preparedModels.push(...preparedPost);
|
||||
const posts = await channel.posts?.fetch?.() as PostModel[] | undefined;
|
||||
if (posts?.length) {
|
||||
for await (const post of posts) {
|
||||
const preparedPost = await prepareDeletePost(post);
|
||||
preparedModels.push(...preparedPost);
|
||||
}
|
||||
}
|
||||
|
||||
return preparedModels;
|
||||
|
||||
@@ -16,7 +16,7 @@ export const prepareDeletePost = async (post: PostModel): Promise<Model[]> => {
|
||||
const relations: Array<Relation<Model> | Query<Model>> = [post.drafts, post.postsInThread];
|
||||
for await (const relation of relations) {
|
||||
try {
|
||||
const model = await relation.fetch();
|
||||
const model = await relation?.fetch();
|
||||
if (model) {
|
||||
if (Array.isArray(model)) {
|
||||
model.forEach((m) => preparedModels.push(m.prepareDestroyPermanently()));
|
||||
@@ -31,8 +31,8 @@ export const prepareDeletePost = async (post: PostModel): Promise<Model[]> => {
|
||||
|
||||
const associatedChildren: Array<Query<any>> = [post.files, post.reactions];
|
||||
for await (const children of associatedChildren) {
|
||||
const models = await children.fetch() as Model[];
|
||||
models.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
const models = await children.fetch?.() as Model[] | undefined;
|
||||
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
}
|
||||
|
||||
return preparedModels;
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Model, Q, Query} from '@nozbe/watermelondb';
|
||||
import {Database, Model, Q, Query, Relation} from '@nozbe/watermelondb';
|
||||
|
||||
import {Database as DatabaseConstants, Preferences} from '@constants';
|
||||
import {getPreferenceValue} from '@helpers/api/preference';
|
||||
import {selectDefaultTeam} from '@helpers/api/team';
|
||||
import {DEFAULT_LOCALE} from '@i18n';
|
||||
|
||||
import {prepareDeleteCategory} from './categories';
|
||||
import {prepareDeleteChannel, queryDefaultChannelForTeam} from './channel';
|
||||
import {queryPreferencesByCategoryAndName} from './preference';
|
||||
import {patchTeamHistory, queryConfig, queryTeamHistory} from './system';
|
||||
import {queryCurrentUser} from './user';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
@@ -211,22 +213,16 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
|
||||
try {
|
||||
const preparedModels: Model[] = [team.prepareDestroyPermanently()];
|
||||
|
||||
try {
|
||||
const model = await team.myTeam.fetch();
|
||||
if (model) {
|
||||
preparedModels.push(model.prepareDestroyPermanently());
|
||||
const relations: Array<Relation<Model>> = [team.myTeam, team.teamChannelHistory];
|
||||
for await (const relation of relations) {
|
||||
try {
|
||||
const model = await relation?.fetch?.();
|
||||
if (model) {
|
||||
preparedModels.push(model.prepareDestroyPermanently());
|
||||
}
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
|
||||
try {
|
||||
const model = await team.teamChannelHistory.fetch();
|
||||
if (model) {
|
||||
preparedModels.push(model.prepareDestroyPermanently());
|
||||
}
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
|
||||
const associatedChildren: Array<Query<any>> = [
|
||||
@@ -236,20 +232,34 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
|
||||
];
|
||||
for await (const children of associatedChildren) {
|
||||
try {
|
||||
const models = await children.fetch() as Model[];
|
||||
models.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
const models = await children.fetch?.() as Model[] | undefined;
|
||||
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
const channels = await team.channels.fetch() as ChannelModel[];
|
||||
for await (const channel of channels) {
|
||||
try {
|
||||
const preparedChannel = await prepareDeleteChannel(channel);
|
||||
preparedModels.push(...preparedChannel);
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
const categories = await team.categories.fetch?.() as CategoryModel[] | undefined;
|
||||
if (categories?.length) {
|
||||
for await (const category of categories) {
|
||||
try {
|
||||
const preparedCategory = await prepareDeleteCategory(category);
|
||||
preparedModels.push(...preparedCategory);
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const channels = await team.channels.fetch?.() as ChannelModel[] | undefined;
|
||||
if (channels?.length) {
|
||||
for await (const channel of channels) {
|
||||
try {
|
||||
const preparedChannel = await prepareDeleteChannel(channel);
|
||||
preparedModels.push(...preparedChannel);
|
||||
} catch {
|
||||
// Record not found, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
types/database/models/servers/channel.d.ts
vendored
3
types/database/models/servers/channel.d.ts
vendored
@@ -71,5 +71,8 @@ export default class ChannelModel extends Model {
|
||||
/** settings: User specific settings/preferences for this channel */
|
||||
settings: Relation<MyChannelSettingsModel>;
|
||||
|
||||
/** categoryChannel: category of this channel */
|
||||
categoryChannel: Relation<CategoryChanelModel>;
|
||||
|
||||
toApi = () => Channel;
|
||||
}
|
||||
|
||||
7
types/database/models/servers/team.d.ts
vendored
7
types/database/models/servers/team.d.ts
vendored
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Query, Relation} from '@nozbe/watermelondb';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import type {Query, Relation} from '@nozbe/watermelondb';
|
||||
import type Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
/**
|
||||
* A Team houses and enables communication to happen across channels and users.
|
||||
@@ -41,6 +41,9 @@ export default class TeamModel extends Model {
|
||||
/** allowed_domains : List of domains that can join this team */
|
||||
allowedDomains: string;
|
||||
|
||||
/** categories : All the categories associated with this team */
|
||||
categories: Query<CategoryModel>;
|
||||
|
||||
/** channels : All the channels associated with this team */
|
||||
channels: Query<ChannelModel>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user