removed SlashCommands from the Server database schema (#6116)

This commit is contained in:
Avinash Lingaloo 2022-04-01 19:23:57 +04:00 committed by GitHub
parent b7d04afa21
commit 764e08e25d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 6 additions and 281 deletions

View file

@ -27,7 +27,6 @@ export const MM_TABLES = {
PREFERENCE: 'Preference',
REACTION: 'Reaction',
ROLE: 'Role',
SLASH_COMMAND: 'SlashCommand',
SYSTEM: 'System',
TEAM: 'Team',
TEAM_CHANNEL_HISTORY: 'TeamChannelHistory',

View file

@ -14,7 +14,7 @@ import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
import {CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
TermsOfServiceModel, ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
} from '@database/models/server';
import AppDataOperator from '@database/operator/app_data_operator';
@ -50,7 +50,7 @@ class DatabaseManager {
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
TermsOfServiceModel, ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
];
this.databaseDirectory = '';

View file

@ -15,7 +15,7 @@ import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
import {CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
TermsOfServiceModel, ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
} from '@database/models/server';
import AppDataOperator from '@database/operator/app_data_operator';
@ -45,7 +45,7 @@ class DatabaseManager {
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
TermsOfServiceModel, ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
];

View file

@ -18,7 +18,6 @@ export {default as PostsInThreadModel} from './posts_in_thread';
export {default as PreferenceModel} from './preference';
export {default as ReactionModel} from './reaction';
export {default as RoleModel} from './role';
export {default as SlashCommandModel} from './slash_command';
export {default as SystemModel} from './system';
export {default as TeamChannelHistoryModel} from './team_channel_history';
export {default as TeamMembershipModel} from './team_membership';

View file

@ -1,58 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import type SlashCommandModelInterface from '@typings/database/models/servers/slash_command';
import type TeamModel from '@typings/database/models/servers/team';
const {SLASH_COMMAND, TEAM} = MM_TABLES.SERVER;
/**
* The SlashCommand model describes the commands of the various commands available in each team.
*/
export default class SlashCommandModel extends Model implements SlashCommandModelInterface {
/** table (name) : SlashCommand */
static table = SLASH_COMMAND;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** A TEAM can have multiple slash commands. (relationship is 1:N) */
[TEAM]: {type: 'belongs_to', key: 'team_id'},
};
/** is_auto_complete : Boolean flag for auto-completing slash commands */
@field('is_auto_complete') isAutoComplete!: boolean;
/** description : The description for the slash command */
@field('description') description!: string;
/** display_name : The name for the command */
@field('display_name') displayName!: string;
/** hint : A helpful text explaining the purpose of the command */
@field('hint') hint!: string;
/** method : HTTP API methods like get, put, post, patch, etc. */
@field('method') method!: string;
/** team_id : The foreign key of the parent Team */
@field('team_id') teamId!: string;
/** token : A key identifying this slash command */
@field('token') token!: string;
/** trigger : A pattern/text used to recognize when a slash command needs to launch */
@field('trigger') trigger!: string;
/** update_at : The timestamp to when this command was last updated on the server */
@field('update_at') updateAt!: number;
/** team : The related parent TEAM record */
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
}

View file

@ -10,7 +10,6 @@ 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';
import type TeamModelInterface from '@typings/database/models/servers/team';
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
@ -22,7 +21,6 @@ const {
CHANNEL,
TEAM,
MY_TEAM,
SLASH_COMMAND,
TEAM_CHANNEL_HISTORY,
TEAM_MEMBERSHIP,
TEAM_SEARCH_HISTORY,
@ -49,9 +47,6 @@ export default class TeamModel extends Model implements TeamModelInterface {
/** A TEAM can be associated to one MY_TEAM (relationship is 1:1) */
[MY_TEAM]: {type: 'has_many', foreignKey: 'id'},
/** A TEAM has a 1:N relationship with SLASH_COMMAND. A TEAM can possess multiple slash commands */
[SLASH_COMMAND]: {type: 'has_many', foreignKey: 'team_id'},
/** A TEAM has a 1:N relationship with TEAM_MEMBERSHIP. A TEAM can regroup multiple users */
[TEAM_MEMBERSHIP]: {type: 'has_many', foreignKey: 'team_id'},
@ -98,9 +93,6 @@ export default class TeamModel extends Model implements TeamModelInterface {
/** myTeam : Retrieves additional information about the team that this user is possibly part of. */
@immutableRelation(MY_TEAM, 'id') myTeam!: Relation<MyTeamModel>;
/** slashCommands : All the slash commands associated with this team */
@children(SLASH_COMMAND) slashCommands!: Query<SlashCommandModel>;
/** teamChannelHistory : A history of the channels in this team that has been visited, ordered by the most recent and capped to the last 5 */
@immutableRelation(TEAM_CHANNEL_HISTORY, 'id') teamChannelHistory!: Relation<TeamChannelHistoryModel>;

View file

@ -4,7 +4,6 @@
import DatabaseManager from '@database/manager';
import {
isRecordMyTeamEqualToRaw,
isRecordSlashCommandEqualToRaw,
isRecordTeamChannelHistoryEqualToRaw,
isRecordTeamEqualToRaw,
isRecordTeamMembershipEqualToRaw,
@ -12,7 +11,6 @@ import {
} from '@database/operator/server_data_operator/comparators';
import {
transformMyTeamRecord,
transformSlashCommandRecord,
transformTeamChannelHistoryRecord,
transformTeamMembershipRecord,
transformTeamRecord,
@ -184,46 +182,4 @@ describe('*** Operator: Team Handlers tests ***', () => {
transformer: transformTeamSearchHistoryRecord,
});
});
it('=> HandleSlashCommand: should write to the SLASH_COMMAND table', async () => {
expect.assertions(2);
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
const slashCommands = [
{
id: 'command_1',
auto_complete: true,
auto_complete_desc: 'mock_command',
auto_complete_hint: 'hint',
create_at: 1445538153952,
creator_id: 'creator_id',
delete_at: 1445538153952,
description: 'description',
display_name: 'display_name',
icon_url: 'display_name',
method: 'get',
team_id: 'teamA',
token: 'token',
trigger: 'trigger',
update_at: 1445538153953,
url: 'url',
username: 'userA',
},
];
await operator.handleSlashCommand({
slashCommands,
prepareRecordsOnly: false,
});
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
expect(spyOnHandleRecords).toHaveBeenCalledWith({
fieldName: 'id',
createOrUpdateRawValues: slashCommands,
tableName: 'SlashCommand',
prepareRecordsOnly: false,
findMatchingRecordBy: isRecordSlashCommandEqualToRaw,
transformer: transformSlashCommandRecord,
});
});
});

View file

@ -5,7 +5,6 @@ import {MM_TABLES} from '@constants/database';
import DataOperatorException from '@database/exceptions/data_operator_exception';
import {
isRecordMyTeamEqualToRaw,
isRecordSlashCommandEqualToRaw,
isRecordTeamChannelHistoryEqualToRaw,
isRecordTeamEqualToRaw,
isRecordTeamMembershipEqualToRaw,
@ -13,7 +12,6 @@ import {
} from '@database/operator/server_data_operator/comparators';
import {
transformMyTeamRecord,
transformSlashCommandRecord,
transformTeamChannelHistoryRecord,
transformTeamMembershipRecord,
transformTeamRecord,
@ -34,7 +32,6 @@ import type TeamSearchHistoryModel from '@typings/database/models/servers/team_s
const {
MY_TEAM,
SLASH_COMMAND,
TEAM,
TEAM_CHANNEL_HISTORY,
TEAM_MEMBERSHIP,
@ -159,33 +156,6 @@ const TeamHandler = (superclass: any) => class extends superclass {
});
};
/**
* handleSlashCommand: Handler responsible for the Create/Update operations occurring on the SLASH_COMMAND table from the 'Server' schema
* @param {HandleSlashCommandArgs} slashCommandsArgs
* @param {SlashCommand[]} slashCommandsArgs.slashCommands
* @param {boolean} slashCommandsArgs.prepareRecordsOnly
* @throws DataOperatorException
* @returns {Promise<SlashCommandModel[]>}
*/
handleSlashCommand = ({slashCommands, prepareRecordsOnly = true}: HandleSlashCommandArgs): Promise<SlashCommandModel[]> => {
if (!slashCommands.length) {
throw new DataOperatorException(
'An empty "slashCommands" array has been passed to the handleSlashCommand method',
);
}
const createOrUpdateRawValues = getUniqueRawsBy({raws: slashCommands, key: 'id'});
return this.handleRecords({
fieldName: 'id',
findMatchingRecordBy: isRecordSlashCommandEqualToRaw,
transformer: transformSlashCommandRecord,
prepareRecordsOnly,
createOrUpdateRawValues,
tableName: SLASH_COMMAND,
});
};
/**
* handleMyTeam: Handler responsible for the Create/Update operations occurring on the MY_TEAM table from the 'Server' schema
* @param {HandleMyTeamArgs} myTeamsArgs

View file

@ -3,7 +3,6 @@
import {
transformMyTeamRecord,
transformSlashCommandRecord,
transformTeamChannelHistoryRecord,
transformTeamMembershipRecord,
transformTeamRecord,
@ -13,43 +12,6 @@ import {createTestConnection} from '@database/operator/utils/create_test_connect
import {OperationType} from '@typings/database/enums';
describe('*** TEAM Prepare Records Test ***', () => {
it('=> transformSlashCommandRecord: should return an array of type SlashCommand', async () => {
expect.assertions(3);
const database = await createTestConnection({databaseName: 'team_prepare_records', setActive: true});
expect(database).toBeTruthy();
const preparedRecords = await transformSlashCommandRecord({
action: OperationType.CREATE,
database: database!,
value: {
record: undefined,
raw: {
id: 'command_1',
auto_complete: true,
auto_complete_desc: 'mock_command',
auto_complete_hint: 'hint',
create_at: 1445538153952,
creator_id: 'creator_id',
delete_at: 1445538153952,
description: 'description',
display_name: 'display_name',
icon_url: 'display_name',
method: 'get',
team_id: 'teamA',
token: 'token',
trigger: 'trigger',
update_at: 1445538153953,
url: 'url',
username: 'userA',
},
},
});
expect(preparedRecords).toBeTruthy();
expect(preparedRecords!.collection.modelClass.name).toBe('SlashCommandModel');
});
it('=> transformMyTeamRecord: should return an array of type MyTeam', async () => {
expect.assertions(3);

View file

@ -7,7 +7,6 @@ import {OperationType} from '@typings/database/enums';
import type {TransformerArgs} from '@typings/database/database';
import type MyTeamModel from '@typings/database/models/servers/my_team';
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
import type TeamModel from '@typings/database/models/servers/team';
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
@ -15,7 +14,6 @@ import type TeamSearchHistoryModel from '@typings/database/models/servers/team_s
const {
MY_TEAM,
SLASH_COMMAND,
TEAM,
TEAM_CHANNEL_HISTORY,
TEAM_MEMBERSHIP,
@ -140,41 +138,6 @@ export const transformTeamSearchHistoryRecord = ({action, database, value}: Tran
}) as Promise<TeamSearchHistoryModel>;
};
/**
* transformSlashCommandRecord: Prepares a record of the SERVER database 'SlashCommand' table for update or create actions.
* @param {DataFactory} operator
* @param {Database} operator.database
* @param {RecordPair} operator.value
* @returns {Promise<SlashCommandModel>}
*/
export const transformSlashCommandRecord = ({action, database, value}: TransformerArgs): Promise<SlashCommandModel> => {
const raw = value.raw as SlashCommand;
const record = value.record as SlashCommandModel;
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 = (slashCommand: SlashCommandModel) => {
slashCommand._raw.id = isCreateAction ? (raw?.id ?? slashCommand.id) : record.id;
slashCommand.isAutoComplete = raw.auto_complete;
slashCommand.description = raw.description;
slashCommand.displayName = raw.display_name;
slashCommand.hint = raw.auto_complete_hint;
slashCommand.method = raw.method;
slashCommand.teamId = raw.team_id;
slashCommand.token = raw.token;
slashCommand.trigger = raw.trigger;
slashCommand.updateAt = raw.update_at;
};
return prepareBaseRecord({
action,
database,
tableName: SLASH_COMMAND,
value,
fieldsMapper,
}) as Promise<SlashCommandModel>;
};
/**
* transformMyTeamRecord: Prepares a record of the SERVER database 'MyTeam' table for update or create actions.
* @param {DataFactory} operator

View file

@ -10,7 +10,7 @@ import type SlashCommandModel from '@typings/database/models/servers/slash_comma
import type TeamModel from '@typings/database/models/servers/team';
import type UserModel from '@typings/database/models/servers/user';
const {CHANNEL, POST, SLASH_COMMAND, TEAM, USER} = MM_TABLES.SERVER;
const {CHANNEL, POST, TEAM, USER} = MM_TABLES.SERVER;
/**
* getValidRecordsForUpdate: Database Operations on some tables are expensive. As such, we would like to operate if and only if we are
@ -22,7 +22,7 @@ const {CHANNEL, POST, SLASH_COMMAND, TEAM, USER} = MM_TABLES.SERVER;
* @returns {boolean}
*/
export const getValidRecordsForUpdate = ({tableName, newValue, existingRecord}: IdenticalRecordArgs) => {
const guardTables = [CHANNEL, POST, SLASH_COMMAND, TEAM, USER];
const guardTables = [CHANNEL, POST, TEAM, USER];
if (guardTables.includes(tableName)) {
type Raw = Post | UserProfile | Team | SlashCommand | Channel;
type ExistingRecord = PostModel | UserModel | TeamModel | SlashCommandModel | ChannelModel;

View file

@ -21,7 +21,6 @@ import {
PreferenceSchema,
ReactionSchema,
RoleSchema,
SlashCommandSchema,
SystemSchema,
TeamChannelHistorySchema,
TeamMembershipSchema,
@ -54,7 +53,6 @@ export const serverSchema: AppSchema = appSchema({
PreferenceSchema,
ReactionSchema,
RoleSchema,
SlashCommandSchema,
SystemSchema,
TeamChannelHistorySchema,
TeamMembershipSchema,

View file

@ -18,7 +18,6 @@ export {default as PostsInChannelSchema} from './posts_in_channel';
export {default as PreferenceSchema} from './preference';
export {default as ReactionSchema} from './reaction';
export {default as RoleSchema} from './role';
export {default as SlashCommandSchema} from './slash_command';
export {default as SystemSchema} from './system';
export {default as TeamChannelHistorySchema} from './team_channel_history';
export {default as TeamMembershipSchema} from './team_membership';

View file

@ -1,23 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {tableSchema} from '@nozbe/watermelondb';
import {MM_TABLES} from '@constants/database';
const {SLASH_COMMAND} = MM_TABLES.SERVER;
export default tableSchema({
name: SLASH_COMMAND,
columns: [
{name: 'is_auto_complete', type: 'boolean'},
{name: 'description', type: 'string'},
{name: 'display_name', type: 'string'},
{name: 'hint', type: 'string'},
{name: 'method', type: 'string'},
{name: 'team_id', type: 'string', isIndexed: true},
{name: 'token', type: 'string'},
{name: 'trigger', type: 'string'},
{name: 'update_at', type: 'number'},
],
});

View file

@ -25,7 +25,6 @@ const {
PREFERENCE,
REACTION,
ROLE,
SLASH_COMMAND,
SYSTEM,
TEAM,
TEAM_CHANNEL_HISTORY,
@ -345,32 +344,6 @@ describe('*** Test schema for SERVER database ***', () => {
{name: 'permissions', type: 'string'},
],
},
[SLASH_COMMAND]: {
name: SLASH_COMMAND,
unsafeSql: undefined,
columns: {
is_auto_complete: {name: 'is_auto_complete', type: 'boolean'},
description: {name: 'description', type: 'string'},
display_name: {name: 'display_name', type: 'string'},
hint: {name: 'hint', type: 'string'},
method: {name: 'method', type: 'string'},
team_id: {name: 'team_id', type: 'string', isIndexed: true},
token: {name: 'token', type: 'string'},
trigger: {name: 'trigger', type: 'string'},
update_at: {name: 'update_at', type: 'number'},
},
columnArray: [
{name: 'is_auto_complete', type: 'boolean'},
{name: 'description', type: 'string'},
{name: 'display_name', type: 'string'},
{name: 'hint', type: 'string'},
{name: 'method', type: 'string'},
{name: 'team_id', type: 'string', isIndexed: true},
{name: 'token', type: 'string'},
{name: 'trigger', type: 'string'},
{name: 'update_at', type: 'number'},
],
},
[SYSTEM]: {
name: SYSTEM,
unsafeSql: undefined,

View file

@ -236,7 +236,6 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
const associatedChildren: Array<Query<Model>|undefined> = [
team.members,
team.slashCommands,
team.teamSearchHistories,
];
await Promise.all(associatedChildren.map(async (children) => {

View file

@ -4,7 +4,6 @@
import type CategoryModel from './category';
import type ChannelModel from './channel';
import type MyTeamModel from './my_team';
import type SlashCommandModel from './slash_command';
import type TeamChannelHistoryModel from './team_channel_history';
import type TeamMembershipModel from './team_membership';
import type TeamSearchHistoryModel from './team_search_history';
@ -57,9 +56,6 @@ export default class TeamModel extends Model {
/** myTeam : Retrieves additional information about the team that this user is possibly part of. This query might yield no result if the user isn't part of a team. */
myTeam: Relation<MyTeamModel>;
/** slashCommands : All the slash commands associated with this team */
slashCommands: Query<SlashCommandModel>;
/** teamChannelHistory : A history of the channels in this team that has been visited, ordered by the most recent and capped to the last 5 */
teamChannelHistory: Relation<TeamChannelHistoryModel>;