sqlite-reader 0.1.0 → 0.2.0
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/package.json +2 -2
- package/sqlite-reader.cjs +14 -13
- package/sqlite-reader.mjs +14 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sqlite-reader",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Read-only SQLite3 binary parser — extract rows from a table given a raw file buffer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sqlite",
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
"types": "./index.d.ts",
|
|
39
39
|
"sideEffects": false,
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
41
|
+
"node": ">=22"
|
|
42
42
|
}
|
|
43
43
|
}
|
package/sqlite-reader.cjs
CHANGED
|
@@ -71,6 +71,15 @@ function traverseTable(db, pageNum, pageSize) {
|
|
|
71
71
|
const pageType = db[base + hdr];
|
|
72
72
|
const numCells = u16(db, base + hdr + 3);
|
|
73
73
|
const rows = [];
|
|
74
|
+
if (pageType === 5) {
|
|
75
|
+
const rightmost = u32(db, base + hdr + 8);
|
|
76
|
+
const ptrBase = base + hdr + 12;
|
|
77
|
+
for (let i = 0; i < numCells; i++) {
|
|
78
|
+
const cellPos = base + u16(db, ptrBase + i * 2);
|
|
79
|
+
rows.push(...traverseTable(db, u32(db, cellPos), pageSize));
|
|
80
|
+
}
|
|
81
|
+
rows.push(...traverseTable(db, rightmost, pageSize));
|
|
82
|
+
}
|
|
74
83
|
if (pageType === 13) {
|
|
75
84
|
const ptrBase = base + hdr + 8;
|
|
76
85
|
for (let i = 0; i < numCells; i++) {
|
|
@@ -81,21 +90,13 @@ function traverseTable(db, pageNum, pageSize) {
|
|
|
81
90
|
pos += rs;
|
|
82
91
|
rows.push(decodeRecord(db.subarray(pos, pos + payloadLen)));
|
|
83
92
|
}
|
|
84
|
-
} else if (pageType === 5) {
|
|
85
|
-
const rightmost = u32(db, base + hdr + 8);
|
|
86
|
-
const ptrBase = base + hdr + 12;
|
|
87
|
-
for (let i = 0; i < numCells; i++) {
|
|
88
|
-
const cellPos = base + u16(db, ptrBase + i * 2);
|
|
89
|
-
rows.push(...traverseTable(db, u32(db, cellPos), pageSize));
|
|
90
|
-
}
|
|
91
|
-
rows.push(...traverseTable(db, rightmost, pageSize));
|
|
92
93
|
}
|
|
93
94
|
return rows;
|
|
94
95
|
}
|
|
95
96
|
function parseColumnNames(sql) {
|
|
96
97
|
const start = sql.indexOf("(");
|
|
97
98
|
const end = sql.lastIndexOf(")");
|
|
98
|
-
if (start === -1 || end === -1) return [];
|
|
99
|
+
/* c8 ignore next */ if (start === -1 || end === -1) return [];
|
|
99
100
|
const defs = [];
|
|
100
101
|
let depth = 0;
|
|
101
102
|
let cur = "";
|
|
@@ -109,7 +110,7 @@ function parseColumnNames(sql) {
|
|
|
109
110
|
}
|
|
110
111
|
cur += ch;
|
|
111
112
|
}
|
|
112
|
-
if (cur.trim()) defs.push(cur.trim());
|
|
113
|
+
/* c8 ignore next */ if (cur.trim()) defs.push(cur.trim());
|
|
113
114
|
return defs.map((def) => def.match(/^["'`]?(\w+)["'`]?/)?.[1] ?? "").filter((name) => name && !/^(CONSTRAINT|PRIMARY|UNIQUE|CHECK|FOREIGN)/i.test(name));
|
|
114
115
|
}
|
|
115
116
|
var MAGIC = "SQLite format 3\0";
|
|
@@ -121,12 +122,12 @@ function readTable(db, tableName) {
|
|
|
121
122
|
let rootPage = null;
|
|
122
123
|
let columnSql = null;
|
|
123
124
|
for (const row of master) if (row[0] === "table" && row[1] === tableName) {
|
|
124
|
-
rootPage = typeof row[3] === "number" ? row[3] : null;
|
|
125
|
-
columnSql = typeof row[4] === "string" ? row[4] : null;
|
|
125
|
+
rootPage = typeof row[3] === "number" ? row[3] : /* c8 ignore next */ null;
|
|
126
|
+
columnSql = typeof row[4] === "string" ? row[4] : /* c8 ignore next */ null;
|
|
126
127
|
break;
|
|
127
128
|
}
|
|
128
129
|
if (rootPage === null) return [];
|
|
129
|
-
const columns = columnSql ? parseColumnNames(columnSql) : [];
|
|
130
|
+
const columns = columnSql ? parseColumnNames(columnSql) : /* c8 ignore next */ [];
|
|
130
131
|
return traverseTable(db, rootPage, pageSize).map((row) => Object.fromEntries(columns.map((col, i) => [col, row[i] ?? null])));
|
|
131
132
|
}
|
|
132
133
|
//#endregion
|
package/sqlite-reader.mjs
CHANGED
|
@@ -70,6 +70,15 @@ function traverseTable(db, pageNum, pageSize) {
|
|
|
70
70
|
const pageType = db[base + hdr];
|
|
71
71
|
const numCells = u16(db, base + hdr + 3);
|
|
72
72
|
const rows = [];
|
|
73
|
+
if (pageType === 5) {
|
|
74
|
+
const rightmost = u32(db, base + hdr + 8);
|
|
75
|
+
const ptrBase = base + hdr + 12;
|
|
76
|
+
for (let i = 0; i < numCells; i++) {
|
|
77
|
+
const cellPos = base + u16(db, ptrBase + i * 2);
|
|
78
|
+
rows.push(...traverseTable(db, u32(db, cellPos), pageSize));
|
|
79
|
+
}
|
|
80
|
+
rows.push(...traverseTable(db, rightmost, pageSize));
|
|
81
|
+
}
|
|
73
82
|
if (pageType === 13) {
|
|
74
83
|
const ptrBase = base + hdr + 8;
|
|
75
84
|
for (let i = 0; i < numCells; i++) {
|
|
@@ -80,21 +89,13 @@ function traverseTable(db, pageNum, pageSize) {
|
|
|
80
89
|
pos += rs;
|
|
81
90
|
rows.push(decodeRecord(db.subarray(pos, pos + payloadLen)));
|
|
82
91
|
}
|
|
83
|
-
} else if (pageType === 5) {
|
|
84
|
-
const rightmost = u32(db, base + hdr + 8);
|
|
85
|
-
const ptrBase = base + hdr + 12;
|
|
86
|
-
for (let i = 0; i < numCells; i++) {
|
|
87
|
-
const cellPos = base + u16(db, ptrBase + i * 2);
|
|
88
|
-
rows.push(...traverseTable(db, u32(db, cellPos), pageSize));
|
|
89
|
-
}
|
|
90
|
-
rows.push(...traverseTable(db, rightmost, pageSize));
|
|
91
92
|
}
|
|
92
93
|
return rows;
|
|
93
94
|
}
|
|
94
95
|
function parseColumnNames(sql) {
|
|
95
96
|
const start = sql.indexOf("(");
|
|
96
97
|
const end = sql.lastIndexOf(")");
|
|
97
|
-
if (start === -1 || end === -1) return [];
|
|
98
|
+
/* c8 ignore next */ if (start === -1 || end === -1) return [];
|
|
98
99
|
const defs = [];
|
|
99
100
|
let depth = 0;
|
|
100
101
|
let cur = "";
|
|
@@ -108,7 +109,7 @@ function parseColumnNames(sql) {
|
|
|
108
109
|
}
|
|
109
110
|
cur += ch;
|
|
110
111
|
}
|
|
111
|
-
if (cur.trim()) defs.push(cur.trim());
|
|
112
|
+
/* c8 ignore next */ if (cur.trim()) defs.push(cur.trim());
|
|
112
113
|
return defs.map((def) => def.match(/^["'`]?(\w+)["'`]?/)?.[1] ?? "").filter((name) => name && !/^(CONSTRAINT|PRIMARY|UNIQUE|CHECK|FOREIGN)/i.test(name));
|
|
113
114
|
}
|
|
114
115
|
var MAGIC = "SQLite format 3\0";
|
|
@@ -120,12 +121,12 @@ function readTable(db, tableName) {
|
|
|
120
121
|
let rootPage = null;
|
|
121
122
|
let columnSql = null;
|
|
122
123
|
for (const row of master) if (row[0] === "table" && row[1] === tableName) {
|
|
123
|
-
rootPage = typeof row[3] === "number" ? row[3] : null;
|
|
124
|
-
columnSql = typeof row[4] === "string" ? row[4] : null;
|
|
124
|
+
rootPage = typeof row[3] === "number" ? row[3] : /* c8 ignore next */ null;
|
|
125
|
+
columnSql = typeof row[4] === "string" ? row[4] : /* c8 ignore next */ null;
|
|
125
126
|
break;
|
|
126
127
|
}
|
|
127
128
|
if (rootPage === null) return [];
|
|
128
|
-
const columns = columnSql ? parseColumnNames(columnSql) : [];
|
|
129
|
+
const columns = columnSql ? parseColumnNames(columnSql) : /* c8 ignore next */ [];
|
|
129
130
|
return traverseTable(db, rootPage, pageSize).map((row) => Object.fromEntries(columns.map((col, i) => [col, row[i] ?? null])));
|
|
130
131
|
}
|
|
131
132
|
//#endregion
|