gaojintao01 commited on
Commit
c8317fa
·
1 Parent(s): a16f718
server/prisma/convert-sqlite-to-postgres.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * 将 SQLite 迁移文件转换为 PostgreSQL 语法
6
+ */
7
+
8
+ // SQLite 到 PostgreSQL 的转换映射
9
+ const sqliteToPostgresConversions = [
10
+ // 主键和自动递增
11
+ {
12
+ pattern: /INTEGER\s+NOT\s+NULL\s+PRIMARY\s+KEY\s+AUTOINCREMENT/g,
13
+ replacement: 'SERIAL PRIMARY KEY'
14
+ },
15
+ {
16
+ pattern: /\s+AUTOINCREMENT/g,
17
+ replacement: ''
18
+ },
19
+ // 数据类型
20
+ {
21
+ pattern: /\bDATETIME\b/g,
22
+ replacement: 'TIMESTAMP'
23
+ },
24
+ // 布尔值默认值 - 修复正则表达式,更精确的匹配
25
+ {
26
+ pattern: /DEFAULT\s+(?:'?(false|true)'?)/gi,
27
+ replacement: "DEFAULT $1"
28
+ },
29
+ // 数字默认值
30
+ {
31
+ pattern: /DEFAULT\s+'?0'?/g,
32
+ replacement: "DEFAULT 0"
33
+ },
34
+ {
35
+ pattern: /DEFAULT\s+'?1'?/g,
36
+ replacement: "DEFAULT 1"
37
+ }
38
+ ];
39
+
40
+ /**
41
+ * 转换单个 SQL 文件
42
+ */
43
+ function convertSqlFile(filePath) {
44
+ try {
45
+ let sqlContent = fs.readFileSync(filePath, 'utf8');
46
+
47
+ console.log(`转换文件: ${path.basename(filePath)}`);
48
+
49
+ // 应用所有转换规则
50
+ sqliteToPostgresConversions.forEach(({ pattern, replacement }) => {
51
+ sqlContent = sqlContent.replace(pattern, replacement);
52
+ });
53
+
54
+ // 写回文件
55
+ fs.writeFileSync(filePath, sqlContent);
56
+
57
+ console.log(`✓ ${path.basename(filePath)} 转换完成`);
58
+ return true;
59
+ } catch (error) {
60
+ console.error(`✗ ${path.basename(filePath)} 转换失败:`, error.message);
61
+ return false;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 递归处理目录中的所有迁移文件
67
+ */
68
+ function convertMigrationsDirectory(migrationsDir) {
69
+ const items = fs.readdirSync(migrationsDir);
70
+
71
+ let successCount = 0;
72
+ let failCount = 0;
73
+
74
+ items.forEach(item => {
75
+ const itemPath = path.join(migrationsDir, item);
76
+ const stat = fs.statSync(itemPath);
77
+
78
+ if (stat.isDirectory() && item !== 'migration_lock.toml') {
79
+ // 递归处理子目录
80
+ const result = convertMigrationsDirectory(itemPath);
81
+ successCount += result.successCount;
82
+ failCount += result.failCount;
83
+ } else if (item === 'migration.sql') {
84
+ // 处理迁移文件
85
+ if (convertSqlFile(itemPath)) {
86
+ successCount++;
87
+ } else {
88
+ failCount++;
89
+ }
90
+ }
91
+ });
92
+
93
+ return { successCount, failCount };
94
+ }
95
+
96
+ /**
97
+ * 主函数
98
+ */
99
+ function main() {
100
+ const migrationsDir = path.join(__dirname, 'migrations');
101
+
102
+ console.log('开始转换 SQLite 迁移文件到 PostgreSQL 语法...\n');
103
+
104
+ const result = convertMigrationsDirectory(migrationsDir);
105
+
106
+ console.log(`\n转换完成!`);
107
+ console.log(`成功: ${result.successCount} 个文件`);
108
+ console.log(`失败: ${result.failCount} 个文件`);
109
+ }
110
+
111
+ // 运行转换
112
+ if (require.main === module) {
113
+ main();
114
+ }
115
+
116
+ module.exports = { convertSqlFile, convertMigrationsDirectory };
server/prisma/migrations/20230921191814_init/migration.sql CHANGED
@@ -1,107 +1,107 @@
1
  -- CreateTable
2
  CREATE TABLE "api_keys" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "secret" TEXT,
5
  "createdBy" INTEGER,
6
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
8
  );
9
 
10
  -- CreateTable
11
  CREATE TABLE "workspace_documents" (
12
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
13
  "docId" TEXT NOT NULL,
14
  "filename" TEXT NOT NULL,
15
  "docpath" TEXT NOT NULL,
16
  "workspaceId" INTEGER NOT NULL,
17
  "metadata" TEXT,
18
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
19
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
  CONSTRAINT "workspace_documents_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
21
  );
22
 
23
  -- CreateTable
24
  CREATE TABLE "invites" (
25
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
26
  "code" TEXT NOT NULL,
27
  "status" TEXT NOT NULL DEFAULT 'pending',
28
  "claimedBy" INTEGER,
29
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
30
  "createdBy" INTEGER NOT NULL,
31
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
32
  );
33
 
34
  -- CreateTable
35
  CREATE TABLE "system_settings" (
36
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
37
  "label" TEXT NOT NULL,
38
  "value" TEXT,
39
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
40
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
41
  );
42
 
43
  -- CreateTable
44
  CREATE TABLE "users" (
45
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
46
  "username" TEXT,
47
  "password" TEXT NOT NULL,
48
  "role" TEXT NOT NULL DEFAULT 'default',
49
  "suspended" INTEGER NOT NULL DEFAULT 0,
50
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
51
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
52
  );
53
 
54
  -- CreateTable
55
  CREATE TABLE "document_vectors" (
56
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
57
  "docId" TEXT NOT NULL,
58
  "vectorId" TEXT NOT NULL,
59
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
60
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
61
  );
62
 
63
  -- CreateTable
64
  CREATE TABLE "welcome_messages" (
65
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
66
  "user" TEXT NOT NULL,
67
  "response" TEXT NOT NULL,
68
  "orderIndex" INTEGER,
69
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
70
  );
71
 
72
  -- CreateTable
73
  CREATE TABLE "workspaces" (
74
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
75
  "name" TEXT NOT NULL,
76
  "slug" TEXT NOT NULL,
77
  "vectorTag" TEXT,
78
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
79
  "openAiTemp" REAL,
80
  "openAiHistory" INTEGER NOT NULL DEFAULT 20,
81
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
82
  "openAiPrompt" TEXT
83
  );
84
 
85
  -- CreateTable
86
  CREATE TABLE "workspace_chats" (
87
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
88
  "workspaceId" INTEGER NOT NULL,
89
  "prompt" TEXT NOT NULL,
90
  "response" TEXT NOT NULL,
91
  "include" BOOLEAN NOT NULL DEFAULT true,
92
  "user_id" INTEGER,
93
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
94
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
95
  CONSTRAINT "workspace_chats_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
96
  );
97
 
98
  -- CreateTable
99
  CREATE TABLE "workspace_users" (
100
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
101
  "user_id" INTEGER NOT NULL,
102
  "workspace_id" INTEGER NOT NULL,
103
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
104
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
105
  CONSTRAINT "workspace_users_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
106
  CONSTRAINT "workspace_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
107
  );
 
1
  -- CreateTable
2
  CREATE TABLE "api_keys" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "secret" TEXT,
5
  "createdBy" INTEGER,
6
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
8
  );
9
 
10
  -- CreateTable
11
  CREATE TABLE "workspace_documents" (
12
+ "id" SERIAL PRIMARY KEY,
13
  "docId" TEXT NOT NULL,
14
  "filename" TEXT NOT NULL,
15
  "docpath" TEXT NOT NULL,
16
  "workspaceId" INTEGER NOT NULL,
17
  "metadata" TEXT,
18
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
19
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
  CONSTRAINT "workspace_documents_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
21
  );
22
 
23
  -- CreateTable
24
  CREATE TABLE "invites" (
25
+ "id" SERIAL PRIMARY KEY,
26
  "code" TEXT NOT NULL,
27
  "status" TEXT NOT NULL DEFAULT 'pending',
28
  "claimedBy" INTEGER,
29
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
30
  "createdBy" INTEGER NOT NULL,
31
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
32
  );
33
 
34
  -- CreateTable
35
  CREATE TABLE "system_settings" (
36
+ "id" SERIAL PRIMARY KEY,
37
  "label" TEXT NOT NULL,
38
  "value" TEXT,
39
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
40
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
41
  );
42
 
43
  -- CreateTable
44
  CREATE TABLE "users" (
45
+ "id" SERIAL PRIMARY KEY,
46
  "username" TEXT,
47
  "password" TEXT NOT NULL,
48
  "role" TEXT NOT NULL DEFAULT 'default',
49
  "suspended" INTEGER NOT NULL DEFAULT 0,
50
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
51
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
52
  );
53
 
54
  -- CreateTable
55
  CREATE TABLE "document_vectors" (
56
+ "id" SERIAL PRIMARY KEY,
57
  "docId" TEXT NOT NULL,
58
  "vectorId" TEXT NOT NULL,
59
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
60
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
61
  );
62
 
63
  -- CreateTable
64
  CREATE TABLE "welcome_messages" (
65
+ "id" SERIAL PRIMARY KEY,
66
  "user" TEXT NOT NULL,
67
  "response" TEXT NOT NULL,
68
  "orderIndex" INTEGER,
69
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
70
  );
71
 
72
  -- CreateTable
73
  CREATE TABLE "workspaces" (
74
+ "id" SERIAL PRIMARY KEY,
75
  "name" TEXT NOT NULL,
76
  "slug" TEXT NOT NULL,
77
  "vectorTag" TEXT,
78
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
79
  "openAiTemp" REAL,
80
  "openAiHistory" INTEGER NOT NULL DEFAULT 20,
81
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
82
  "openAiPrompt" TEXT
83
  );
84
 
85
  -- CreateTable
86
  CREATE TABLE "workspace_chats" (
87
+ "id" SERIAL PRIMARY KEY,
88
  "workspaceId" INTEGER NOT NULL,
89
  "prompt" TEXT NOT NULL,
90
  "response" TEXT NOT NULL,
91
  "include" BOOLEAN NOT NULL DEFAULT true,
92
  "user_id" INTEGER,
93
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
94
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
95
  CONSTRAINT "workspace_chats_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
96
  );
97
 
98
  -- CreateTable
99
  CREATE TABLE "workspace_users" (
100
+ "id" SERIAL PRIMARY KEY,
101
  "user_id" INTEGER NOT NULL,
102
  "workspace_id" INTEGER NOT NULL,
103
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
104
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
105
  CONSTRAINT "workspace_users_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
106
  CONSTRAINT "workspace_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
107
  );
server/prisma/migrations/20231101195421_init/migration.sql CHANGED
@@ -1,11 +1,11 @@
1
  -- CreateTable
2
  CREATE TABLE "cache_data" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "name" TEXT NOT NULL,
5
  "data" TEXT NOT NULL,
6
  "belongsTo" TEXT,
7
  "byId" INTEGER,
8
- "expiresAt" DATETIME,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
11
  );
 
1
  -- CreateTable
2
  CREATE TABLE "cache_data" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "name" TEXT NOT NULL,
5
  "data" TEXT NOT NULL,
6
  "belongsTo" TEXT,
7
  "byId" INTEGER,
8
+ "expiresAt" TIMESTAMP,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
11
  );
server/prisma/migrations/20240202002020_init/migration.sql CHANGED
@@ -1,6 +1,6 @@
1
  -- CreateTable
2
  CREATE TABLE "embed_configs" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "uuid" TEXT NOT NULL,
5
  "enabled" BOOLEAN NOT NULL DEFAULT false,
6
  "chat_mode" TEXT NOT NULL DEFAULT 'query',
@@ -13,14 +13,14 @@ CREATE TABLE "embed_configs" (
13
  "workspace_id" INTEGER NOT NULL,
14
  "createdBy" INTEGER,
15
  "usersId" INTEGER,
16
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
17
  CONSTRAINT "embed_configs_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
18
  CONSTRAINT "embed_configs_usersId_fkey" FOREIGN KEY ("usersId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
19
  );
20
 
21
  -- CreateTable
22
  CREATE TABLE "embed_chats" (
23
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
24
  "prompt" TEXT NOT NULL,
25
  "response" TEXT NOT NULL,
26
  "session_id" TEXT NOT NULL,
@@ -28,7 +28,7 @@ CREATE TABLE "embed_chats" (
28
  "connection_information" TEXT,
29
  "embed_id" INTEGER NOT NULL,
30
  "usersId" INTEGER,
31
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
32
  CONSTRAINT "embed_chats_embed_id_fkey" FOREIGN KEY ("embed_id") REFERENCES "embed_configs" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
33
  CONSTRAINT "embed_chats_usersId_fkey" FOREIGN KEY ("usersId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
34
  );
 
1
  -- CreateTable
2
  CREATE TABLE "embed_configs" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "uuid" TEXT NOT NULL,
5
  "enabled" BOOLEAN NOT NULL DEFAULT false,
6
  "chat_mode" TEXT NOT NULL DEFAULT 'query',
 
13
  "workspace_id" INTEGER NOT NULL,
14
  "createdBy" INTEGER,
15
  "usersId" INTEGER,
16
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
17
  CONSTRAINT "embed_configs_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
18
  CONSTRAINT "embed_configs_usersId_fkey" FOREIGN KEY ("usersId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
19
  );
20
 
21
  -- CreateTable
22
  CREATE TABLE "embed_chats" (
23
+ "id" SERIAL PRIMARY KEY,
24
  "prompt" TEXT NOT NULL,
25
  "response" TEXT NOT NULL,
26
  "session_id" TEXT NOT NULL,
 
28
  "connection_information" TEXT,
29
  "embed_id" INTEGER NOT NULL,
30
  "usersId" INTEGER,
31
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
32
  CONSTRAINT "embed_chats_embed_id_fkey" FOREIGN KEY ("embed_id") REFERENCES "embed_configs" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
33
  CONSTRAINT "embed_chats_usersId_fkey" FOREIGN KEY ("usersId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
34
  );
server/prisma/migrations/20240206181106_init/migration.sql CHANGED
@@ -1,11 +1,11 @@
1
  -- CreateTable
2
  CREATE TABLE "workspace_suggested_messages" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "workspaceId" INTEGER NOT NULL,
5
  "heading" TEXT NOT NULL,
6
  "message" TEXT NOT NULL,
7
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
9
  CONSTRAINT "workspace_suggested_messages_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE
10
  );
11
 
 
1
  -- CreateTable
2
  CREATE TABLE "workspace_suggested_messages" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "workspaceId" INTEGER NOT NULL,
5
  "heading" TEXT NOT NULL,
6
  "message" TEXT NOT NULL,
7
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
9
  CONSTRAINT "workspace_suggested_messages_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE
10
  );
11
 
server/prisma/migrations/20240206211916_init/migration.sql CHANGED
@@ -1,10 +1,10 @@
1
  -- CreateTable
2
  CREATE TABLE "event_logs" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "event" TEXT NOT NULL,
5
  "metadata" TEXT,
6
  "userId" INTEGER,
7
- "occurredAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
8
  );
9
 
10
  -- CreateIndex
 
1
  -- CreateTable
2
  CREATE TABLE "event_logs" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "event" TEXT NOT NULL,
5
  "metadata" TEXT,
6
  "userId" INTEGER,
7
+ "occurredAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
8
  );
9
 
10
  -- CreateIndex
server/prisma/migrations/20240208224848_init/migration.sql CHANGED
@@ -3,13 +3,13 @@ ALTER TABLE "workspace_chats" ADD COLUMN "thread_id" INTEGER;
3
 
4
  -- CreateTable
5
  CREATE TABLE "workspace_threads" (
6
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
7
  "name" TEXT NOT NULL,
8
  "slug" TEXT NOT NULL,
9
  "workspace_id" INTEGER NOT NULL,
10
  "user_id" INTEGER,
11
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
12
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
13
  CONSTRAINT "workspace_threads_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
14
  CONSTRAINT "workspace_threads_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
15
  );
 
3
 
4
  -- CreateTable
5
  CREATE TABLE "workspace_threads" (
6
+ "id" SERIAL PRIMARY KEY,
7
  "name" TEXT NOT NULL,
8
  "slug" TEXT NOT NULL,
9
  "workspace_id" INTEGER NOT NULL,
10
  "user_id" INTEGER,
11
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
12
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
13
  CONSTRAINT "workspace_threads_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
14
  CONSTRAINT "workspace_threads_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
15
  );
server/prisma/migrations/20240412183346_init/migration.sql CHANGED
@@ -4,15 +4,15 @@ ALTER TABLE "workspaces" ADD COLUMN "agentProvider" TEXT;
4
 
5
  -- CreateTable
6
  CREATE TABLE "workspace_agent_invocations" (
7
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
8
  "uuid" TEXT NOT NULL,
9
  "prompt" TEXT NOT NULL,
10
  "closed" BOOLEAN NOT NULL DEFAULT false,
11
  "user_id" INTEGER,
12
  "thread_id" INTEGER,
13
  "workspace_id" INTEGER NOT NULL,
14
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
15
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
16
  CONSTRAINT "workspace_agent_invocations_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
17
  CONSTRAINT "workspace_agent_invocations_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE
18
  );
 
4
 
5
  -- CreateTable
6
  CREATE TABLE "workspace_agent_invocations" (
7
+ "id" SERIAL PRIMARY KEY,
8
  "uuid" TEXT NOT NULL,
9
  "prompt" TEXT NOT NULL,
10
  "closed" BOOLEAN NOT NULL DEFAULT false,
11
  "user_id" INTEGER,
12
  "thread_id" INTEGER,
13
  "workspace_id" INTEGER NOT NULL,
14
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
15
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
16
  CONSTRAINT "workspace_agent_invocations_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
17
  CONSTRAINT "workspace_agent_invocations_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE
18
  );
server/prisma/migrations/20240425004220_init/migration.sql CHANGED
@@ -3,20 +3,20 @@ ALTER TABLE "users" ADD COLUMN "seen_recovery_codes" BOOLEAN DEFAULT false;
3
 
4
  -- CreateTable
5
  CREATE TABLE "recovery_codes" (
6
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
7
  "user_id" INTEGER NOT NULL,
8
  "code_hash" TEXT NOT NULL,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
  CONSTRAINT "recovery_codes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
11
  );
12
 
13
  -- CreateTable
14
  CREATE TABLE "password_reset_tokens" (
15
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
16
  "user_id" INTEGER NOT NULL,
17
  "token" TEXT NOT NULL,
18
- "expiresAt" DATETIME NOT NULL,
19
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
  CONSTRAINT "password_reset_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
21
  );
22
 
 
3
 
4
  -- CreateTable
5
  CREATE TABLE "recovery_codes" (
6
+ "id" SERIAL PRIMARY KEY,
7
  "user_id" INTEGER NOT NULL,
8
  "code_hash" TEXT NOT NULL,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
  CONSTRAINT "recovery_codes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
11
  );
12
 
13
  -- CreateTable
14
  CREATE TABLE "password_reset_tokens" (
15
+ "id" SERIAL PRIMARY KEY,
16
  "user_id" INTEGER NOT NULL,
17
  "token" TEXT NOT NULL,
18
+ "expiresAt" TIMESTAMP NOT NULL,
19
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
  CONSTRAINT "password_reset_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
21
  );
22
 
server/prisma/migrations/20240510032311_init/migration.sql CHANGED
@@ -1,13 +1,13 @@
1
  -- CreateTable
2
  CREATE TABLE "slash_command_presets" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "command" TEXT NOT NULL,
5
  "prompt" TEXT NOT NULL,
6
  "description" TEXT NOT NULL,
7
  "uid" INTEGER NOT NULL DEFAULT 0,
8
  "userId" INTEGER,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  CONSTRAINT "slash_command_presets_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
  );
13
 
 
1
  -- CreateTable
2
  CREATE TABLE "slash_command_presets" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "command" TEXT NOT NULL,
5
  "prompt" TEXT NOT NULL,
6
  "description" TEXT NOT NULL,
7
  "uid" INTEGER NOT NULL DEFAULT 0,
8
  "userId" INTEGER,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  CONSTRAINT "slash_command_presets_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
  );
13
 
server/prisma/migrations/20240618224346_init/migration.sql CHANGED
@@ -3,22 +3,22 @@ ALTER TABLE "workspace_documents" ADD COLUMN "watched" BOOLEAN DEFAULT false;
3
 
4
  -- CreateTable
5
  CREATE TABLE "document_sync_queues" (
6
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
7
  "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
8
- "nextSyncAt" DATETIME NOT NULL,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "lastSyncedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  "workspaceDocId" INTEGER NOT NULL,
12
  CONSTRAINT "document_sync_queues_workspaceDocId_fkey" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
13
  );
14
 
15
  -- CreateTable
16
  CREATE TABLE "document_sync_executions" (
17
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
18
  "queueId" INTEGER NOT NULL,
19
  "status" TEXT NOT NULL DEFAULT 'unknown',
20
  "result" TEXT,
21
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
22
  CONSTRAINT "document_sync_executions_queueId_fkey" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues" ("id") ON DELETE CASCADE ON UPDATE CASCADE
23
  );
24
 
 
3
 
4
  -- CreateTable
5
  CREATE TABLE "document_sync_queues" (
6
+ "id" SERIAL PRIMARY KEY,
7
  "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
8
+ "nextSyncAt" TIMESTAMP NOT NULL,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
+ "lastSyncedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  "workspaceDocId" INTEGER NOT NULL,
12
  CONSTRAINT "document_sync_queues_workspaceDocId_fkey" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
13
  );
14
 
15
  -- CreateTable
16
  CREATE TABLE "document_sync_executions" (
17
+ "id" SERIAL PRIMARY KEY,
18
  "queueId" INTEGER NOT NULL,
19
  "status" TEXT NOT NULL DEFAULT 'unknown',
20
  "result" TEXT,
21
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
22
  CONSTRAINT "document_sync_executions_queueId_fkey" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues" ("id") ON DELETE CASCADE ON UPDATE CASCADE
23
  );
24
 
server/prisma/migrations/20240824005054_init/migration.sql CHANGED
@@ -1,10 +1,10 @@
1
  -- CreateTable
2
  CREATE TABLE "browser_extension_api_keys" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "key" TEXT NOT NULL,
5
  "user_id" INTEGER,
6
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
- "lastUpdatedAt" DATETIME NOT NULL,
8
  CONSTRAINT "browser_extension_api_keys_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
  );
10
 
 
1
  -- CreateTable
2
  CREATE TABLE "browser_extension_api_keys" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "key" TEXT NOT NULL,
5
  "user_id" INTEGER,
6
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
+ "lastUpdatedAt" TIMESTAMP NOT NULL,
8
  CONSTRAINT "browser_extension_api_keys_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
  );
10
 
server/prisma/migrations/20241029203722_init/migration.sql CHANGED
@@ -1,10 +1,10 @@
1
  -- CreateTable
2
  CREATE TABLE "temporary_auth_tokens" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "token" TEXT NOT NULL,
5
  "userId" INTEGER NOT NULL,
6
- "expiresAt" DATETIME NOT NULL,
7
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
  CONSTRAINT "temporary_auth_tokens_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
  );
10
 
 
1
  -- CreateTable
2
  CREATE TABLE "temporary_auth_tokens" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "token" TEXT NOT NULL,
5
  "userId" INTEGER NOT NULL,
6
+ "expiresAt" TIMESTAMP NOT NULL,
7
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
  CONSTRAINT "temporary_auth_tokens_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
  );
10
 
server/prisma/migrations/20250318154720_init/migration.sql CHANGED
@@ -1,13 +1,13 @@
1
  -- CreateTable
2
  CREATE TABLE "system_prompt_variables" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "key" TEXT NOT NULL,
5
  "value" TEXT,
6
  "description" TEXT,
7
  "type" TEXT NOT NULL DEFAULT 'system',
8
  "userId" INTEGER,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "updatedAt" DATETIME NOT NULL,
11
  CONSTRAINT "system_prompt_variables_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
  );
13
 
 
1
  -- CreateTable
2
  CREATE TABLE "system_prompt_variables" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "key" TEXT NOT NULL,
5
  "value" TEXT,
6
  "description" TEXT,
7
  "type" TEXT NOT NULL DEFAULT 'system',
8
  "userId" INTEGER,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
+ "updatedAt" TIMESTAMP NOT NULL,
11
  CONSTRAINT "system_prompt_variables_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
  );
13
 
server/prisma/migrations/20250506214129_init/migration.sql CHANGED
@@ -1,10 +1,10 @@
1
  -- CreateTable
2
  CREATE TABLE "prompt_history" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "workspaceId" INTEGER NOT NULL,
5
  "prompt" TEXT NOT NULL,
6
  "modifiedBy" INTEGER,
7
- "modifiedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
  CONSTRAINT "prompt_history_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
9
  CONSTRAINT "prompt_history_modifiedBy_fkey" FOREIGN KEY ("modifiedBy") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
10
  );
 
1
  -- CreateTable
2
  CREATE TABLE "prompt_history" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "workspaceId" INTEGER NOT NULL,
5
  "prompt" TEXT NOT NULL,
6
  "modifiedBy" INTEGER,
7
+ "modifiedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
  CONSTRAINT "prompt_history_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
9
  CONSTRAINT "prompt_history_modifiedBy_fkey" FOREIGN KEY ("modifiedBy") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
10
  );
server/prisma/migrations/20250725194841_init/migration.sql CHANGED
@@ -1,12 +1,12 @@
1
  -- CreateTable
2
  CREATE TABLE "desktop_mobile_devices" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "deviceOs" TEXT NOT NULL,
5
  "deviceName" TEXT NOT NULL,
6
  "token" TEXT NOT NULL,
7
  "approved" BOOLEAN NOT NULL DEFAULT false,
8
  "userId" INTEGER,
9
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
  CONSTRAINT "desktop_mobile_devices_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
11
  );
12
 
 
1
  -- CreateTable
2
  CREATE TABLE "desktop_mobile_devices" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "deviceOs" TEXT NOT NULL,
5
  "deviceName" TEXT NOT NULL,
6
  "token" TEXT NOT NULL,
7
  "approved" BOOLEAN NOT NULL DEFAULT false,
8
  "userId" INTEGER,
9
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
  CONSTRAINT "desktop_mobile_devices_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
11
  );
12
 
server/prisma/migrations/20250808171557_init/migration.sql CHANGED
@@ -1,13 +1,13 @@
1
  -- CreateTable
2
  CREATE TABLE "workspace_parsed_files" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
  "filename" TEXT NOT NULL,
5
  "workspaceId" INTEGER NOT NULL,
6
  "userId" INTEGER,
7
  "threadId" INTEGER,
8
  "metadata" TEXT,
9
  "tokenCountEstimate" INTEGER DEFAULT 0,
10
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  CONSTRAINT "workspace_parsed_files_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
12
  CONSTRAINT "workspace_parsed_files_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
13
  CONSTRAINT "workspace_parsed_files_threadId_fkey" FOREIGN KEY ("threadId") REFERENCES "workspace_threads" ("id") ON DELETE CASCADE ON UPDATE CASCADE
 
1
  -- CreateTable
2
  CREATE TABLE "workspace_parsed_files" (
3
+ "id" SERIAL PRIMARY KEY,
4
  "filename" TEXT NOT NULL,
5
  "workspaceId" INTEGER NOT NULL,
6
  "userId" INTEGER,
7
  "threadId" INTEGER,
8
  "metadata" TEXT,
9
  "tokenCountEstimate" INTEGER DEFAULT 0,
10
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
  CONSTRAINT "workspace_parsed_files_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
12
  CONSTRAINT "workspace_parsed_files_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
13
  CONSTRAINT "workspace_parsed_files_threadId_fkey" FOREIGN KEY ("threadId") REFERENCES "workspace_threads" ("id") ON DELETE CASCADE ON UPDATE CASCADE
server/prisma/verify-postgres-conversions.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * 验证 PostgreSQL 转换是否正确
6
+ */
7
+
8
+ // 需要检查的 SQLite 语法模式
9
+ const sqlitePatterns = [
10
+ /AUTOINCREMENT/i,
11
+ /DATETIME/i,
12
+ /INTEGER\s+NOT\s+NULL\s+PRIMARY\s+KEY\s+AUTOINCREMENT/i
13
+ ];
14
+
15
+ /**
16
+ * 验证单个 SQL 文件
17
+ */
18
+ function verifySqlFile(filePath) {
19
+ try {
20
+ const sqlContent = fs.readFileSync(filePath, 'utf8');
21
+ const issues = [];
22
+
23
+ // 检查是否还有 SQLite 语法
24
+ sqlitePatterns.forEach(pattern => {
25
+ if (pattern.test(sqlContent)) {
26
+ issues.push(`发现 SQLite 语法: ${pattern.source}`);
27
+ }
28
+ });
29
+
30
+ // 检查 PostgreSQL 语法是否正确
31
+ if (!sqlContent.includes('SERIAL PRIMARY KEY') && sqlContent.includes('CREATE TABLE')) {
32
+ // 检查是否有 SERIAL 或者 SERIAL PRIMARY KEY
33
+ const hasSerial = /\bSERIAL\b/.test(sqlContent);
34
+ const hasPrimaryKey = /\bPRIMARY\s+KEY\b/.test(sqlContent);
35
+
36
+ if (!hasSerial && !hasPrimaryKey) {
37
+ issues.push('缺少 SERIAL 或 PRIMARY KEY 定义');
38
+ }
39
+ }
40
+
41
+ return {
42
+ file: path.basename(filePath),
43
+ issues: issues,
44
+ isValid: issues.length === 0
45
+ };
46
+ } catch (error) {
47
+ return {
48
+ file: path.basename(filePath),
49
+ issues: [`读取文件失败: ${error.message}`],
50
+ isValid: false
51
+ };
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 递归验证目录中的所有迁移文件
57
+ */
58
+ function verifyMigrationsDirectory(migrationsDir) {
59
+ const items = fs.readdirSync(migrationsDir);
60
+ const results = [];
61
+
62
+ items.forEach(item => {
63
+ const itemPath = path.join(migrationsDir, item);
64
+ const stat = fs.statSync(itemPath);
65
+
66
+ if (stat.isDirectory() && item !== 'migration_lock.toml') {
67
+ // 递归处理子目录
68
+ const subResults = verifyMigrationsDirectory(itemPath);
69
+ results.push(...subResults);
70
+ } else if (item === 'migration.sql') {
71
+ // 验证迁移文件
72
+ results.push(verifySqlFile(itemPath));
73
+ }
74
+ });
75
+
76
+ return results;
77
+ }
78
+
79
+ /**
80
+ * 生成验证报告
81
+ */
82
+ function generateReport(results) {
83
+ const validFiles = results.filter(r => r.isValid);
84
+ const invalidFiles = results.filter(r => !r.isValid);
85
+
86
+ console.log('=== PostgreSQL 转换验证报告 ===\n');
87
+
88
+ console.log(`总文件数: ${results.length}`);
89
+ console.log(`有效文件: ${validFiles.length}`);
90
+ console.log(`有问题的文件: ${invalidFiles.length}\n`);
91
+
92
+ if (invalidFiles.length > 0) {
93
+ console.log('=== 有问题的文件 ===');
94
+ invalidFiles.forEach(result => {
95
+ console.log(`\n📄 ${result.file}:`);
96
+ result.issues.forEach(issue => {
97
+ console.log(` ❌ ${issue}`);
98
+ });
99
+ });
100
+ }
101
+
102
+ console.log('\n=== 有效文件 ===');
103
+ validFiles.forEach(result => {
104
+ console.log(` ✅ ${result.file}`);
105
+ });
106
+
107
+ return {
108
+ total: results.length,
109
+ valid: validFiles.length,
110
+ invalid: invalidFiles.length
111
+ };
112
+ }
113
+
114
+ /**
115
+ * 主函数
116
+ */
117
+ function main() {
118
+ const migrationsDir = path.join(__dirname, 'migrations');
119
+
120
+ console.log('开始验证 PostgreSQL 转换...\n');
121
+
122
+ const results = verifyMigrationsDirectory(migrationsDir);
123
+ const report = generateReport(results);
124
+
125
+ if (report.invalid === 0) {
126
+ console.log('\n🎉 所有文件都已正确转换为 PostgreSQL 语法!');
127
+ } else {
128
+ console.log(`\n⚠️ 发现 ${report.invalid} 个文件需要手动检查。`);
129
+ }
130
+
131
+ return report;
132
+ }
133
+
134
+ // 运行验证
135
+ if (require.main === module) {
136
+ main();
137
+ }
138
+
139
+ module.exports = { verifySqlFile, verifyMigrationsDirectory, generateReport };