spine-framework 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -95,18 +95,65 @@ async function migrateCommand(options: MigrateOptions): Promise<void> {
|
|
|
95
95
|
const sql = readFileSync(resolve(MIGRATIONS_DIR, file), 'utf8')
|
|
96
96
|
process.stdout.write(` Applying ${file}... `)
|
|
97
97
|
|
|
98
|
-
// Split into
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
// Split SQL into statements, being careful to preserve dollar-quoted blocks.
|
|
99
|
+
// Dollar-quoted strings ($$ ... $$ or $tag$ ... $tag$) can contain semicolons
|
|
100
|
+
// that are NOT statement terminators.
|
|
101
|
+
function splitSqlStatements(sql: string): string[] {
|
|
102
|
+
const statements: string[] = []
|
|
103
|
+
let current = ''
|
|
104
|
+
let inDollarQuote = false
|
|
105
|
+
let dollarTag = ''
|
|
106
|
+
let i = 0
|
|
107
|
+
|
|
108
|
+
while (i < sql.length) {
|
|
109
|
+
if (!inDollarQuote) {
|
|
110
|
+
// Check for start of dollar quote: $tag$ or $$
|
|
111
|
+
const dollarMatch = sql.slice(i).match(/^(\$[A-Za-z_]*\$)/)
|
|
112
|
+
if (dollarMatch) {
|
|
113
|
+
inDollarQuote = true
|
|
114
|
+
dollarTag = dollarMatch[1]
|
|
115
|
+
current += dollarMatch[1]
|
|
116
|
+
i += dollarMatch[1].length
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
// Check for statement terminator (semicolon outside dollar quote)
|
|
120
|
+
if (sql[i] === ';') {
|
|
121
|
+
const stmt = current.trim()
|
|
122
|
+
if (stmt.length > 0 && !stmt.startsWith('--')) {
|
|
123
|
+
statements.push(stmt + ';')
|
|
124
|
+
}
|
|
125
|
+
current = ''
|
|
126
|
+
i++
|
|
127
|
+
continue
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
// We're inside a dollar-quoted string
|
|
131
|
+
// Check for end of dollar quote
|
|
132
|
+
if (sql.slice(i, i + dollarTag.length) === dollarTag) {
|
|
133
|
+
inDollarQuote = false
|
|
134
|
+
current += dollarTag
|
|
135
|
+
i += dollarTag.length
|
|
136
|
+
continue
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
current += sql[i]
|
|
140
|
+
i++
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Don't forget the last statement (might not have trailing semicolon)
|
|
144
|
+
const last = current.trim()
|
|
145
|
+
if (last.length > 0 && !last.startsWith('--')) {
|
|
146
|
+
statements.push(last + (last.endsWith(';') ? '' : ';'))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return statements
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const statements = splitSqlStatements(sql)
|
|
106
153
|
|
|
107
154
|
try {
|
|
108
155
|
for (const stmt of statements) {
|
|
109
|
-
await client.query(stmt
|
|
156
|
+
await client.query(stmt)
|
|
110
157
|
}
|
|
111
158
|
console.log('✓')
|
|
112
159
|
applied++
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/migrate.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/migrate.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkKxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,QAevD"}
|