@pineliner/odb-client 1.0.3 → 1.0.4
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.
- package/dist/database/sql-parser.d.ts +1 -1
- package/dist/database/sql-parser.d.ts.map +1 -1
- package/dist/index.cjs +20 -46
- package/dist/index.js +20 -46
- package/package.json +1 -1
- package/src/database/sql-parser.ts +26 -64
|
@@ -7,7 +7,7 @@ export interface SQLParserOptions {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Parse SQL file into statements, separating PRAGMA from regular SQL
|
|
10
|
-
* Uses
|
|
10
|
+
* Uses custom parser that handles BEGIN...END blocks
|
|
11
11
|
*/
|
|
12
12
|
export declare function parseSQL(sqlContent: string, options?: SQLParserOptions): ParsedStatements;
|
|
13
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-parser.d.ts","sourceRoot":"","sources":["../../src/database/sql-parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql-parser.d.ts","sourceRoot":"","sources":["../../src/database/sql-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,gBAAgB,CA0B7F;AAoFD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAG/D"}
|
package/dist/index.cjs
CHANGED
|
@@ -1441,14 +1441,13 @@ const external_libsql_client_namespaceObject = require("@libsql/client");
|
|
|
1441
1441
|
// No explicit close needed
|
|
1442
1442
|
}
|
|
1443
1443
|
}
|
|
1444
|
-
const external_node_sql_parser_namespaceObject = require("node-sql-parser");
|
|
1445
1444
|
/**
|
|
1446
1445
|
* Parse SQL file into statements, separating PRAGMA from regular SQL
|
|
1447
|
-
* Uses
|
|
1446
|
+
* Uses custom parser that handles BEGIN...END blocks
|
|
1448
1447
|
*/ function parseSQL(sqlContent, options = {}) {
|
|
1449
1448
|
const separatePragma = options.separatePragma ?? true;
|
|
1450
|
-
//
|
|
1451
|
-
const statements =
|
|
1449
|
+
// Split SQL statements manually
|
|
1450
|
+
const statements = splitStatements(sqlContent);
|
|
1452
1451
|
if (!separatePragma) return {
|
|
1453
1452
|
pragmaStatements: [],
|
|
1454
1453
|
regularStatements: statements
|
|
@@ -1465,54 +1464,29 @@ const external_node_sql_parser_namespaceObject = require("node-sql-parser");
|
|
|
1465
1464
|
regularStatements
|
|
1466
1465
|
};
|
|
1467
1466
|
}
|
|
1468
|
-
/**
|
|
1469
|
-
* Split SQL content using node-sql-parser (more robust than custom parser)
|
|
1470
|
-
* Falls back to simple split if parser fails
|
|
1471
|
-
*/ function splitStatementsWithParser(sqlContent) {
|
|
1472
|
-
try {
|
|
1473
|
-
const parser = new external_node_sql_parser_namespaceObject.Parser();
|
|
1474
|
-
// node-sql-parser supports splitting multiple statements
|
|
1475
|
-
// Try to use it, but have fallback for edge cases
|
|
1476
|
-
const opt = {
|
|
1477
|
-
database: 'sqlite',
|
|
1478
|
-
type: 'table'
|
|
1479
|
-
};
|
|
1480
|
-
// Split by semicolons first to handle parser limitations with very large files
|
|
1481
|
-
const roughStatements = sqlContent.split(/;[\s\n]*/).map((s)=>s.trim()).filter((s)=>s.length > 0);
|
|
1482
|
-
const validStatements = [];
|
|
1483
|
-
for (const stmt of roughStatements){
|
|
1484
|
-
// Add semicolon back
|
|
1485
|
-
const fullStmt = stmt + ';';
|
|
1486
|
-
// Skip comments-only statements
|
|
1487
|
-
if (!stmt.trim().startsWith('--') && '' !== stmt.trim()) // Validate with parser (but don't fail if it can't parse complex statements)
|
|
1488
|
-
try {
|
|
1489
|
-
parser.astify(fullStmt, opt);
|
|
1490
|
-
validStatements.push(fullStmt);
|
|
1491
|
-
} catch (parseError) {
|
|
1492
|
-
// If parser can't handle it, include it anyway if it looks like valid SQL
|
|
1493
|
-
// This handles complex statements like CREATE TRIGGER, CREATE VIEW with subqueries
|
|
1494
|
-
if (stmt.match(/^(CREATE|ALTER|DROP|INSERT|UPDATE|DELETE|SELECT|PRAGMA)/i)) validStatements.push(fullStmt);
|
|
1495
|
-
else console.warn(`Skipping potentially invalid statement: ${stmt.substring(0, 50)}...`);
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
return validStatements;
|
|
1499
|
-
} catch (error) {
|
|
1500
|
-
console.warn('node-sql-parser failed, using fallback parser:', error);
|
|
1501
|
-
// Fallback to original simple parser
|
|
1502
|
-
return splitStatements(sqlContent);
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
1467
|
/**
|
|
1506
1468
|
* Split SQL content into individual statements
|
|
1507
|
-
* Handles comments, quotes, and
|
|
1469
|
+
* Handles comments, quotes, semicolons, and BEGIN...END blocks properly
|
|
1508
1470
|
*/ function splitStatements(sqlContent) {
|
|
1509
1471
|
const statements = [];
|
|
1510
1472
|
let currentStatement = '';
|
|
1511
1473
|
let inQuote = false;
|
|
1512
1474
|
let quoteChar = '';
|
|
1475
|
+
let beginEndDepth = 0;
|
|
1513
1476
|
const lines = sqlContent.split('\n');
|
|
1514
1477
|
for (const line of lines){
|
|
1515
1478
|
let processedLine = '';
|
|
1479
|
+
const lineWithoutComments = line.replace(/--.*$/, '');
|
|
1480
|
+
// Track BEGIN...END depth for this line BEFORE processing characters
|
|
1481
|
+
if (!inQuote && lineWithoutComments.trim()) {
|
|
1482
|
+
const beginMatches = lineWithoutComments.match(/\bBEGIN\b/gi);
|
|
1483
|
+
const endMatches = lineWithoutComments.match(/\bEND\b/gi);
|
|
1484
|
+
if (beginMatches) beginEndDepth += beginMatches.length;
|
|
1485
|
+
if (endMatches) {
|
|
1486
|
+
beginEndDepth -= endMatches.length;
|
|
1487
|
+
if (beginEndDepth < 0) beginEndDepth = 0;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1516
1490
|
for(let i = 0; i < line.length; i++){
|
|
1517
1491
|
const char = line[i];
|
|
1518
1492
|
const prevChar = i > 0 ? line[i - 1] : '';
|
|
@@ -1532,11 +1506,11 @@ const external_node_sql_parser_namespaceObject = require("node-sql-parser");
|
|
|
1532
1506
|
}
|
|
1533
1507
|
}
|
|
1534
1508
|
processedLine += char;
|
|
1535
|
-
// Split on semicolon when not in quotes
|
|
1536
|
-
if (';' === char && !inQuote) {
|
|
1509
|
+
// Split on semicolon when not in quotes AND not inside BEGIN...END
|
|
1510
|
+
if (';' === char && !inQuote && 0 === beginEndDepth) {
|
|
1537
1511
|
currentStatement += processedLine;
|
|
1538
1512
|
const stmt = currentStatement.trim();
|
|
1539
|
-
if (stmt) statements.push(stmt);
|
|
1513
|
+
if (stmt && !stmt.startsWith('--')) statements.push(stmt);
|
|
1540
1514
|
currentStatement = '';
|
|
1541
1515
|
processedLine = '';
|
|
1542
1516
|
}
|
|
@@ -1545,7 +1519,7 @@ const external_node_sql_parser_namespaceObject = require("node-sql-parser");
|
|
|
1545
1519
|
}
|
|
1546
1520
|
// Handle remaining statement
|
|
1547
1521
|
const finalStmt = currentStatement.trim();
|
|
1548
|
-
if (finalStmt) statements.push(finalStmt);
|
|
1522
|
+
if (finalStmt && !finalStmt.startsWith('--')) statements.push(finalStmt);
|
|
1549
1523
|
return statements;
|
|
1550
1524
|
}
|
|
1551
1525
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as __WEBPACK_EXTERNAL_MODULE_bun_sqlite__ from "bun:sqlite";
|
|
2
2
|
import * as __WEBPACK_EXTERNAL_MODULE__libsql_client__ from "@libsql/client";
|
|
3
|
-
import * as __WEBPACK_EXTERNAL_MODULE_node_sql_parser__ from "node-sql-parser";
|
|
4
3
|
import * as __WEBPACK_EXTERNAL_MODULE_node_fs__ from "node:fs";
|
|
5
4
|
// Core types for the ODBLite client
|
|
6
5
|
// Error types
|
|
@@ -1369,11 +1368,11 @@ ODBLiteClient.join;
|
|
|
1369
1368
|
}
|
|
1370
1369
|
/**
|
|
1371
1370
|
* Parse SQL file into statements, separating PRAGMA from regular SQL
|
|
1372
|
-
* Uses
|
|
1371
|
+
* Uses custom parser that handles BEGIN...END blocks
|
|
1373
1372
|
*/ function parseSQL(sqlContent, options = {}) {
|
|
1374
1373
|
const separatePragma = options.separatePragma ?? true;
|
|
1375
|
-
//
|
|
1376
|
-
const statements =
|
|
1374
|
+
// Split SQL statements manually
|
|
1375
|
+
const statements = splitStatements(sqlContent);
|
|
1377
1376
|
if (!separatePragma) return {
|
|
1378
1377
|
pragmaStatements: [],
|
|
1379
1378
|
regularStatements: statements
|
|
@@ -1390,54 +1389,29 @@ ODBLiteClient.join;
|
|
|
1390
1389
|
regularStatements
|
|
1391
1390
|
};
|
|
1392
1391
|
}
|
|
1393
|
-
/**
|
|
1394
|
-
* Split SQL content using node-sql-parser (more robust than custom parser)
|
|
1395
|
-
* Falls back to simple split if parser fails
|
|
1396
|
-
*/ function splitStatementsWithParser(sqlContent) {
|
|
1397
|
-
try {
|
|
1398
|
-
const parser = new __WEBPACK_EXTERNAL_MODULE_node_sql_parser__.Parser();
|
|
1399
|
-
// node-sql-parser supports splitting multiple statements
|
|
1400
|
-
// Try to use it, but have fallback for edge cases
|
|
1401
|
-
const opt = {
|
|
1402
|
-
database: 'sqlite',
|
|
1403
|
-
type: 'table'
|
|
1404
|
-
};
|
|
1405
|
-
// Split by semicolons first to handle parser limitations with very large files
|
|
1406
|
-
const roughStatements = sqlContent.split(/;[\s\n]*/).map((s)=>s.trim()).filter((s)=>s.length > 0);
|
|
1407
|
-
const validStatements = [];
|
|
1408
|
-
for (const stmt of roughStatements){
|
|
1409
|
-
// Add semicolon back
|
|
1410
|
-
const fullStmt = stmt + ';';
|
|
1411
|
-
// Skip comments-only statements
|
|
1412
|
-
if (!stmt.trim().startsWith('--') && '' !== stmt.trim()) // Validate with parser (but don't fail if it can't parse complex statements)
|
|
1413
|
-
try {
|
|
1414
|
-
parser.astify(fullStmt, opt);
|
|
1415
|
-
validStatements.push(fullStmt);
|
|
1416
|
-
} catch (parseError) {
|
|
1417
|
-
// If parser can't handle it, include it anyway if it looks like valid SQL
|
|
1418
|
-
// This handles complex statements like CREATE TRIGGER, CREATE VIEW with subqueries
|
|
1419
|
-
if (stmt.match(/^(CREATE|ALTER|DROP|INSERT|UPDATE|DELETE|SELECT|PRAGMA)/i)) validStatements.push(fullStmt);
|
|
1420
|
-
else console.warn(`Skipping potentially invalid statement: ${stmt.substring(0, 50)}...`);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
return validStatements;
|
|
1424
|
-
} catch (error) {
|
|
1425
|
-
console.warn('node-sql-parser failed, using fallback parser:', error);
|
|
1426
|
-
// Fallback to original simple parser
|
|
1427
|
-
return splitStatements(sqlContent);
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
1392
|
/**
|
|
1431
1393
|
* Split SQL content into individual statements
|
|
1432
|
-
* Handles comments, quotes, and
|
|
1394
|
+
* Handles comments, quotes, semicolons, and BEGIN...END blocks properly
|
|
1433
1395
|
*/ function splitStatements(sqlContent) {
|
|
1434
1396
|
const statements = [];
|
|
1435
1397
|
let currentStatement = '';
|
|
1436
1398
|
let inQuote = false;
|
|
1437
1399
|
let quoteChar = '';
|
|
1400
|
+
let beginEndDepth = 0;
|
|
1438
1401
|
const lines = sqlContent.split('\n');
|
|
1439
1402
|
for (const line of lines){
|
|
1440
1403
|
let processedLine = '';
|
|
1404
|
+
const lineWithoutComments = line.replace(/--.*$/, '');
|
|
1405
|
+
// Track BEGIN...END depth for this line BEFORE processing characters
|
|
1406
|
+
if (!inQuote && lineWithoutComments.trim()) {
|
|
1407
|
+
const beginMatches = lineWithoutComments.match(/\bBEGIN\b/gi);
|
|
1408
|
+
const endMatches = lineWithoutComments.match(/\bEND\b/gi);
|
|
1409
|
+
if (beginMatches) beginEndDepth += beginMatches.length;
|
|
1410
|
+
if (endMatches) {
|
|
1411
|
+
beginEndDepth -= endMatches.length;
|
|
1412
|
+
if (beginEndDepth < 0) beginEndDepth = 0;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1441
1415
|
for(let i = 0; i < line.length; i++){
|
|
1442
1416
|
const char = line[i];
|
|
1443
1417
|
const prevChar = i > 0 ? line[i - 1] : '';
|
|
@@ -1457,11 +1431,11 @@ ODBLiteClient.join;
|
|
|
1457
1431
|
}
|
|
1458
1432
|
}
|
|
1459
1433
|
processedLine += char;
|
|
1460
|
-
// Split on semicolon when not in quotes
|
|
1461
|
-
if (';' === char && !inQuote) {
|
|
1434
|
+
// Split on semicolon when not in quotes AND not inside BEGIN...END
|
|
1435
|
+
if (';' === char && !inQuote && 0 === beginEndDepth) {
|
|
1462
1436
|
currentStatement += processedLine;
|
|
1463
1437
|
const stmt = currentStatement.trim();
|
|
1464
|
-
if (stmt) statements.push(stmt);
|
|
1438
|
+
if (stmt && !stmt.startsWith('--')) statements.push(stmt);
|
|
1465
1439
|
currentStatement = '';
|
|
1466
1440
|
processedLine = '';
|
|
1467
1441
|
}
|
|
@@ -1470,7 +1444,7 @@ ODBLiteClient.join;
|
|
|
1470
1444
|
}
|
|
1471
1445
|
// Handle remaining statement
|
|
1472
1446
|
const finalStmt = currentStatement.trim();
|
|
1473
|
-
if (finalStmt) statements.push(finalStmt);
|
|
1447
|
+
if (finalStmt && !finalStmt.startsWith('--')) statements.push(finalStmt);
|
|
1474
1448
|
return statements;
|
|
1475
1449
|
}
|
|
1476
1450
|
/**
|
package/package.json
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Parser } from 'node-sql-parser'
|
|
2
|
-
|
|
3
1
|
export interface ParsedStatements {
|
|
4
2
|
pragmaStatements: string[]
|
|
5
3
|
regularStatements: string[]
|
|
@@ -11,13 +9,13 @@ export interface SQLParserOptions {
|
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Parse SQL file into statements, separating PRAGMA from regular SQL
|
|
14
|
-
* Uses
|
|
12
|
+
* Uses custom parser that handles BEGIN...END blocks
|
|
15
13
|
*/
|
|
16
14
|
export function parseSQL(sqlContent: string, options: SQLParserOptions = {}): ParsedStatements {
|
|
17
15
|
const separatePragma = options.separatePragma ?? true
|
|
18
16
|
|
|
19
|
-
//
|
|
20
|
-
const statements =
|
|
17
|
+
// Split SQL statements manually
|
|
18
|
+
const statements = splitStatements(sqlContent)
|
|
21
19
|
|
|
22
20
|
if (!separatePragma) {
|
|
23
21
|
return {
|
|
@@ -41,74 +39,38 @@ export function parseSQL(sqlContent: string, options: SQLParserOptions = {}): Pa
|
|
|
41
39
|
return { pragmaStatements, regularStatements }
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
/**
|
|
45
|
-
* Split SQL content using node-sql-parser (more robust than custom parser)
|
|
46
|
-
* Falls back to simple split if parser fails
|
|
47
|
-
*/
|
|
48
|
-
function splitStatementsWithParser(sqlContent: string): string[] {
|
|
49
|
-
try {
|
|
50
|
-
const parser = new Parser()
|
|
51
|
-
|
|
52
|
-
// node-sql-parser supports splitting multiple statements
|
|
53
|
-
// Try to use it, but have fallback for edge cases
|
|
54
|
-
const opt = {
|
|
55
|
-
database: 'sqlite',
|
|
56
|
-
type: 'table' as any
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Split by semicolons first to handle parser limitations with very large files
|
|
60
|
-
const roughStatements = sqlContent.split(/;[\s\n]*/)
|
|
61
|
-
.map(s => s.trim())
|
|
62
|
-
.filter(s => s.length > 0)
|
|
63
|
-
|
|
64
|
-
const validStatements: string[] = []
|
|
65
|
-
|
|
66
|
-
for (const stmt of roughStatements) {
|
|
67
|
-
// Add semicolon back
|
|
68
|
-
const fullStmt = stmt + ';'
|
|
69
|
-
|
|
70
|
-
// Skip comments-only statements
|
|
71
|
-
if (stmt.trim().startsWith('--') || stmt.trim() === '') {
|
|
72
|
-
continue
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Validate with parser (but don't fail if it can't parse complex statements)
|
|
76
|
-
try {
|
|
77
|
-
parser.astify(fullStmt, opt)
|
|
78
|
-
validStatements.push(fullStmt)
|
|
79
|
-
} catch (parseError) {
|
|
80
|
-
// If parser can't handle it, include it anyway if it looks like valid SQL
|
|
81
|
-
// This handles complex statements like CREATE TRIGGER, CREATE VIEW with subqueries
|
|
82
|
-
if (stmt.match(/^(CREATE|ALTER|DROP|INSERT|UPDATE|DELETE|SELECT|PRAGMA)/i)) {
|
|
83
|
-
validStatements.push(fullStmt)
|
|
84
|
-
} else {
|
|
85
|
-
console.warn(`Skipping potentially invalid statement: ${stmt.substring(0, 50)}...`)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return validStatements
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.warn('node-sql-parser failed, using fallback parser:', error)
|
|
93
|
-
// Fallback to original simple parser
|
|
94
|
-
return splitStatements(sqlContent)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
42
|
/**
|
|
99
43
|
* Split SQL content into individual statements
|
|
100
|
-
* Handles comments, quotes, and
|
|
44
|
+
* Handles comments, quotes, semicolons, and BEGIN...END blocks properly
|
|
101
45
|
*/
|
|
102
46
|
function splitStatements(sqlContent: string): string[] {
|
|
103
47
|
const statements: string[] = []
|
|
104
48
|
let currentStatement = ''
|
|
105
49
|
let inQuote = false
|
|
106
50
|
let quoteChar = ''
|
|
51
|
+
let beginEndDepth = 0
|
|
107
52
|
|
|
108
53
|
const lines = sqlContent.split('\n')
|
|
109
54
|
|
|
110
55
|
for (const line of lines) {
|
|
111
56
|
let processedLine = ''
|
|
57
|
+
const lineWithoutComments = line.replace(/--.*$/, '')
|
|
58
|
+
|
|
59
|
+
// Track BEGIN...END depth for this line BEFORE processing characters
|
|
60
|
+
if (!inQuote && lineWithoutComments.trim()) {
|
|
61
|
+
const beginMatches = lineWithoutComments.match(/\bBEGIN\b/gi)
|
|
62
|
+
const endMatches = lineWithoutComments.match(/\bEND\b/gi)
|
|
63
|
+
|
|
64
|
+
if (beginMatches) {
|
|
65
|
+
beginEndDepth += beginMatches.length
|
|
66
|
+
}
|
|
67
|
+
if (endMatches) {
|
|
68
|
+
beginEndDepth -= endMatches.length
|
|
69
|
+
if (beginEndDepth < 0) {
|
|
70
|
+
beginEndDepth = 0
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
112
74
|
|
|
113
75
|
for (let i = 0; i < line.length; i++) {
|
|
114
76
|
const char = line[i]
|
|
@@ -133,11 +95,11 @@ function splitStatements(sqlContent: string): string[] {
|
|
|
133
95
|
|
|
134
96
|
processedLine += char
|
|
135
97
|
|
|
136
|
-
// Split on semicolon when not in quotes
|
|
137
|
-
if (char === ';' && !inQuote) {
|
|
98
|
+
// Split on semicolon when not in quotes AND not inside BEGIN...END
|
|
99
|
+
if (char === ';' && !inQuote && beginEndDepth === 0) {
|
|
138
100
|
currentStatement += processedLine
|
|
139
101
|
const stmt = currentStatement.trim()
|
|
140
|
-
if (stmt) {
|
|
102
|
+
if (stmt && !stmt.startsWith('--')) {
|
|
141
103
|
statements.push(stmt)
|
|
142
104
|
}
|
|
143
105
|
currentStatement = ''
|
|
@@ -152,7 +114,7 @@ function splitStatements(sqlContent: string): string[] {
|
|
|
152
114
|
|
|
153
115
|
// Handle remaining statement
|
|
154
116
|
const finalStmt = currentStatement.trim()
|
|
155
|
-
if (finalStmt) {
|
|
117
|
+
if (finalStmt && !finalStmt.startsWith('--')) {
|
|
156
118
|
statements.push(finalStmt)
|
|
157
119
|
}
|
|
158
120
|
|