chore: update migrator

This commit is contained in:
steven 2023-09-29 12:47:49 +08:00
parent 87ddeb2c79
commit 8168fb71a8
5 changed files with 136 additions and 168 deletions

View File

@ -14,130 +14,111 @@ DROP TABLE IF EXISTS `idp`;
-- migration_history
CREATE TABLE `migration_history` (
`version` varchar(255) NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`version`)
`version` VARCHAR(255) NOT NULL PRIMARY KEY,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- system_setting
CREATE TABLE `system_setting` (
`name` varchar(255) NOT NULL,
`value` text NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`name`)
`name` VARCHAR(255) NOT NULL PRIMARY KEY,
`value` TEXT NOT NULL,
`description` TEXT NOT NULL
);
-- user
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_status` varchar(255) NOT NULL DEFAULT 'NORMAL',
`username` varchar(255) NOT NULL,
`role` varchar(255) NOT NULL DEFAULT 'USER',
`email` varchar(255) NOT NULL DEFAULT '',
`nickname` varchar(255) NOT NULL DEFAULT '',
`password_hash` varchar(255) NOT NULL,
`avatar_url` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
CONSTRAINT `user_chk_1` CHECK ((`row_status` in (_utf8mb4'NORMAL',_utf8mb4'ARCHIVED'))),
CONSTRAINT `user_chk_2` CHECK ((`role` in (_utf8mb4'HOST',_utf8mb4'ADMIN',_utf8mb4'USER')))
`row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL',
`username` VARCHAR(255) NOT NULL UNIQUE,
`role` VARCHAR(255) NOT NULL DEFAULT 'USER',
`email` VARCHAR(255) NOT NULL DEFAULT '',
`nickname` VARCHAR(255) NOT NULL DEFAULT '',
`password_hash` VARCHAR(255) NOT NULL,
`avatar_url` TEXT NOT NULL
);
-- user_setting
CREATE TABLE `user_setting` (
`user_id` int NOT NULL,
`key` varchar(255) NOT NULL,
`value` text NOT NULL,
UNIQUE KEY `user_id` (`user_id`,`key`)
`user_id` INT NOT NULL,
`key` VARCHAR(255) NOT NULL,
`value` TEXT NOT NULL,
UNIQUE(`user_id`,`key`)
);
-- memo
CREATE TABLE `memo` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_status` varchar(255) NOT NULL DEFAULT 'NORMAL',
`content` text NOT NULL,
`visibility` varchar(255) NOT NULL DEFAULT 'PRIVATE',
PRIMARY KEY (`id`),
KEY `creator_id` (`creator_id`),
KEY `visibility` (`visibility`),
CONSTRAINT `memo_chk_1` CHECK ((`row_status` in (_utf8mb4'NORMAL',_utf8mb4'ARCHIVED'))),
CONSTRAINT `memo_chk_2` CHECK ((`visibility` in (_utf8mb4'PUBLIC',_utf8mb4'PROTECTED',_utf8mb4'PRIVATE')))
`row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL',
`content` TEXT NOT NULL,
`visibility` VARCHAR(255) NOT NULL DEFAULT 'PRIVATE'
);
-- memo_organizer
CREATE TABLE `memo_organizer` (
`memo_id` int NOT NULL,
`user_id` int NOT NULL,
`pinned` int NOT NULL DEFAULT '0',
UNIQUE KEY `memo_id` (`memo_id`,`user_id`),
CONSTRAINT `memo_organizer_chk_1` CHECK ((`pinned` in (0,1)))
`memo_id` INT NOT NULL,
`user_id` INT NOT NULL,
`pinned` INT NOT NULL DEFAULT '0',
UNIQUE(`memo_id`,`user_id`)
);
-- memo_relation
CREATE TABLE `memo_relation` (
`memo_id` int NOT NULL,
`related_memo_id` int NOT NULL,
`type` varchar(256) NOT NULL,
UNIQUE KEY `memo_id` (`memo_id`,`related_memo_id`,`type`)
`memo_id` INT NOT NULL,
`related_memo_id` INT NOT NULL,
`type` VARCHAR(256) NOT NULL,
UNIQUE(`memo_id`,`related_memo_id`,`type`)
);
-- resource
CREATE TABLE `resource` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`filename` text NOT NULL,
`blob` blob,
`external_link` text NOT NULL,
`type` varchar(255) NOT NULL DEFAULT '',
`size` int NOT NULL DEFAULT '0',
`internal_path` varchar(255) NOT NULL DEFAULT '',
`memo_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `creator_id` (`creator_id`),
KEY `memo_id` (`memo_id`)
`filename` TEXT NOT NULL,
`blob` BLOB,
`external_link` TEXT NOT NULL,
`type` VARCHAR(255) NOT NULL DEFAULT '',
`size` INT NOT NULL DEFAULT '0',
`INTernal_path` VARCHAR(255) NOT NULL DEFAULT '',
`memo_id` INT DEFAULT NULL
);
-- tag
CREATE TABLE `tag` (
`name` varchar(255) NOT NULL,
`creator_id` int NOT NULL,
UNIQUE KEY `name` (`name`,`creator_id`)
`name` VARCHAR(255) NOT NULL,
`creator_id` INT NOT NULL,
UNIQUE(`name`,`creator_id`)
);
-- activity
CREATE TABLE `activity` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`type` varchar(255) NOT NULL DEFAULT '',
`level` varchar(255) NOT NULL DEFAULT 'INFO',
`payload` text NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `activity_chk_1` CHECK ((`level` in (_utf8mb4'INFO',_utf8mb4'WARN',_utf8mb4'ERROR')))
`type` VARCHAR(255) NOT NULL DEFAULT '',
`level` VARCHAR(255) NOT NULL DEFAULT 'INFO',
`payload` TEXT NOT NULL
);
-- storage
CREATE TABLE `storage` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`type` varchar(256) NOT NULL,
`config` text NOT NULL,
PRIMARY KEY (`id`)
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(256) NOT NULL,
`type` VARCHAR(256) NOT NULL,
`config` TEXT NOT NULL
);
-- idp
CREATE TABLE `idp` (
`id` int NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`type` text NOT NULL,
`identifier_filter` varchar(256) NOT NULL DEFAULT '',
`config` text NOT NULL,
PRIMARY KEY (`id`)
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` TEXT NOT NULL,
`type` TEXT NOT NULL,
`identifier_filter` VARCHAR(256) NOT NULL DEFAULT '',
`config` TEXT NOT NULL
);

View File

@ -14,130 +14,111 @@ DROP TABLE IF EXISTS `idp`;
-- migration_history
CREATE TABLE `migration_history` (
`version` varchar(255) NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`version`)
`version` VARCHAR(255) NOT NULL PRIMARY KEY,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- system_setting
CREATE TABLE `system_setting` (
`name` varchar(255) NOT NULL,
`value` text NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`name`)
`name` VARCHAR(255) NOT NULL PRIMARY KEY,
`value` TEXT NOT NULL,
`description` TEXT NOT NULL
);
-- user
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_status` varchar(255) NOT NULL DEFAULT 'NORMAL',
`username` varchar(255) NOT NULL,
`role` varchar(255) NOT NULL DEFAULT 'USER',
`email` varchar(255) NOT NULL DEFAULT '',
`nickname` varchar(255) NOT NULL DEFAULT '',
`password_hash` varchar(255) NOT NULL,
`avatar_url` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
CONSTRAINT `user_chk_1` CHECK ((`row_status` in (_utf8mb4'NORMAL',_utf8mb4'ARCHIVED'))),
CONSTRAINT `user_chk_2` CHECK ((`role` in (_utf8mb4'HOST',_utf8mb4'ADMIN',_utf8mb4'USER')))
`row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL',
`username` VARCHAR(255) NOT NULL UNIQUE,
`role` VARCHAR(255) NOT NULL DEFAULT 'USER',
`email` VARCHAR(255) NOT NULL DEFAULT '',
`nickname` VARCHAR(255) NOT NULL DEFAULT '',
`password_hash` VARCHAR(255) NOT NULL,
`avatar_url` TEXT NOT NULL
);
-- user_setting
CREATE TABLE `user_setting` (
`user_id` int NOT NULL,
`key` varchar(255) NOT NULL,
`value` text NOT NULL,
UNIQUE KEY `user_id` (`user_id`,`key`)
`user_id` INT NOT NULL,
`key` VARCHAR(255) NOT NULL,
`value` TEXT NOT NULL,
UNIQUE(`user_id`,`key`)
);
-- memo
CREATE TABLE `memo` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_status` varchar(255) NOT NULL DEFAULT 'NORMAL',
`content` text NOT NULL,
`visibility` varchar(255) NOT NULL DEFAULT 'PRIVATE',
PRIMARY KEY (`id`),
KEY `creator_id` (`creator_id`),
KEY `visibility` (`visibility`),
CONSTRAINT `memo_chk_1` CHECK ((`row_status` in (_utf8mb4'NORMAL',_utf8mb4'ARCHIVED'))),
CONSTRAINT `memo_chk_2` CHECK ((`visibility` in (_utf8mb4'PUBLIC',_utf8mb4'PROTECTED',_utf8mb4'PRIVATE')))
`row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL',
`content` TEXT NOT NULL,
`visibility` VARCHAR(255) NOT NULL DEFAULT 'PRIVATE'
);
-- memo_organizer
CREATE TABLE `memo_organizer` (
`memo_id` int NOT NULL,
`user_id` int NOT NULL,
`pinned` int NOT NULL DEFAULT '0',
UNIQUE KEY `memo_id` (`memo_id`,`user_id`),
CONSTRAINT `memo_organizer_chk_1` CHECK ((`pinned` in (0,1)))
`memo_id` INT NOT NULL,
`user_id` INT NOT NULL,
`pinned` INT NOT NULL DEFAULT '0',
UNIQUE(`memo_id`,`user_id`)
);
-- memo_relation
CREATE TABLE `memo_relation` (
`memo_id` int NOT NULL,
`related_memo_id` int NOT NULL,
`type` varchar(256) NOT NULL,
UNIQUE KEY `memo_id` (`memo_id`,`related_memo_id`,`type`)
`memo_id` INT NOT NULL,
`related_memo_id` INT NOT NULL,
`type` VARCHAR(256) NOT NULL,
UNIQUE(`memo_id`,`related_memo_id`,`type`)
);
-- resource
CREATE TABLE `resource` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`filename` text NOT NULL,
`blob` blob,
`external_link` text NOT NULL,
`type` varchar(255) NOT NULL DEFAULT '',
`size` int NOT NULL DEFAULT '0',
`internal_path` varchar(255) NOT NULL DEFAULT '',
`memo_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `creator_id` (`creator_id`),
KEY `memo_id` (`memo_id`)
`filename` TEXT NOT NULL,
`blob` BLOB,
`external_link` TEXT NOT NULL,
`type` VARCHAR(255) NOT NULL DEFAULT '',
`size` INT NOT NULL DEFAULT '0',
`INTernal_path` VARCHAR(255) NOT NULL DEFAULT '',
`memo_id` INT DEFAULT NULL
);
-- tag
CREATE TABLE `tag` (
`name` varchar(255) NOT NULL,
`creator_id` int NOT NULL,
UNIQUE KEY `name` (`name`,`creator_id`)
`name` VARCHAR(255) NOT NULL,
`creator_id` INT NOT NULL,
UNIQUE(`name`,`creator_id`)
);
-- activity
CREATE TABLE `activity` (
`id` int NOT NULL AUTO_INCREMENT,
`creator_id` int NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`creator_id` INT NOT NULL,
`created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`type` varchar(255) NOT NULL DEFAULT '',
`level` varchar(255) NOT NULL DEFAULT 'INFO',
`payload` text NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `activity_chk_1` CHECK ((`level` in (_utf8mb4'INFO',_utf8mb4'WARN',_utf8mb4'ERROR')))
`type` VARCHAR(255) NOT NULL DEFAULT '',
`level` VARCHAR(255) NOT NULL DEFAULT 'INFO',
`payload` TEXT NOT NULL
);
-- storage
CREATE TABLE `storage` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`type` varchar(256) NOT NULL,
`config` text NOT NULL,
PRIMARY KEY (`id`)
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(256) NOT NULL,
`type` VARCHAR(256) NOT NULL,
`config` TEXT NOT NULL
);
-- idp
CREATE TABLE `idp` (
`id` int NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`type` text NOT NULL,
`identifier_filter` varchar(256) NOT NULL DEFAULT '',
`config` text NOT NULL,
PRIMARY KEY (`id`)
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` TEXT NOT NULL,
`type` TEXT NOT NULL,
`identifier_filter` VARCHAR(256) NOT NULL DEFAULT '',
`config` TEXT NOT NULL
);

View File

@ -35,15 +35,9 @@ func (d *Driver) nonProdMigrate(ctx context.Context) error {
return errors.Errorf("failed to read latest schema file: %s", err)
}
for _, stmt := range strings.Split(string(buf), ";") {
stmt = strings.TrimSpace(stmt)
if stmt == "" {
continue
}
_, err := d.db.ExecContext(ctx, stmt)
if err != nil {
return errors.Errorf("failed to exec SQL %s: %s", stmt, err)
}
stmt := string(buf)
if _, err := d.db.ExecContext(ctx, stmt); err != nil {
return errors.Errorf("failed to exec SQL %s: %s", stmt, err)
}
// In demo mode, we should seed the database.
@ -54,17 +48,27 @@ func (d *Driver) nonProdMigrate(ctx context.Context) error {
}
return nil
}
func (d *Driver) prodMigrate(ctx context.Context) error {
currentVersion := version.GetCurrentVersion(d.profile.Mode)
migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
if err != nil {
return errors.Wrap(err, "failed to find migration history")
}
// If there is no migration history, we should apply the latest schema.
if len(migrationHistoryList) == 0 {
_, err := d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
Version: currentVersion,
})
buf, err := migrationFS.ReadFile("migration/prod/" + latestSchemaFileName)
if err != nil {
return errors.Errorf("failed to read latest schema file: %s", err)
}
stmt := string(buf)
if _, err := d.db.ExecContext(ctx, stmt); err != nil {
return errors.Errorf("failed to exec SQL %s: %s", stmt, err)
}
if _, err := d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
Version: currentVersion,
}); err != nil {
return errors.Wrap(err, "failed to upsert migration history")
}
return nil
@ -76,7 +80,6 @@ func (d *Driver) prodMigrate(ctx context.Context) error {
}
sort.Sort(version.SortVersion(migrationHistoryVersionList))
latestMigrationHistoryVersion := migrationHistoryVersionList[len(migrationHistoryVersionList)-1]
if !version.IsVersionGreaterThan(version.GetSchemaVersion(currentVersion), latestMigrationHistoryVersion) {
return nil
}
@ -96,7 +99,7 @@ func (d *Driver) prodMigrate(ctx context.Context) error {
}
func (d *Driver) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("migration/prod/%s/*.sql", minorVersion))
if err != nil {
return errors.Wrap(err, "failed to read ddl files")
}
@ -131,13 +134,12 @@ func (d *Driver) applyMigrationForMinorVersion(ctx context.Context, minorVersion
var seedFS embed.FS
func (d *Driver) seed(ctx context.Context) error {
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
filenames, err := fs.Glob(seedFS, "seed/*.sql")
if err != nil {
return errors.Wrap(err, "failed to read seed files")
}
sort.Strings(filenames)
// Loop over all seed files and execute them in order.
for _, filename := range filenames {
buf, err := seedFS.ReadFile(filename)

View File

@ -3,6 +3,7 @@ package mysql
import (
"context"
"database/sql"
"fmt"
"github.com/pkg/errors"
@ -16,7 +17,10 @@ type Driver struct {
}
func NewDriver(profile *profile.Profile) (store.Driver, error) {
db, err := sql.Open("mysql", profile.DSN)
// Open MySQL connection with parameter.
// multiStatements=true is required for migration.
// See more in: https://github.com/go-sql-driver/mysql#multistatements
db, err := sql.Open("mysql", fmt.Sprintf("%s?multiStatements=true", profile.DSN))
if err != nil {
return nil, errors.Wrapf(err, "failed to open db: %s", profile.DSN)
}

View File

@ -117,7 +117,7 @@ func (d *Driver) applyLatestSchema(ctx context.Context) error {
if d.profile.Mode == "prod" {
schemaMode = "prod"
}
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
latestSchemaPath := fmt.Sprintf("migration/%s/%s", schemaMode, latestSchemaFileName)
buf, err := migrationFS.ReadFile(latestSchemaPath)
if err != nil {
return errors.Wrapf(err, "failed to read latest schema %q", latestSchemaPath)