[Gekidou] Groups + group membership schema (#6251)

* First pass at adding groups to mobile

* Reverts back and updates the group vars

* Cleans tests

* Missing created/updated/deleted fields in types, many-many ref fix

* Adds to manager

* PR Feedback

* Failing test

* Move FK out of comment, add indexes

* updated docs/database/server artefacts

Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>
This commit is contained in:
Shaz MJ
2022-05-19 17:54:39 +10:00
committed by GitHub
parent 7e27113f61
commit 6d6085ed4b
26 changed files with 770 additions and 47 deletions

View File

@@ -18,6 +18,10 @@ export const MM_TABLES = {
CUSTOM_EMOJI: 'CustomEmoji',
DRAFT: 'Draft',
FILE: 'File',
GROUP: 'Group',
GROUP_CHANNEL: 'GroupChannel',
GROUP_MEMBERSHIP: 'GroupMembership',
GROUP_TEAM: 'GroupTeam',
MY_CHANNEL: 'MyChannel',
MY_CHANNEL_SETTINGS: 'MyChannelSettings',
MY_TEAM: 'MyTeam',

View File

@@ -12,7 +12,7 @@ import AppDatabaseMigrations from '@database/migration/app';
import ServerDatabaseMigrations from '@database/migration/server';
import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
import {CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
@@ -49,7 +49,7 @@ class DatabaseManager {
this.appModels = [InfoModel, GlobalModel, ServersModel];
this.serverModels = [
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,

View File

@@ -13,7 +13,7 @@ import AppDatabaseMigrations from '@database/migration/app';
import ServerDatabaseMigrations from '@database/migration/server';
import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
import {CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
@@ -45,7 +45,7 @@ class DatabaseManager {
this.appModels = [InfoModel, GlobalModel, ServersModel];
this.serverModels = [
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
MyChannelModel, MyChannelSettingsModel, MyTeamModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,

View File

@@ -0,0 +1,83 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {field, lazy} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type GroupInterface from '@typings/database/models/servers/group';
import type TeamModel from '@typings/database/models/servers/team';
import type UserModel from '@typings/database/models/servers/user';
const {
CHANNEL,
GROUP,
GROUP_CHANNEL,
GROUP_TEAM,
GROUP_MEMBERSHIP,
TEAM,
USER,
} = MM_TABLES.SERVER;
/**
* A Group is a collection of users that can be associated with a team or a channel
*/
export default class GroupModel extends Model implements GroupInterface {
/** table (name) : Group */
static table = GROUP;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** Groups are associated with Channels (relationship N:N) through GROUP_CHANNEL */
[GROUP_CHANNEL]: {type: 'has_many', foreignKey: 'group_id'},
/** Groups are associated with Members (Users) (relationship N:N) through GROUP_MEMBERSHIP */
[GROUP_MEMBERSHIP]: {type: 'has_many', foreignKey: 'group_id'},
/** Groups are associated with Teams (relationship N:N) through GROUP_TEAM */
[GROUP_TEAM]: {type: 'has_many', foreignKey: 'group_id'},
};
/** name : The name for the group */
@field('name') name!: string;
/** display_name : The display name for the group */
@field('display_name') displayName!: string;
/** description : The display name for the group */
@field('description') description!: string;
/** remote_id : The source for the group (i.e. custom) */
@field('source') source!: string;
/** remote_id : The remote id for the group (i.e. in a shared channel) */
@field('remote_id') remoteId!: string;
/** created_at : The creation date for this row */
@field('created_at') createdAt!: number;
/** updated_at : The update date for this row */
@field('updated_at') updatedAt!: number;
/** deleted_at : The delete date for this row */
@field('deleted_at') deletedAt!: number;
/** channels : Retrieves all the channels that are associated to this group */
@lazy channels = this.collections.
get<ChannelModel>(CHANNEL).
query(Q.on(GROUP_CHANNEL, 'group_id', this.id));
/** teams : Retrieves all the teams that are associated to this group */
@lazy teams = this.collections.
get<TeamModel>(TEAM).
query(Q.on(GROUP_TEAM, 'group_id', this.id));
/** members : Retrieves all the members that are associated to this group */
@lazy members = this.collections.
get<UserModel>(USER).
query(Q.on(GROUP_MEMBERSHIP, 'group_id', this.id));
}

View File

@@ -0,0 +1,54 @@
// 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 ChannelModel from '@typings/database/models/servers/channel';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupChannelInterface from '@typings/database/models/servers/group_channel';
const {CHANNEL, GROUP, GROUP_CHANNEL} = MM_TABLES.SERVER;
/**
* The GroupChannel model represents the 'association table' where many groups have channels and many channels are in
* groups (relationship type N:N)
*/
export default class GroupChannelModel extends Model implements GroupChannelInterface {
/** table (name) : GroupChannel */
static table = GROUP_CHANNEL;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** A GroupChannel belongs to a Group */
[GROUP]: {type: 'belongs_to', key: 'group_id'},
/** A GroupChannel has a Channel */
[CHANNEL]: {type: 'belongs_to', key: 'channel_id'},
};
/** group_id : The foreign key to the related Group record */
@field('group_id') groupId!: string;
/** channel_id : The foreign key to the related Channel record */
@field('channel_id') channelId!: string;
/** created_at : The creation date for this row */
@field('created_at') createdAt!: number;
/** updated_at : The update date for this row */
@field('updated_at') updatedAt!: number;
/** deleted_at : The delete date for this row */
@field('deleted_at') deletedAt!: number;
/** group : The related group */
@immutableRelation(GROUP, 'group_id') group!: Relation<GroupModel>;
/** channel : The related channel */
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
}

View File

@@ -0,0 +1,54 @@
// 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 GroupModel from '@typings/database/models/servers/group';
import type GroupMembershipInterface from '@typings/database/models/servers/group_membership';
import type UserModel from '@typings/database/models/servers/user';
const {USER, GROUP, GROUP_MEMBERSHIP} = MM_TABLES.SERVER;
/**
* The GroupMembership model represents the 'association table' where many groups have users and many users are in
* groups (relationship type N:N)
*/
export default class GroupMembershipModel extends Model implements GroupMembershipInterface {
/** table (name) : GroupMembership */
static table = GROUP_MEMBERSHIP;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** A GroupMembership belongs to a Group */
[GROUP]: {type: 'belongs_to', key: 'group_id'},
/** A GroupMembership has a User */
[USER]: {type: 'belongs_to', key: 'user_id'},
};
/** group_id : The foreign key to the related Group record */
@field('group_id') groupId!: string;
/** user_id : The foreign key to the related User record */
@field('user_id') userId!: string;
/** created_at : The creation date for this row */
@field('created_at') createdAt!: number;
/** updated_at : The update date for this row */
@field('updated_at') updatedAt!: number;
/** deleted_at : The delete date for this row */
@field('deleted_at') deletedAt!: number;
/** group : The related group */
@immutableRelation(GROUP, 'group_id') group!: Relation<GroupModel>;
/** member : The related member */
@immutableRelation(USER, 'user_id') member!: Relation<UserModel>;
}

View File

@@ -0,0 +1,54 @@
// 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 GroupModel from '@typings/database/models/servers/group';
import type GroupTeamInterface from '@typings/database/models/servers/group_team';
import type TeamModel from '@typings/database/models/servers/team';
const {TEAM, GROUP, GROUP_TEAM} = MM_TABLES.SERVER;
/**
* The GroupTeam model represents the 'association table' where many groups have teams and many teams are in
* groups (relationship type N:N)
*/
export default class GroupTeamModel extends Model implements GroupTeamInterface {
/** table (name) : GroupTeam */
static table = GROUP_TEAM;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** A GroupTeam belongs to a Group */
[GROUP]: {type: 'belongs_to', key: 'group_id'},
/** A GroupTeam has a Team */
[TEAM]: {type: 'belongs_to', key: 'team_id'},
};
/** group_id : The foreign key to the related Group record */
@field('group_id') groupId!: string;
/** team_id : The foreign key to the related Team record */
@field('team_id') teamId!: string;
/** created_at : The creation date for this row */
@field('created_at') createdAt!: number;
/** updated_at : The update date for this row */
@field('updated_at') updatedAt!: number;
/** deleted_at : The delete date for this row */
@field('deleted_at') deletedAt!: number;
/** group : The related group */
@immutableRelation(GROUP, 'group_id') group!: Relation<GroupModel>;
/** team : The related team */
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
}

View File

@@ -9,6 +9,10 @@ export {default as ChannelModel} from './channel';
export {default as CustomEmojiModel} from './custom_emoji';
export {default as DraftModel} from './draft';
export {default as FileModel} from './file';
export {default as GroupModel} from './group';
export {default as GroupChannelModel} from './group_channel';
export {default as GroupMembershipModel} from './group_membership';
export {default as GroupTeamModel} from './group_team';
export {default as MyChannelModel} from './my_channel';
export {default as MyChannelSettingsModel} from './my_channel_settings';
export {default as MyTeamModel} from './my_team';

View File

@@ -12,6 +12,10 @@ import {
CustomEmojiSchema,
DraftSchema,
FileSchema,
GroupSchema,
GroupChannelSchema,
GroupMembershipSchema,
GroupTeamSchema,
MyChannelSchema,
MyChannelSettingsSchema,
MyTeamSchema,
@@ -43,6 +47,10 @@ export const serverSchema: AppSchema = appSchema({
CustomEmojiSchema,
DraftSchema,
FileSchema,
GroupSchema,
GroupChannelSchema,
GroupMembershipSchema,
GroupTeamSchema,
MyChannelSchema,
MyChannelSettingsSchema,
MyTeamSchema,

View File

@@ -0,0 +1,22 @@
// 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 {GROUP} = MM_TABLES.SERVER;
export default tableSchema({
name: GROUP,
columns: [
{name: 'display_name', type: 'string'},
{name: 'name', type: 'string', isIndexed: true},
{name: 'description', type: 'string'},
{name: 'source', type: 'string'},
{name: 'remote_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
});

View File

@@ -0,0 +1,19 @@
// 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 {GROUP_CHANNEL} = MM_TABLES.SERVER;
export default tableSchema({
name: GROUP_CHANNEL,
columns: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'channel_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
});

View File

@@ -0,0 +1,19 @@
// 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 {GROUP_MEMBERSHIP} = MM_TABLES.SERVER;
export default tableSchema({
name: GROUP_MEMBERSHIP,
columns: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'user_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
});

View File

@@ -0,0 +1,19 @@
// 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 {GROUP_TEAM} = MM_TABLES.SERVER;
export default tableSchema({
name: GROUP_TEAM,
columns: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'team_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
});

View File

@@ -9,6 +9,10 @@ export {default as ChannelSchema} from './channel';
export {default as CustomEmojiSchema} from './custom_emoji';
export {default as DraftSchema} from './draft';
export {default as FileSchema} from './file';
export {default as GroupSchema} from './group';
export {default as GroupChannelSchema} from './group_channel';
export {default as GroupTeamSchema} from './group_team';
export {default as GroupMembershipSchema} from './group_membership';
export {default as MyChannelSchema} from './my_channel';
export {default as MyChannelSettingsSchema} from './my_channel_settings';
export {default as MyTeamSchema} from './my_team';

View File

@@ -16,6 +16,10 @@ const {
CUSTOM_EMOJI,
DRAFT,
FILE,
GROUP,
GROUP_CHANNEL,
GROUP_MEMBERSHIP,
GROUP_TEAM,
MY_CHANNEL,
MY_CHANNEL_SETTINGS,
MY_TEAM,
@@ -237,6 +241,84 @@ describe('*** Test schema for SERVER database ***', () => {
{name: 'width', type: 'number'},
],
},
[GROUP]: {
name: GROUP,
unsafeSql: undefined,
columns: {
display_name: {name: 'display_name', type: 'string'},
name: {name: 'name', type: 'string', isIndexed: true},
description: {name: 'description', type: 'string'},
source: {name: 'source', type: 'string'},
remote_id: {name: 'remote_id', type: 'string', isIndexed: true},
created_at: {name: 'created_at', type: 'number'},
updated_at: {name: 'updated_at', type: 'number'},
deleted_at: {name: 'deleted_at', type: 'number'},
},
columnArray: [
{name: 'display_name', type: 'string'},
{name: 'name', type: 'string', isIndexed: true},
{name: 'description', type: 'string'},
{name: 'source', type: 'string'},
{name: 'remote_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
},
[GROUP_CHANNEL]: {
name: GROUP_CHANNEL,
unsafeSql: undefined,
columns: {
group_id: {name: 'group_id', type: 'string', isIndexed: true},
channel_id: {name: 'channel_id', type: 'string', isIndexed: true},
created_at: {name: 'created_at', type: 'number'},
updated_at: {name: 'updated_at', type: 'number'},
deleted_at: {name: 'deleted_at', type: 'number'},
},
columnArray: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'channel_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
},
[GROUP_MEMBERSHIP]: {
name: GROUP_MEMBERSHIP,
unsafeSql: undefined,
columns: {
group_id: {name: 'group_id', type: 'string', isIndexed: true},
user_id: {name: 'user_id', type: 'string', isIndexed: true},
created_at: {name: 'created_at', type: 'number'},
updated_at: {name: 'updated_at', type: 'number'},
deleted_at: {name: 'deleted_at', type: 'number'},
},
columnArray: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'user_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
},
[GROUP_TEAM]: {
name: GROUP_TEAM,
unsafeSql: undefined,
columns: {
group_id: {name: 'group_id', type: 'string', isIndexed: true},
team_id: {name: 'team_id', type: 'string', isIndexed: true},
created_at: {name: 'created_at', type: 'number'},
updated_at: {name: 'updated_at', type: 'number'},
deleted_at: {name: 'deleted_at', type: 'number'},
},
columnArray: [
{name: 'group_id', type: 'string', isIndexed: true},
{name: 'team_id', type: 'string', isIndexed: true},
{name: 'created_at', type: 'number'},
{name: 'updated_at', type: 'number'},
{name: 'deleted_at', type: 'number'},
],
},
[POSTS_IN_THREAD]: {
name: POSTS_IN_THREAD,
unsafeSql: undefined,

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 KiB

After

Width:  |  Height:  |  Size: 711 KiB

File diff suppressed because one or more lines are too long

View File

@@ -122,6 +122,61 @@ CREATE TABLE [File] (
)
)
CREATE TABLE [Group] (
-- server-generated
[id] string NOT NULL ,
[name] string NOT NULL ,
[display_name] string NOT NULL ,
[description] string NOT NULL ,
[remote_id] string NOT NULL ,
[source] string NOT NULL ,
[created_at] number NOT NULL ,
[updated_at] number NOT NULL ,
[deleted_at] number NOT NULL ,
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED (
[id] ASC
)
)
CREATE TABLE [GroupChannel] (
-- composition ID Group.id-Channel.id
[id] string NOT NULL ,
[group_id] string NOT NULL ,
[channel_id] string NOT NULL ,
[created_at] number NOT NULL ,
[updated_at] number NOT NULL ,
[deleted_at] number NOT NULL ,
CONSTRAINT [PK_GroupChannel] PRIMARY KEY CLUSTERED (
[id] ASC
)
)
CREATE TABLE [GroupMembership] (
-- composition ID Group.id-User.id
[id] string NOT NULL ,
[group_id] string NOT NULL ,
[user_id] string NOT NULL ,
[created_at] number NOT NULL ,
[updated_at] number NOT NULL ,
[deleted_at] number NOT NULL ,
CONSTRAINT [PK_GroupMembership] PRIMARY KEY CLUSTERED (
[id] ASC
)
)
CREATE TABLE [GroupTeam] (
-- composition ID Group.id-Team.id
[id] string NOT NULL ,
[group_id] string NOT NULL ,
[team_id] string NOT NULL ,
[created_at] number NOT NULL ,
[updated_at] number NOT NULL ,
[deleted_at] number NOT NULL ,
CONSTRAINT [PK_GroupTeam] PRIMARY KEY CLUSTERED (
[id] ASC
)
)
CREATE TABLE [MyChannel] (
-- same as Channel.id
[id] string NOT NULL ,
@@ -413,6 +468,36 @@ REFERENCES [Post] ([id])
ALTER TABLE [File] CHECK CONSTRAINT [FK_File_post_id]
ALTER TABLE [GroupChannel] WITH CHECK ADD CONSTRAINT [FK_GroupChannel_group_id] FOREIGN KEY([group_id])
REFERENCES [Group] ([id])
ALTER TABLE [GroupChannel] CHECK CONSTRAINT [FK_GroupChannel_group_id]
ALTER TABLE [GroupChannel] WITH CHECK ADD CONSTRAINT [FK_GroupChannel_channel_id] FOREIGN KEY([channel_id])
REFERENCES [Channel] ([id])
ALTER TABLE [GroupChannel] CHECK CONSTRAINT [FK_GroupChannel_channel_id]
ALTER TABLE [GroupMembership] WITH CHECK ADD CONSTRAINT [FK_GroupMembership_group_id] FOREIGN KEY([group_id])
REFERENCES [Group] ([id])
ALTER TABLE [GroupMembership] CHECK CONSTRAINT [FK_GroupMembership_group_id]
ALTER TABLE [GroupMembership] WITH CHECK ADD CONSTRAINT [FK_GroupMembership_user_id] FOREIGN KEY([user_id])
REFERENCES [User] ([id])
ALTER TABLE [GroupMembership] CHECK CONSTRAINT [FK_GroupMembership_user_id]
ALTER TABLE [GroupTeam] WITH CHECK ADD CONSTRAINT [FK_GroupTeam_group_id] FOREIGN KEY([group_id])
REFERENCES [Group] ([id])
ALTER TABLE [GroupTeam] CHECK CONSTRAINT [FK_GroupTeam_group_id]
ALTER TABLE [GroupTeam] WITH CHECK ADD CONSTRAINT [FK_GroupTeam_team_id] FOREIGN KEY([team_id])
REFERENCES [Team] ([id])
ALTER TABLE [GroupTeam] CHECK CONSTRAINT [FK_GroupTeam_team_id]
ALTER TABLE [MyChannel] WITH CHECK ADD CONSTRAINT [FK_MyChannel_id] FOREIGN KEY([id])
REFERENCES [Channel] ([id])
@@ -493,11 +578,6 @@ REFERENCES [Team] ([id])
ALTER TABLE [ThreadsInTeam] CHECK CONSTRAINT [FK_ThreadsInTeam_team_id]
ALTER TABLE [ThreadsInTeam] WITH CHECK ADD CONSTRAINT [FK_ThreadsInTeam_thread_id] FOREIGN KEY([thread_id])
REFERENCES [Thread] ([id])
ALTER TABLE [ThreadsInTeam] CHECK CONSTRAINT [FK_ThreadsInTeam_thread_id]
ALTER TABLE [ThreadParticipant] WITH CHECK ADD CONSTRAINT [FK_ThreadParticipant_thread_id] FOREIGN KEY([thread_id])
REFERENCES [Thread] ([id])
@@ -541,6 +621,30 @@ ON [Draft] ([root_id])
CREATE INDEX [idx_File_post_id]
ON [File] ([post_id])
CREATE INDEX [idx_Group_name]
ON [Group] ([name])
CREATE INDEX [idx_Group_remote_id]
ON [Group] ([remote_id])
CREATE INDEX [idx_GroupChannel_group_id]
ON [GroupChannel] ([group_id])
CREATE INDEX [idx_GroupChannel_channel_id]
ON [GroupChannel] ([channel_id])
CREATE INDEX [idx_GroupMembership_group_id]
ON [GroupMembership] ([group_id])
CREATE INDEX [idx_GroupMembership_user_id]
ON [GroupMembership] ([user_id])
CREATE INDEX [idx_GroupTeam_group_id]
ON [GroupTeam] ([group_id])
CREATE INDEX [idx_GroupTeam_team_id]
ON [GroupTeam] ([team_id])
CREATE INDEX [idx_Post_channel_id]
ON [Post] ([channel_id])

View File

@@ -84,6 +84,44 @@ post_id string INDEX FK >- Post.id
size number
width number
Group
-
id PK string # server-generated
name string INDEX
display_name string
description string
remote_id string INDEX
source string
created_at number
updated_at number
deleted_at number
GroupChannel
-
id PK string # composition ID Group.id-Channel.id
group_id string INDEX FK >- Group.id
channel_id string INDEX FK >- Channel.id
created_at number
updated_at number
deleted_at number
GroupMembership
-
id PK string # composition ID Group.id-User.id
group_id string INDEX FK >- Group.id
user_id string INDEX FK >- User.id
created_at number
updated_at number
deleted_at number
GroupTeam
-
id PK string # composition ID Group.id-Team.id
group_id string INDEX FK >- Group.id
team_id string INDEX FK >- Team.id
created_at number
updated_at number
deleted_at number
MyChannel
-

48
types/api/groups.d.ts vendored
View File

@@ -1,37 +1,31 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
type SyncableType = 'team' | 'channel';
type SyncablePatch = {
scheme_admin: boolean;
auto_add: boolean;
};
type Group = {
id: string;
name: string;
display_name: string;
description: string;
type: string;
source: string;
remote_id: string;
member_count: number;
allow_reference: boolean;
create_at: number;
update_at: number;
delete_at: number;
has_syncables: boolean;
member_count: number;
scheme_admin?: boolean;
allow_reference: boolean;
};
type GroupTeam = {
team_id: string;
team_display_name: string;
team_type: string;
group_id: string;
auto_add: boolean;
scheme_admin?: boolean;
create_at: number;
delete_at: number;
update_at: number;
};
}
type GroupChannel = {
channel_id: string;
channel_display_name: string;
@@ -41,31 +35,11 @@ type GroupChannel = {
team_type: string;
group_id: string;
auto_add: boolean;
scheme_admin?: boolean;
member_count?: number;
timezone_count?: number;
create_at: number;
delete_at: number;
update_at: number;
member_count?: number;
timezone_count?: number;
};
type GroupSyncables = {
teams: GroupTeam[];
channels: GroupChannel[];
};
type GroupsState = {
syncables: {
[x: string]: GroupSyncables;
};
members: any;
groups: {
[x: string]: Group;
};
myGroups: {
[x: string]: Group;
};
};
type GroupSearchOpts = {
q: string;
is_linked?: boolean;
is_configured?: boolean;
};
}
type GroupMembership = UserProfile[]

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Query} from '@nozbe/watermelondb';
import {lazy} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import type ChannelModel from './channel';
import type TeamModel from './team';
import type UserModel from './user';
/**
* A Group is a collection of users, associated to teams and/or channels
*/
export default class GroupModel extends Model {
/** table (name) : Group */
static table: string;
/** associations : Describes every relationship to this table. */
static associations: Associations;
/** name : The name of the group */
name: string;
/** display_name : The display name for the group */
displayName: string;
/** description : A short description of the group */
description: string;
/** source : The source of the group */
source: string;
/** remote_id : The remote_id of the group */
remoteId: string;
/** created_at : The timestamp for when it was created */
createdAt: number;
/** updated_at : The timestamp for when it was updated */
updatedAt: number;
/** deleted_at : The timestamp for when it was deleted */
deletedAt: number;
/** channels : All the channels associated with this group */
@lazy channels: Query<ChannelModel>;
/** teams : All the teams associated with this group */
@lazy teams: Query<TeamModel>;
/** members : All the members (users) of this group */
@lazy members: Query<UserModel>;
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import type ChannelModel from './channel';
import type GroupModel from './group';
/**
* The GroupChannel model represents the 'association table' where many groups have channels and many channels are in
* groups (relationship type N:N)
*/
export default class GroupChannelModel extends Model {
/** table (name) : GroupChannel */
static table: string;
/** associations : Describes every relationship to this table. */
static associations: Associations;
/** group_id : The foreign key to the related Group record */
groupId: string;
/* channel_id : The foreign key to the related User record*/
channelId: string;
/** created_at : The timestamp for when it was created */
createdAt: number;
/** updated_at : The timestamp for when it was updated */
updatedAt: number;
/** deleted_at : The timestamp for when it was deleted */
deletedAt: number;
/** group : The related group */
group: Relation<GroupModel>;
/** channel : The related channel */
channel: Relation<ChannelModel>;
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import type GroupModel from './group';
import type UserModel from './user';
/**
* The GroupMembership model represents the 'association table' where many groups have users and many users are in
* groups (relationship type N:N)
*/
export default class GroupMembershipModel extends Model {
/** table (name) : GroupMembership */
static table: string;
/** associations : Describes every relationship to this table. */
static associations: Associations;
/** group_id : The foreign key to the related Group record */
groupId: string;
/* user_id : The foreign key to the related User record*/
userId: string;
/** created_at : The timestamp for when it was created */
createdAt: number;
/** updated_at : The timestamp for when it was updated */
updatedAt: number;
/** deleted_at : The timestamp for when it was deleted */
deletedAt: number;
/** group : The related group */
group: Relation<GroupModel>;
/** user : The related user */
member: Relation<UserModel>;
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import type GroupModel from './group';
import type TeamModel from './team';
/**
* The GroupTeam model represents the 'association table' where many groups have teams and many teams are in
* groups (relationship type N:N)
*/
export default class GroupTeamModel extends Model {
/** table (name) : GroupTeam */
static table: string;
/** associations : Describes every relationship to this table. */
static associations: Associations;
/** group_id : The foreign key to the related Group record */
groupId: string;
/* team_id : The foreign key to the related Team record*/
teamId: string;
/** created_at : The timestamp for when it was created */
createdAt: number;
/** updated_at : The timestamp for when it was updated */
updatedAt: number;
/** deleted_at : The timestamp for when it was deleted */
deletedAt: number;
/** group : The related group */
group: Relation<GroupModel>;
/** team : The related team */
team: Relation<TeamModel>;
}

View File

@@ -99,6 +99,10 @@ type RawValue =
| CustomEmoji
| Draft
| FileInfo
| Group
| GroupChannel
| GroupTeam
| GroupMembership
| IdValue
| Metadata
| MyTeam