注册表新增数据库存储同步
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
const { defaultLogger } = require('../utils/logger');
|
||||
|
||||
const logger = defaultLogger.child('RegistrySchema');
|
||||
|
||||
/**
|
||||
* 注册表数据库表结构管理
|
||||
*/
|
||||
class RegistrySchema {
|
||||
constructor(databaseManager) {
|
||||
this.db = databaseManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化所有注册表相关的数据库表
|
||||
*/
|
||||
async initializeTables() {
|
||||
try {
|
||||
await this.createArtistsTable();
|
||||
await this.createArtworksTable();
|
||||
await this.createRegistryMetaTable();
|
||||
logger.info('注册表数据库表初始化完成');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
logger.error('初始化注册表数据库表失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建艺术家表
|
||||
*/
|
||||
async createArtistsTable() {
|
||||
const tableName = 'registry_artists';
|
||||
|
||||
if (await this.db.tableExists(tableName)) {
|
||||
logger.debug(`表 ${tableName} 已存在,跳过创建`);
|
||||
return;
|
||||
}
|
||||
|
||||
const createSQL = `
|
||||
CREATE TABLE ${tableName} (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
artist_name VARCHAR(255) NOT NULL UNIQUE COMMENT '艺术家名称',
|
||||
normalized_name VARCHAR(255) NOT NULL COMMENT '标准化后的艺术家名称',
|
||||
artwork_count INT DEFAULT 0 COMMENT '作品数量',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_artist_name (artist_name),
|
||||
INDEX idx_normalized_name (normalized_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表艺术家表';
|
||||
`;
|
||||
|
||||
await this.db.createTable(tableName, createSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建作品表
|
||||
*/
|
||||
async createArtworksTable() {
|
||||
const tableName = 'registry_artworks';
|
||||
|
||||
if (await this.db.tableExists(tableName)) {
|
||||
logger.debug(`表 ${tableName} 已存在,跳过创建`);
|
||||
return;
|
||||
}
|
||||
|
||||
const createSQL = `
|
||||
CREATE TABLE ${tableName} (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
artist_id INT NOT NULL COMMENT '艺术家ID',
|
||||
artwork_id BIGINT NOT NULL COMMENT '作品ID',
|
||||
artist_name VARCHAR(255) NOT NULL COMMENT '艺术家名称(冗余字段,便于查询)',
|
||||
file_path TEXT COMMENT '文件路径(可选)',
|
||||
download_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '下载时间',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
UNIQUE KEY uk_artist_artwork (artist_id, artwork_id),
|
||||
INDEX idx_artwork_id (artwork_id),
|
||||
INDEX idx_artist_id (artist_id),
|
||||
INDEX idx_artist_name (artist_name),
|
||||
INDEX idx_download_date (download_date),
|
||||
FOREIGN KEY (artist_id) REFERENCES registry_artists(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表作品表';
|
||||
`;
|
||||
|
||||
await this.db.createTable(tableName, createSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建注册表元数据表
|
||||
*/
|
||||
async createRegistryMetaTable() {
|
||||
const tableName = 'registry_meta';
|
||||
|
||||
if (await this.db.tableExists(tableName)) {
|
||||
logger.debug(`表 ${tableName} 已存在,跳过创建`);
|
||||
return;
|
||||
}
|
||||
|
||||
const createSQL = `
|
||||
CREATE TABLE ${tableName} (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
meta_key VARCHAR(100) NOT NULL UNIQUE COMMENT '元数据键',
|
||||
meta_value TEXT COMMENT '元数据值',
|
||||
description TEXT COMMENT '描述',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_meta_key (meta_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表元数据表';
|
||||
`;
|
||||
|
||||
await this.db.createTable(tableName, createSQL);
|
||||
|
||||
// 插入初始元数据
|
||||
await this.initializeMetaData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化元数据
|
||||
*/
|
||||
async initializeMetaData() {
|
||||
const metaData = [
|
||||
{
|
||||
meta_key: 'version',
|
||||
meta_value: '1.0.5',
|
||||
description: '注册表版本号'
|
||||
},
|
||||
{
|
||||
meta_key: 'storage_type',
|
||||
meta_value: 'database',
|
||||
description: '存储类型:database 或 json'
|
||||
},
|
||||
{
|
||||
meta_key: 'created_at',
|
||||
meta_value: new Date().toISOString(),
|
||||
description: '注册表创建时间'
|
||||
},
|
||||
{
|
||||
meta_key: 'last_migration',
|
||||
meta_value: new Date().toISOString(),
|
||||
description: '最后一次迁移时间'
|
||||
}
|
||||
];
|
||||
|
||||
for (const meta of metaData) {
|
||||
try {
|
||||
await this.db.insert('registry_meta', meta);
|
||||
} catch (error) {
|
||||
// 如果键已存在,忽略错误
|
||||
if (!error.message.includes('Duplicate entry')) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表结构信息
|
||||
*/
|
||||
getTableInfo() {
|
||||
return {
|
||||
artists: {
|
||||
tableName: 'registry_artists',
|
||||
description: '存储艺术家信息',
|
||||
fields: {
|
||||
id: '主键ID',
|
||||
artist_name: '艺术家名称',
|
||||
normalized_name: '标准化后的艺术家名称',
|
||||
artwork_count: '作品数量',
|
||||
created_at: '创建时间',
|
||||
updated_at: '更新时间'
|
||||
}
|
||||
},
|
||||
artworks: {
|
||||
tableName: 'registry_artworks',
|
||||
description: '存储作品信息',
|
||||
fields: {
|
||||
id: '主键ID',
|
||||
artist_id: '艺术家ID(外键)',
|
||||
artwork_id: '作品ID',
|
||||
artist_name: '艺术家名称(冗余字段)',
|
||||
file_path: '文件路径',
|
||||
download_date: '下载时间',
|
||||
created_at: '创建时间',
|
||||
updated_at: '更新时间'
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
tableName: 'registry_meta',
|
||||
description: '存储注册表元数据',
|
||||
fields: {
|
||||
id: '主键ID',
|
||||
meta_key: '元数据键',
|
||||
meta_value: '元数据值',
|
||||
description: '描述',
|
||||
created_at: '创建时间',
|
||||
updated_at: '更新时间'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查所有表是否存在
|
||||
*/
|
||||
async checkTablesExist() {
|
||||
const tables = ['registry_artists', 'registry_artworks', 'registry_meta'];
|
||||
const results = {};
|
||||
|
||||
for (const table of tables) {
|
||||
results[table] = await this.db.tableExists(table);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除所有注册表相关的表(谨慎使用)
|
||||
*/
|
||||
async dropAllTables() {
|
||||
const tables = ['registry_artworks', 'registry_artists', 'registry_meta'];
|
||||
|
||||
try {
|
||||
// 按照外键依赖顺序删除表
|
||||
for (const table of tables) {
|
||||
if (await this.db.tableExists(table)) {
|
||||
await this.db.query(`DROP TABLE ${table}`);
|
||||
logger.info(`表 ${table} 已删除`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('所有注册表相关的表已删除');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
logger.error('删除注册表表失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RegistrySchema;
|
||||
Reference in New Issue
Block a user