( schemaName: string, sql: string )
| 553 | // Our parser follows this spec |
| 554 | // https://www.sqlite.org/lang_createtable.html |
| 555 | export function parseCreateTableScript( |
| 556 | schemaName: string, |
| 557 | sql: string |
| 558 | ): DatabaseTableSchema { |
| 559 | const cursor = new CursorV2(tokenizeSql(sql, "sqlite")); |
| 560 | |
| 561 | cursor.expectToken("CREATE"); |
| 562 | cursor.expectTokenOptional("TEMP"); |
| 563 | cursor.expectTokenOptional("TEMPORARY"); |
| 564 | cursor.expectTokenOptional("VIRTUAL"); |
| 565 | cursor.expectToken("TABLE"); |
| 566 | cursor.expectTokensOptional(["IF", "NOT", "EXIST"]); |
| 567 | |
| 568 | const tableName = cursor.consumeIdentifier(); |
| 569 | |
| 570 | // Check for FTS5 |
| 571 | let fts5: DatabaseTableFts5 | undefined; |
| 572 | |
| 573 | if (cursor.match("USING")) { |
| 574 | cursor.next(); |
| 575 | if (cursor.match("FTS5")) { |
| 576 | cursor.next(); |
| 577 | fts5 = parseFTS5(cursor.consumeParen()); |
| 578 | } |
| 579 | } |
| 580 | |
| 581 | const defs = cursor.match("(") |
| 582 | ? parseTableDefinition(schemaName, cursor.consumeParen()) |
| 583 | : { columns: [], constraints: [] }; |
| 584 | |
| 585 | // Parsing table options |
| 586 | const pk = defs.columns.filter((col) => col.pk).map((col) => col.name); |
| 587 | |
| 588 | const autoIncrement = defs.columns.some( |
| 589 | (col) => !!col.constraint?.autoIncrement |
| 590 | ); |
| 591 | |
| 592 | return { |
| 593 | tableName, |
| 594 | schemaName, |
| 595 | ...defs, |
| 596 | pk, |
| 597 | autoIncrement, |
| 598 | fts5, |
| 599 | ...parseTableOption(cursor), |
| 600 | }; |
| 601 | } |
searching dependent graphs…