(stmt: string)
| 205 | /^create\s+table\s+(?:if\s+not\s+exists\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*\(([\s\S]*)\)\s*$/i; |
| 206 | |
| 207 | export function parseCreateTable(stmt: string): ParsedTable | null { |
| 208 | const m = CREATE_TABLE_RE.exec(stmt.trim()); |
| 209 | if (!m) return null; |
| 210 | const name = m[1]; |
| 211 | const body = m[2]; |
| 212 | |
| 213 | const lines = splitColumnList(body); |
| 214 | const columns: ParsedColumn[] = []; |
| 215 | const extras: string[] = []; |
| 216 | |
| 217 | for (const line of lines) { |
| 218 | const col = parseColumnLine(line); |
| 219 | if (col) { |
| 220 | columns.push(col); |
| 221 | continue; |
| 222 | } |
| 223 | const trimmed = line.trim().replace(/,$/, '').trim(); |
| 224 | if (trimmed.length > 0) extras.push(trimmed); |
| 225 | } |
| 226 | |
| 227 | let primaryKey: string | null = columns.find(c => c.isPrimaryKey)?.name ?? null; |
| 228 | if (!primaryKey) { |
| 229 | for (const extra of extras) { |
| 230 | const pkMatch = /^primary\s+key\s*\(\s*`?([A-Za-z_][A-Za-z0-9_]*)`?\s*\)/i.exec(extra); |
| 231 | if (pkMatch) { |
| 232 | primaryKey = pkMatch[1]; |
| 233 | break; |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | return { |
| 239 | name, |
| 240 | columns, |
| 241 | primaryKey, |
| 242 | extraConstraints: extras, |
| 243 | rawDdl: stmt.trim(), |
| 244 | }; |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * Split a column-list body on top-level commas (i.e. commas not inside |
no test coverage detected