Skip to content

Commit

Permalink
feat(mysql): no more need to write indices
Browse files Browse the repository at this point in the history
updated: github, monitor, schedule, status, teach
  • Loading branch information
shigma committed Mar 25, 2021
1 parent eb9ada5 commit f15df3b
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 44 deletions.
3 changes: 2 additions & 1 deletion packages/koishi-core/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ export namespace Tables {

interface Meta<O> {
primary?: keyof O
unique?: (keyof O)[]
type?: 'incremental'
}

export const config: { [T in TableType]?: Meta<Tables[T]> } = {}

export function extend<T extends TableType>(name: T, meta?: Meta<Tables[T]>) {
config[name] = { primary: 'id', type: 'incremental', ...meta } as any
config[name] = { primary: 'id', unique: [], type: 'incremental', ...meta } as any
}

extend('user')
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-github/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ Tables.extend('github', { primary: 'name' })
Database.extend('koishi-plugin-mysql', ({ tables, Domain }) => {
tables.user.ghAccessToken = 'varchar(50)'
tables.user.ghRefreshToken = 'varchar(50)'
tables.channel.githubWebhooks = new Domain.Json('json default "{}"')
tables.github = Object.assign<any, any>(['primary key (`name`)'], {
tables.channel.githubWebhooks = new Domain.Json('text', {})
tables.github = {
id: 'int',
name: 'varchar(50)',
secret: 'varchar(50)',
})
}
})

interface Repository {
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-monitor/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ Database.extend('koishi-plugin-mysql', {

Database.extend('koishi-plugin-mysql', ({ tables, Domain }) => {
tables.channel.subscribe = new Domain.Json()
tables.subscribe = Object.assign<any, any>([], {
tables.subscribe = {
id: '`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT',
names: new Domain.Array(),
})
}
})

Database.extend('koishi-plugin-mongo', {
Expand Down
33 changes: 19 additions & 14 deletions packages/plugin-mysql/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,31 @@ class MysqlDatabase {
for (const name in MysqlDatabase.tables) {
const table = { ...MysqlDatabase.tables[name] }
// create platform rows
const platforms = new Set<string>(this.app.bots.map(bot => bot.platform))
if (name === 'user') {
let index = MysqlDatabase.tables[name]['length']
const platforms = new Set<string>(this.app.bots.map(bot => bot.platform))
platforms.forEach(name => {
const key = escapeId(name)
for (const name of platforms) {
table[name] = 'varchar(50) null default null'
table[index++] = `unique index ${key} (${key}) using btree`
})
}
}
if (!tables[name]) {
const cols = Object.keys(table)
.filter((key) => typeof table[key] !== 'function')
.map((key) => {
if (+key * 0 === 0) return table[key]
return `\`${key}\` ${MysqlDatabase.Domain.definition(table[key])}`
})
.map((key) => `${escapeId(key)} ${MysqlDatabase.Domain.definition(table[key])}`)
const { primary, unique } = KoishiTables.config[name as TableType]
cols.push(`primary key (${escapeId(primary)})`)
for (const key of unique) {
cols.push(`unique index (${escapeId(key)})`)
}
if (name === 'user') {
for (const key of platforms) {
cols.push(`unique index (${escapeId(key)})`)
}
}
logger.info('auto creating table %c', name)
await this.query(`CREATE TABLE ?? (${cols.join(',')}) COLLATE = ?`, [name, this.config.charset])
} else {
const cols = Object.keys(table)
.filter(key => +key * 0 !== 0 && typeof table[key] !== 'function' && !tables[name].includes(key))
.filter(key => typeof table[key] !== 'function' && !tables[name].includes(key))
.map(key => `ADD \`${key}\` ${MysqlDatabase.Domain.definition(table[key])}`)
if (!cols.length) continue
logger.info('auto updating table %c', name)
Expand Down Expand Up @@ -186,7 +190,7 @@ MysqlDatabase.prototype.escapeId = escapeId
namespace MysqlDatabase {
type Declarations = {
[T in TableType]?: {
[K in keyof Tables[T]]: string | (() => string) | Domain<Tables[T][K]>
[K in keyof Tables[T]]?: string | (() => string) | Domain<Tables[T][K]>
}
}

Expand Down Expand Up @@ -231,14 +235,15 @@ namespace MysqlDatabase {
}

export class Json implements Domain {
constructor(public definition = 'JSON') {}
// mysql does not support text column with default value
constructor(public definition = 'text', private defaultValue?: any) {}

toString(value: any) {
return JSON.stringify(value)
}

valueOf(field: FieldInfo) {
return JSON.parse(field.string())
return JSON.parse(field.string()) || this.defaultValue
}
}
}
Expand Down
13 changes: 4 additions & 9 deletions packages/plugin-mysql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,21 @@ Database.extend(MysqlDatabase, {
})

Database.extend(MysqlDatabase, ({ tables, Domain }) => {
tables.user = Object.assign<any, any>([
'primary key (`id`) using btree',
'unique index `name` (`name`) using btree',
], {
tables.user = {
id: new Domain.String(`bigint(20) unsigned not null auto_increment`),
name: `varchar(50) null default null collate 'utf8mb4_general_ci'`,
flag: `bigint(20) unsigned not null default '0'`,
authority: `tinyint(4) unsigned not null default '0'`,
usage: new Domain.Json(),
timers: new Domain.Json(),
})
}

tables.channel = Object.assign<any, any>([
'primary key (`id`) using btree',
], {
tables.channel = {
id: `varchar(50) not null`,
flag: `bigint(20) unsigned not null default '0'`,
assignee: `varchar(50) null`,
disable: new Domain.Array(),
})
}
})

export const name = 'mysql'
Expand Down
8 changes: 3 additions & 5 deletions packages/plugin-schedule/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ export interface Schedule {
Tables.extend('schedule')

Database.extend('koishi-plugin-mysql', ({ Domain, tables }) => {
tables.schedule = Object.assign<any, any>([
'PRIMARY KEY (`id`) USING BTREE',
], {
tables.schedule = {
id: `INT(10) UNSIGNED NOT NULL AUTO_INCREMENT`,
assignee: `VARCHAR(50) NOT NULL`,
time: `TIMESTAMP NULL DEFAULT NULL`,
lastCall: `TIMESTAMP NULL DEFAULT NULL`,
interval: `BIGINT(20) UNSIGNED NOT NULL DEFAULT '0'`,
command: `MEDIUMTEXT NOT NULL COLLATE 'utf8mb4_general_ci'`,
command: `MEDIUMTEXT NOT NULL`,
session: new Domain.Json(),
})
}
})
8 changes: 2 additions & 6 deletions packages/plugin-status/server/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ namespace Stat {
super(table, fields)

Database.extend('koishi-plugin-mysql', ({ tables, Domain }) => {
tables[table] = Object.assign([
'primary key (`time`)',
], Object.fromEntries(fields.map(key => [key, new Domain.Json('text')])))
tables[table] = Object.fromEntries(fields.map(key => [key, new Domain.Json()]))
tables[table].time = timeDomain
})
}
Expand Down Expand Up @@ -88,9 +86,7 @@ namespace Stat {
super(table, fields)

Database.extend('koishi-plugin-mysql', ({ tables }) => {
tables[table] = Object.assign([
'primary key (`time`)',
], Object.fromEntries(fields.map(key => [key, 'int unsigned'])))
tables[table] = Object.fromEntries(fields.map(key => [key, 'int unsigned']))
tables[table].time = timeDomain
})
}
Expand Down
6 changes: 2 additions & 4 deletions packages/plugin-teach/src/database/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ Database.extend('koishi-plugin-mysql', {
})

Database.extend('koishi-plugin-mysql', ({ Domain, tables }) => {
tables.dialogue = Object.assign<any, any>([
'PRIMARY KEY (`id`) USING BTREE',
], {
tables.dialogue = {
id: `INT(11) UNSIGNED NOT NULL AUTO_INCREMENT`,
flag: `INT(10) UNSIGNED NOT NULL DEFAULT '0'`,
probS: `DECIMAL(4,3) UNSIGNED NOT NULL DEFAULT '1.000'`,
Expand All @@ -85,7 +83,7 @@ Database.extend('koishi-plugin-mysql', ({ Domain, tables }) => {
predecessors: new Domain.Array(`TINYTEXT`),
successorTimeout: `INT(10) UNSIGNED NOT NULL DEFAULT '0'`,
writer: 'INT(11) UNSIGNED',
})
}
})

export default function apply(ctx: Context, config: Dialogue.Config) {
Expand Down

0 comments on commit f15df3b

Please sign in to comment.