mirror of
https://github.com/certd/certd.git
synced 2026-06-23 18:57:31 +08:00
build: 数据库迁移脚本同步
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
ALTER TABLE cd_access ADD COLUMN subtype varchar(100);
|
||||
CREATE INDEX `index_access_subtype` ON `cd_access` (`subtype`);
|
||||
|
||||
CREATE TABLE `cd_dns_persist_record`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint NOT NULL,
|
||||
`project_id` bigint,
|
||||
`domain` varchar(255) NOT NULL,
|
||||
`main_domain` varchar(255) NOT NULL,
|
||||
`ca_type` varchar(50) NOT NULL,
|
||||
`acme_account_access_id` bigint NOT NULL,
|
||||
`account_uri` varchar(512) NOT NULL,
|
||||
`host_record` varchar(255) NOT NULL,
|
||||
`record_value` longtext NOT NULL,
|
||||
`policy` varchar(50),
|
||||
`persist_until` bigint,
|
||||
`status` varchar(50) NOT NULL DEFAULT 'pending',
|
||||
`dns_provider_type` varchar(50),
|
||||
`dns_provider_access` bigint,
|
||||
`record_res` longtext,
|
||||
`disabled` bigint NOT NULL DEFAULT 0,
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE = InnoDB ROW_FORMAT = DYNAMIC;
|
||||
|
||||
CREATE INDEX `index_dns_persist_user_id` ON `cd_dns_persist_record` (`user_id`);
|
||||
CREATE INDEX `index_dns_persist_project_id` ON `cd_dns_persist_record` (`project_id`);
|
||||
CREATE INDEX `index_dns_persist_domain` ON `cd_dns_persist_record` (`domain`(191));
|
||||
CREATE INDEX `index_dns_persist_main_domain` ON `cd_dns_persist_record` (`main_domain`(191));
|
||||
CREATE INDEX `index_dns_persist_account` ON `cd_dns_persist_record` (`acme_account_access_id`);
|
||||
@@ -0,0 +1,29 @@
|
||||
-- 激活码表
|
||||
CREATE TABLE `cd_product_activation_code`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`code` varchar(50) NOT NULL,
|
||||
`product_id` bigint NOT NULL,
|
||||
`duration` bigint NOT NULL,
|
||||
`batch_no` varchar(50) NOT NULL DEFAULT '',
|
||||
`status` varchar(20) NOT NULL DEFAULT 'unused',
|
||||
`used_user_id` bigint,
|
||||
`used_time` bigint,
|
||||
`expire_time` bigint,
|
||||
`disabled_time` bigint,
|
||||
`exported` bigint NOT NULL DEFAULT 0,
|
||||
`export_time` bigint,
|
||||
`remark` varchar(500) NOT NULL DEFAULT '',
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE = InnoDB ROW_FORMAT = DYNAMIC;
|
||||
|
||||
CREATE UNIQUE INDEX `index_activation_code_code` ON `cd_product_activation_code` (`code`);
|
||||
CREATE INDEX `index_activation_code_batch_no` ON `cd_product_activation_code` (`batch_no`);
|
||||
CREATE INDEX `index_activation_code_status` ON `cd_product_activation_code` (`status`);
|
||||
CREATE INDEX `index_activation_code_expire_time` ON `cd_product_activation_code` (`expire_time`);
|
||||
CREATE INDEX `index_activation_code_exported` ON `cd_product_activation_code` (`exported`);
|
||||
|
||||
-- cd_user_suite 增加激活码来源追溯
|
||||
ALTER TABLE `cd_user_suite`
|
||||
ADD COLUMN `activation_code_id` bigint;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE `cd_cert_apply_template`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint NOT NULL,
|
||||
`project_id` bigint NULL,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`content` longtext NOT NULL,
|
||||
`is_default` boolean NOT NULL DEFAULT false,
|
||||
`disabled` boolean NOT NULL DEFAULT false,
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE = InnoDB ROW_FORMAT = DYNAMIC;
|
||||
|
||||
CREATE INDEX `index_cert_apply_template_user_id` ON `cd_cert_apply_template` (`user_id`);
|
||||
CREATE INDEX `index_cert_apply_template_project_id` ON `cd_cert_apply_template` (`project_id`);
|
||||
CREATE INDEX `index_cert_apply_template_default` ON `cd_cert_apply_template` (`user_id`, `project_id`, `is_default`);
|
||||
@@ -0,0 +1,31 @@
|
||||
ALTER TABLE cd_access ADD COLUMN subtype varchar(100);
|
||||
CREATE INDEX "index_access_subtype" ON "cd_access" ("subtype");
|
||||
|
||||
CREATE TABLE "cd_dns_persist_record"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint NOT NULL,
|
||||
"project_id" bigint,
|
||||
"domain" varchar(255) NOT NULL,
|
||||
"main_domain" varchar(255) NOT NULL,
|
||||
"ca_type" varchar(50) NOT NULL,
|
||||
"acme_account_access_id" bigint NOT NULL,
|
||||
"account_uri" varchar(512) NOT NULL,
|
||||
"host_record" varchar(255) NOT NULL,
|
||||
"record_value" text NOT NULL,
|
||||
"policy" varchar(50),
|
||||
"persist_until" bigint,
|
||||
"status" varchar(50) NOT NULL DEFAULT 'pending',
|
||||
"dns_provider_type" varchar(50),
|
||||
"dns_provider_access" bigint,
|
||||
"record_res" text,
|
||||
"disabled" bigint NOT NULL DEFAULT 0,
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
CREATE INDEX "index_dns_persist_user_id" ON "cd_dns_persist_record" ("user_id");
|
||||
CREATE INDEX "index_dns_persist_project_id" ON "cd_dns_persist_record" ("project_id");
|
||||
CREATE INDEX "index_dns_persist_domain" ON "cd_dns_persist_record" ("domain");
|
||||
CREATE INDEX "index_dns_persist_main_domain" ON "cd_dns_persist_record" ("main_domain");
|
||||
CREATE INDEX "index_dns_persist_account" ON "cd_dns_persist_record" ("acme_account_access_id");
|
||||
@@ -0,0 +1,29 @@
|
||||
-- 激活码表
|
||||
CREATE TABLE "cd_product_activation_code"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"code" varchar(50) NOT NULL,
|
||||
"product_id" bigint NOT NULL,
|
||||
"duration" bigint NOT NULL,
|
||||
"batch_no" varchar(50) NOT NULL DEFAULT '',
|
||||
"status" varchar(20) NOT NULL DEFAULT 'unused',
|
||||
"used_user_id" bigint,
|
||||
"used_time" bigint,
|
||||
"expire_time" bigint,
|
||||
"disabled_time" bigint,
|
||||
"exported" bigint NOT NULL DEFAULT 0,
|
||||
"export_time" bigint,
|
||||
"remark" varchar(500) NOT NULL DEFAULT '',
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "index_activation_code_code" ON "cd_product_activation_code" ("code");
|
||||
CREATE INDEX "index_activation_code_batch_no" ON "cd_product_activation_code" ("batch_no");
|
||||
CREATE INDEX "index_activation_code_status" ON "cd_product_activation_code" ("status");
|
||||
CREATE INDEX "index_activation_code_expire_time" ON "cd_product_activation_code" ("expire_time");
|
||||
CREATE INDEX "index_activation_code_exported" ON "cd_product_activation_code" ("exported");
|
||||
|
||||
-- cd_user_suite 增加激活码来源追溯
|
||||
ALTER TABLE "cd_user_suite"
|
||||
ADD COLUMN "activation_code_id" bigint;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE "cd_cert_apply_template"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint NOT NULL,
|
||||
"project_id" bigint NULL,
|
||||
"name" varchar(100) NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"is_default" boolean NOT NULL DEFAULT (false),
|
||||
"disabled" boolean NOT NULL DEFAULT (false),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
CREATE INDEX "index_cert_apply_template_user_id" ON "cd_cert_apply_template" ("user_id");
|
||||
CREATE INDEX "index_cert_apply_template_project_id" ON "cd_cert_apply_template" ("project_id");
|
||||
CREATE INDEX "index_cert_apply_template_default" ON "cd_cert_apply_template" ("user_id", "project_id", "is_default");
|
||||
@@ -1,4 +1,7 @@
|
||||
import fs from "fs";
|
||||
|
||||
const MYSQL_INDEX_PREFIX_LENGTH = 191;
|
||||
const MYSQL_TABLE_OPTIONS = "ENGINE = InnoDB ROW_FORMAT = DYNAMIC";
|
||||
/**
|
||||
* ## sqlite与postgres不同点
|
||||
* 1.
|
||||
@@ -55,6 +58,88 @@ function transformPG() {
|
||||
}
|
||||
}
|
||||
|
||||
function buildMysqlTableColumnMap(sql) {
|
||||
const tableColumnMap = new Map();
|
||||
const createTableReg = /CREATE TABLE `([^`]*)`[\s\S]*?;/gi;
|
||||
for (const match of sql.matchAll(createTableReg)) {
|
||||
const [statement, tableName] = match;
|
||||
const tableBody = getCreateTableBody(statement);
|
||||
const columnMap = new Map();
|
||||
const columnReg = /`([^`]*)`\s+varchar\((\d+)\)/gi;
|
||||
for (const columnMatch of tableBody.matchAll(columnReg)) {
|
||||
const [, columnName, length] = columnMatch;
|
||||
columnMap.set(columnName, Number(length));
|
||||
}
|
||||
tableColumnMap.set(tableName, columnMap);
|
||||
}
|
||||
|
||||
const alterAddColumnReg = /ALTER TABLE\s+`?([^`\s]+)`?\s+ADD COLUMN\s+`?([^`\s]+)`?\s+varchar\((\d+)\)/gi;
|
||||
for (const match of sql.matchAll(alterAddColumnReg)) {
|
||||
const [, tableName, columnName, length] = match;
|
||||
const columnMap = tableColumnMap.get(tableName) || new Map();
|
||||
columnMap.set(columnName, Number(length));
|
||||
tableColumnMap.set(tableName, columnMap);
|
||||
}
|
||||
|
||||
return tableColumnMap;
|
||||
}
|
||||
|
||||
function getCreateTableBody(statement) {
|
||||
const start = statement.indexOf("(");
|
||||
const end = statement.lastIndexOf(")");
|
||||
if (start === -1 || end === -1 || end <= start) {
|
||||
return "";
|
||||
}
|
||||
return statement.substring(start + 1, end);
|
||||
}
|
||||
|
||||
function appendMysqlTableOptions(sql) {
|
||||
const createTableReg = /CREATE TABLE `([^`]*)`[\s\S]*?;/gi;
|
||||
return sql.replace(createTableReg, statement => {
|
||||
const sqlWithoutSemicolon = statement.replace(/;\s*$/, "");
|
||||
const sqlWithoutOptions = sqlWithoutSemicolon.replace(/\s+ENGINE\s*=\s*\w+(?:\s+ROW_FORMAT\s*=\s*\w+)?\s*$/i, "");
|
||||
return `${sqlWithoutOptions} ${MYSQL_TABLE_OPTIONS};`;
|
||||
});
|
||||
}
|
||||
|
||||
function addMysqlIndexPrefix(sql) {
|
||||
const tableColumnMap = buildMysqlTableColumnMap(sql);
|
||||
const createIndexReg = /CREATE\s+(UNIQUE\s+)?INDEX\s+`([^`]*)`\s+ON\s+`([^`]*)`\s*\(([^;]*)\);/gi;
|
||||
return sql.replace(createIndexReg, (statement, uniqueKeyword, indexName, tableName, columns) => {
|
||||
const columnMap = tableColumnMap.get(tableName);
|
||||
if (!columnMap) {
|
||||
return statement;
|
||||
}
|
||||
|
||||
const parsedColumns = columns.split(",").map(item => {
|
||||
const columnMatch = item.trim().match(/^`([^`]*)`(?:\((\d+)\))?$/);
|
||||
if (!columnMatch) {
|
||||
return item.trim();
|
||||
}
|
||||
|
||||
const [, columnName, prefixLength] = columnMatch;
|
||||
const columnLength = columnMap.get(columnName);
|
||||
if (!columnLength || columnLength <= MYSQL_INDEX_PREFIX_LENGTH) {
|
||||
return item.trim();
|
||||
}
|
||||
|
||||
if (prefixLength && Number(prefixLength) <= MYSQL_INDEX_PREFIX_LENGTH) {
|
||||
return item.trim();
|
||||
}
|
||||
|
||||
// MySQL 5.7 老配置下 utf8mb4 varchar(255) 完整索引可能超过 767/1000 字节限制。
|
||||
if (uniqueKeyword) {
|
||||
throw new Error(`唯一索引 ${indexName} 的字段 ${tableName}.${columnName} 长度超过 ${MYSQL_INDEX_PREFIX_LENGTH},不能自动改成前缀索引,请缩短字段长度或增加 hash 字段`);
|
||||
}
|
||||
|
||||
return `\`${columnName}\`(${MYSQL_INDEX_PREFIX_LENGTH})`;
|
||||
});
|
||||
|
||||
const unique = uniqueKeyword || "";
|
||||
return `CREATE ${unique}INDEX \`${indexName}\` ON \`${tableName}\` (${parsedColumns.join(", ")});`;
|
||||
});
|
||||
}
|
||||
|
||||
function transformMysql() {
|
||||
// 读取文件列表
|
||||
const sqliteFiles = fs.readdirSync("./migration/");
|
||||
@@ -76,20 +161,8 @@ function transformMysql() {
|
||||
//双引号 替换成反引号
|
||||
pgSql = pgSql.replaceAll(/"/g, "`");
|
||||
|
||||
//提取所有的 create table 的表格name
|
||||
const tableNames = pgSql.match(/CREATE TABLE `([^`]*)`/g);
|
||||
if (tableNames && tableNames.length > 0) {
|
||||
for (const item of tableNames) {
|
||||
/**
|
||||
* CREATE TABLE `cd_project`
|
||||
CREATE TABLE `cd_project_member`
|
||||
CREATE TABLE `cd_audit_log`
|
||||
*/
|
||||
//提取表名
|
||||
const tableName = item.match(/`([^`]*)`/)[1];
|
||||
pgSql += `\nALTER TABLE \`${tableName}\` ENGINE = InnoDB;`;
|
||||
}
|
||||
}
|
||||
pgSql = appendMysqlTableOptions(pgSql);
|
||||
pgSql = addMysqlIndexPrefix(pgSql);
|
||||
|
||||
fs.writeFileSync(`./migration-mysql/${notFile}`, pgSql);
|
||||
}
|
||||
|
||||
@@ -134,5 +134,7 @@ export class MainConfiguration {
|
||||
});
|
||||
|
||||
logger.info("当前环境:", this.app.getEnv()); // prod
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user