@xnetjs/sqlite 0.1.0 → 0.1.1
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/index.d.ts +3 -2
- package/dist/index.js +59 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -163,8 +163,9 @@ interface SQLiteRuntimeCapabilities {
|
|
|
163
163
|
/**
|
|
164
164
|
* Get information about all indexes in the database. Cached per adapter and keyed
|
|
165
165
|
* on `PRAGMA schema_version`, so repeated calls between DDL changes pay one cheap
|
|
166
|
-
* version probe instead of
|
|
167
|
-
*
|
|
166
|
+
* version probe instead of a rebuild (exploration 0253). Concurrent callers share
|
|
167
|
+
* a single in-flight probe+build, and a cold build is a single batched statement
|
|
168
|
+
* — worst case one diagnostic run costs 2 worker round-trips, not 1 + 1 + N.
|
|
168
169
|
*/
|
|
169
170
|
declare function getIndexInfo(db: SQLiteAdapter): Promise<IndexInfo[]>;
|
|
170
171
|
/**
|
package/dist/index.js
CHANGED
|
@@ -79,12 +79,35 @@ async function readSchemaVersion(db) {
|
|
|
79
79
|
return 0;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
async function
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
async function fetchIndexInfoBatched(db) {
|
|
83
|
+
const rows = await db.query(
|
|
84
|
+
`SELECT m.name AS index_name, m.tbl_name AS table_name, m.sql AS index_sql,
|
|
85
|
+
ii.seqno AS seqno, ii.name AS column_name
|
|
86
|
+
FROM sqlite_master AS m
|
|
87
|
+
LEFT JOIN pragma_index_info(m.name) AS ii
|
|
88
|
+
WHERE m.type = 'index' AND m.name NOT LIKE 'sqlite_%'
|
|
89
|
+
ORDER BY m.name, ii.seqno`
|
|
90
|
+
);
|
|
91
|
+
const byName = /* @__PURE__ */ new Map();
|
|
92
|
+
for (const row of rows) {
|
|
93
|
+
let info = byName.get(row.index_name);
|
|
94
|
+
if (!info) {
|
|
95
|
+
info = {
|
|
96
|
+
name: row.index_name,
|
|
97
|
+
tableName: row.table_name,
|
|
98
|
+
unique: row.index_sql?.includes("UNIQUE") ?? false,
|
|
99
|
+
columns: [],
|
|
100
|
+
partial: row.index_sql?.includes("WHERE") ?? false
|
|
101
|
+
};
|
|
102
|
+
byName.set(row.index_name, info);
|
|
103
|
+
}
|
|
104
|
+
if (row.seqno !== null) {
|
|
105
|
+
info.columns.push(row.column_name);
|
|
106
|
+
}
|
|
87
107
|
}
|
|
108
|
+
return [...byName.values()];
|
|
109
|
+
}
|
|
110
|
+
async function fetchIndexInfoPerIndex(db) {
|
|
88
111
|
const indexes = await db.query(
|
|
89
112
|
"SELECT name, tbl_name, sql FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%'"
|
|
90
113
|
);
|
|
@@ -99,9 +122,39 @@ async function getIndexInfo(db) {
|
|
|
99
122
|
partial: idx.sql?.includes("WHERE") ?? false
|
|
100
123
|
});
|
|
101
124
|
}
|
|
102
|
-
indexInfoCache.set(db, { schemaVersion, indexes: result });
|
|
103
125
|
return result;
|
|
104
126
|
}
|
|
127
|
+
async function getIndexInfo(db) {
|
|
128
|
+
let entry = indexInfoCache.get(db);
|
|
129
|
+
if (!entry) {
|
|
130
|
+
entry = {};
|
|
131
|
+
indexInfoCache.set(db, entry);
|
|
132
|
+
}
|
|
133
|
+
if (entry.inFlight) {
|
|
134
|
+
return entry.inFlight;
|
|
135
|
+
}
|
|
136
|
+
const cacheEntry = entry;
|
|
137
|
+
const inFlight = (async () => {
|
|
138
|
+
const schemaVersion = await readSchemaVersion(db);
|
|
139
|
+
if (cacheEntry.resolved && cacheEntry.resolved.schemaVersion === schemaVersion) {
|
|
140
|
+
return cacheEntry.resolved.indexes;
|
|
141
|
+
}
|
|
142
|
+
let indexes;
|
|
143
|
+
try {
|
|
144
|
+
indexes = await fetchIndexInfoBatched(db);
|
|
145
|
+
} catch {
|
|
146
|
+
indexes = await fetchIndexInfoPerIndex(db);
|
|
147
|
+
}
|
|
148
|
+
cacheEntry.resolved = { schemaVersion, indexes };
|
|
149
|
+
return indexes;
|
|
150
|
+
})();
|
|
151
|
+
entry.inFlight = inFlight;
|
|
152
|
+
try {
|
|
153
|
+
return await inFlight;
|
|
154
|
+
} finally {
|
|
155
|
+
cacheEntry.inFlight = void 0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
105
158
|
async function analyzeQuery(db, sql, params) {
|
|
106
159
|
const plan = await db.query(`EXPLAIN QUERY PLAN ${sql}`, params);
|
|
107
160
|
const steps = plan.map((row) => ({
|