|
|
@@ -199,9 +199,239 @@ function customPlugin(): HvigorPlugin {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function rDBPlugin(): HvigorPlugin {
|
|
|
+ return {
|
|
|
+ pluginId: 'customPlugin',
|
|
|
+ apply(node: HvigorNode) {
|
|
|
+ try {
|
|
|
+ // 根据node对象结构获取项目路径
|
|
|
+ const projectPath = node.nodeDir.filePath;
|
|
|
+ console.log('目标路径:', projectPath);
|
|
|
+
|
|
|
+ // 获取所有子模块
|
|
|
+ const modules = node.allSubNodes.filter(subNode => subNode.node.classKind === 'module');
|
|
|
+ console.log('模块数量:', modules.length);
|
|
|
+
|
|
|
+ // 打印每个模块的路径
|
|
|
+ const modulePaths = [];
|
|
|
+ modules.forEach((module, index) => {
|
|
|
+ try {
|
|
|
+ // 从module.node._nodePath获取模块路径
|
|
|
+ const modulePath = module.node._nodePath;
|
|
|
+ if (modulePath) {
|
|
|
+ console.log(`模块 ${index + 1} 路径:`, modulePath);
|
|
|
+ modulePaths.push(modulePath);
|
|
|
+ if (modulePath.includes('basic')) {
|
|
|
+ processTables(modulePath)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log(`模块 ${index + 1} 路径: 无法获取路径`);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`获取模块 ${index + 1} 路径时出错:`, error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 遍历并处理所有模块
|
|
|
+ // modulePaths.forEach((modulePath, index) => {
|
|
|
+ // console.log(`处理模块 ${index + 1}:`, modulePath);
|
|
|
+ // processTables(); // 处理tables目录的逻辑
|
|
|
+ // });
|
|
|
+ // processTables(modulePaths[])
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error in custom plugin:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function processTables(currentDir:string) {
|
|
|
+ try {
|
|
|
+ // 构建tables目录路径
|
|
|
+ const tablesPath = path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'tables');
|
|
|
+ console.log('tables路径:', tablesPath);
|
|
|
+
|
|
|
+ // 检查tables目录是否存在
|
|
|
+ if (fs.existsSync(tablesPath)) {
|
|
|
+ // 读取目录内容
|
|
|
+ const files = fs.readdirSync(tablesPath);
|
|
|
+ console.log(`Found ${files.length} files/directories in tables folder:`);
|
|
|
+
|
|
|
+ const tableNames: string[] = [];
|
|
|
+ const sqlStatements: string[] = [];
|
|
|
+
|
|
|
+ // 替换原有的字段处理逻辑
|
|
|
+ files.forEach((file, index) => {
|
|
|
+ const fullPath = path.join(tablesPath, file);
|
|
|
+ const stat = fs.statSync(fullPath);
|
|
|
+ const type = stat.isDirectory() ? '[DIR]' : '[FILE]';
|
|
|
+ console.log(`${index + 1}. ${type} ${file}`);
|
|
|
+
|
|
|
+ // 如果是文件,读取文件内容
|
|
|
+ if (!stat.isDirectory() && file.endsWith('.ets')) {
|
|
|
+ try {
|
|
|
+ const content = fs.readFileSync(fullPath, 'utf8');
|
|
|
+
|
|
|
+ // 使用正则表达式匹配interface名称
|
|
|
+ const interfaceRegex = /export\s+interface\s+(\w+)/g;
|
|
|
+ let match;
|
|
|
+
|
|
|
+ while ((match = interfaceRegex.exec(content)) !== null) {
|
|
|
+ const interfaceName = match[1];
|
|
|
+ tableNames.push(interfaceName);
|
|
|
+
|
|
|
+ // 解析接口属性并生成字段
|
|
|
+ const fieldDefinitions = parseInterfaceFields(content, interfaceName);
|
|
|
+
|
|
|
+ // 生成CREATE TABLE SQL语句(包含字段)
|
|
|
+ const sqlStatement =
|
|
|
+ `static readonly CREATE_${interfaceName.toUpperCase()}_TABLE = 'CREATE TABLE IF NOT EXISTS ${interfaceName} (${fieldDefinitions})';`;
|
|
|
+ sqlStatements.push(sqlStatement);
|
|
|
+
|
|
|
+ console.log(`Found interface: ${interfaceName}`);
|
|
|
+ }
|
|
|
+ } catch (readError) {
|
|
|
+ console.error(`Error reading file ${file}:`, readError);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 添加解析接口字段的辅助函数
|
|
|
+ function parseInterfaceFields(content: string, interfaceName: string): string {
|
|
|
+ // 查找接口定义区域
|
|
|
+ const interfaceStart = content.indexOf(`export interface ${interfaceName}`);
|
|
|
+ if (interfaceStart === -1) {
|
|
|
+ return 'ID INTEGER PRIMARY KEY AUTOINCREMENT';
|
|
|
+ }
|
|
|
+
|
|
|
+ const openBrace = content.indexOf('{', interfaceStart);
|
|
|
+ const closeBrace = content.indexOf('}', openBrace);
|
|
|
+
|
|
|
+ if (openBrace === -1 || closeBrace === -1) {
|
|
|
+ return 'ID INTEGER PRIMARY KEY AUTOINCREMENT';
|
|
|
+ }
|
|
|
+
|
|
|
+ const interfaceBody = content.substring(openBrace + 1, closeBrace);
|
|
|
+ const lines = interfaceBody.split('\n');
|
|
|
+
|
|
|
+ const fields: string[] = [];
|
|
|
+ let hasPrimaryKey = false;
|
|
|
+
|
|
|
+ lines.forEach(line => {
|
|
|
+ const fieldMatch = line.trim().match(/^(\w+)\??\s*:\s*(.+?);?$/);
|
|
|
+ if (fieldMatch) {
|
|
|
+ const fieldName = fieldMatch[1];
|
|
|
+ const fieldType = fieldMatch[2].trim();
|
|
|
+
|
|
|
+ // 根据TypeScript类型映射到SQLite类型
|
|
|
+ let sqliteType = 'TEXT';
|
|
|
+ if (fieldType.includes('number') || fieldType.includes('Number')) {
|
|
|
+ sqliteType = 'INTEGER';
|
|
|
+ } else if (fieldType.includes('boolean') || fieldType.includes('Boolean')) {
|
|
|
+ sqliteType = 'INTEGER';
|
|
|
+ } else if (fieldType.includes('Date')) {
|
|
|
+ sqliteType = 'TEXT';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否为主键字段(约定以id命名的字段作为主键)
|
|
|
+ if (fieldName.toLowerCase() === 'id') {
|
|
|
+ fields.push(`${fieldName} INTEGER PRIMARY KEY AUTOINCREMENT`);
|
|
|
+ hasPrimaryKey = true;
|
|
|
+ } else {
|
|
|
+ // 处理可选字段
|
|
|
+ const nullable = line.trim().includes('?') ? '' : ' NOT NULL';
|
|
|
+ fields.push(`${fieldName} ${sqliteType}${nullable}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 如果没有定义主键,则添加默认主键
|
|
|
+ if (!hasPrimaryKey) {
|
|
|
+ fields.unshift('ID INTEGER PRIMARY KEY AUTOINCREMENT');
|
|
|
+ }
|
|
|
+
|
|
|
+ return fields.join(', ');
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 更新RelationalStoreUtils.ets文件中的tables数组
|
|
|
+ const relationalStorePath =
|
|
|
+ path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'utils', 'RelationalStoreUtis.ets');
|
|
|
+ if (fs.existsSync(relationalStorePath)) {
|
|
|
+ let content = fs.readFileSync(relationalStorePath, 'utf8');
|
|
|
+
|
|
|
+ // 更新tables数组
|
|
|
+ if (tableNames.length > 0) {
|
|
|
+ const tablesArray = `private static tables: string[] = [${tableNames.map(name => `'${name}'`).join(', ')}]`;
|
|
|
+ const updatedContent = content.replace(/private static tables: string\[\] = \[[^\]]*\]/, tablesArray);
|
|
|
+
|
|
|
+ fs.writeFileSync(relationalStorePath, updatedContent, 'utf8');
|
|
|
+ console.log('RelationalStoreUtis.ets文件已更新');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 替换原有的更新RDBSql.ets文件的代码块
|
|
|
+
|
|
|
+ // 更新RDBSql.ts文件
|
|
|
+ const rdbSqlPath = path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'sqls', 'RDBSql.ts');
|
|
|
+ if (fs.existsSync(rdbSqlPath)) {
|
|
|
+ let content = fs.readFileSync(rdbSqlPath, 'utf8');
|
|
|
+
|
|
|
+ // 构建SQL语句对象属性
|
|
|
+ if (sqlStatements.length > 0) {
|
|
|
+ // 提取属性名和值
|
|
|
+ const sqlProperties: string[] = [];
|
|
|
+ sqlStatements.forEach(statement => {
|
|
|
+ // 从 static readonly CREATE_USER_TABLE = 'CREATE TABLE...' 提取属性
|
|
|
+ const propertyName = statement.split('=')[0].trim().replace('static readonly ', '');
|
|
|
+ const propertyValue = statement.split('=')[1].trim().slice(1, -2); // 去掉引号和分号
|
|
|
+ sqlProperties.push(` ${propertyName}: '${propertyValue}'`);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 构建新的对象内容
|
|
|
+ const newContent = `export const rDbSql = {\n${sqlProperties.join(',\n')}\n}`;
|
|
|
+
|
|
|
+ fs.writeFileSync(rdbSqlPath, newContent, 'utf8');
|
|
|
+ console.log('RDBSql.ts文件已更新为对象形式');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果文件不存在,创建新文件
|
|
|
+ if (sqlStatements.length > 0) {
|
|
|
+ const sqlProperties: string[] = [];
|
|
|
+ sqlStatements.forEach(statement => {
|
|
|
+ const propertyName = statement.split('=')[0].trim().replace('static readonly ', '');
|
|
|
+ const propertyValue = statement.split('=')[1].trim().slice(1, -2);
|
|
|
+ sqlProperties.push(` ${propertyName}: '${propertyValue}'`);
|
|
|
+ });
|
|
|
+
|
|
|
+ const newContent = `export const rDbSql = {\n${sqlProperties.join(',\n')}\n}`;
|
|
|
+
|
|
|
+ // 确保目录存在
|
|
|
+ const dirPath = path.dirname(rdbSqlPath);
|
|
|
+ if (!fs.existsSync(dirPath)) {
|
|
|
+ fs.mkdirSync(dirPath, { recursive: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ fs.writeFileSync(rdbSqlPath, newContent, 'utf8');
|
|
|
+ console.log('RDBSql.ts文件已创建并初始化为对象形式');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ console.log('----------------------------------------');
|
|
|
+ } else {
|
|
|
+ console.log('Tables directory not found');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`处理tables目录时出错:`, error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
export default {
|
|
|
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
|
|
plugins: [
|
|
|
- customPlugin() // 应用自定义Plugin
|
|
|
+ customPlugin(), // 应用自定义Plugin
|
|
|
+ rDBPlugin()
|
|
|
] /* Custom plugin to extend the functionality of Hvigor. */
|
|
|
}
|