@nuxodin/item 0.6.18 → 0.6.19
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
CHANGED
|
@@ -40,10 +40,7 @@ function secondaryIndexKind(prop) {
|
|
|
40
40
|
|
|
41
41
|
function usableIndexKind(table, name, prop) {
|
|
42
42
|
const kind = secondaryIndexKind(prop);
|
|
43
|
-
|
|
44
|
-
if (!issue) return kind;
|
|
45
|
-
console.warn(issue);
|
|
46
|
-
return null;
|
|
43
|
+
return kind && !indexIssue(table, name, prop, kind) ? kind : null;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
function indexIssue(table, name, prop, kind) {
|
|
@@ -109,6 +106,7 @@ export async function schemaToDb(
|
|
|
109
106
|
}
|
|
110
107
|
|
|
111
108
|
const stmts = [];
|
|
109
|
+
const warnings = [];
|
|
112
110
|
const nextTables = Object.keys(schema.properties ?? {});
|
|
113
111
|
const currTables = Object.keys(current.properties ?? {});
|
|
114
112
|
|
|
@@ -117,6 +115,11 @@ export async function schemaToDb(
|
|
|
117
115
|
const { fields, required } = tableData(schema.properties[table]);
|
|
118
116
|
const primaries = primaryFields(fields);
|
|
119
117
|
for (const p of primaries) required.add(p); // primary key columns are always NOT NULL
|
|
118
|
+
for (const [n, f] of fields) {
|
|
119
|
+
const kind = secondaryIndexKind(f);
|
|
120
|
+
const issue = kind && indexIssue(table, n, f, kind);
|
|
121
|
+
if (issue) warnings.push(issue); // the index is left out
|
|
122
|
+
}
|
|
120
123
|
|
|
121
124
|
if (!currTables.includes(table)) {
|
|
122
125
|
const cols = fields.map(([n, f]) =>
|
|
@@ -196,11 +199,8 @@ export async function schemaToDb(
|
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
|
|
199
|
-
for (const stmt of stmts)
|
|
200
|
-
|
|
201
|
-
await query(stmt);
|
|
202
|
-
}
|
|
203
|
-
return { diffs, executed: stmts };
|
|
202
|
+
for (const stmt of stmts) await query(stmt);
|
|
203
|
+
return { diffs, executed: stmts, warnings };
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
async function indexStatements(query, table, nextFields, currFields, { patch = false } = {}) {
|
|
@@ -32,13 +32,11 @@ function preserveDefault(prop, currProp) {
|
|
|
32
32
|
: { ...prop, default: currProp.default }
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function secondaryIndexKind(
|
|
35
|
+
function secondaryIndexKind(prop) {
|
|
36
36
|
// hnsw needs a fixed length and an operator class; the application builds vector indexes
|
|
37
37
|
if (prop['x-vector']) return null
|
|
38
38
|
if (prop['x-index'] === 'unique') return 'UNIQUE INDEX'
|
|
39
39
|
if (prop['x-index'] === true) return 'INDEX'
|
|
40
|
-
if (prop['x-index'] === 'fulltext')
|
|
41
|
-
console.warn(`Skip FULLTEXT INDEX ${table}.${name}: PostgreSQL fulltext requires an expression index`)
|
|
42
40
|
return null
|
|
43
41
|
}
|
|
44
42
|
|
|
@@ -114,6 +112,7 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
const stmts = []
|
|
115
|
+
const warnings = []
|
|
117
116
|
const nextTables = Object.keys(schema.properties ?? {})
|
|
118
117
|
const currTables = Object.keys(current.properties ?? {})
|
|
119
118
|
|
|
@@ -122,6 +121,10 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
122
121
|
const { fields, required } = tableData(schema.properties[table])
|
|
123
122
|
const primaries = primaryFields(fields)
|
|
124
123
|
for (const p of primaries) required.add(p)
|
|
124
|
+
for (const [n, f] of fields) {
|
|
125
|
+
if (f['x-index'] === 'fulltext' && !f['x-vector'])
|
|
126
|
+
warnings.push(`Skip FULLTEXT INDEX ${table}.${n}: PostgreSQL fulltext requires an expression index`)
|
|
127
|
+
}
|
|
125
128
|
|
|
126
129
|
if (!currTables.includes(table)) {
|
|
127
130
|
const cols = fields.map(([n, f]) =>
|
|
@@ -135,7 +138,7 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
135
138
|
for (const [n, f] of fields) if (f['$comment']) stmts.push(commentStmt(table, n, f['$comment']))
|
|
136
139
|
for (const [n, f] of fields) {
|
|
137
140
|
if (primarySet.has(n)) continue
|
|
138
|
-
const kind = secondaryIndexKind(
|
|
141
|
+
const kind = secondaryIndexKind(f)
|
|
139
142
|
if (kind) stmts.push(createIndex(table, n, kind))
|
|
140
143
|
}
|
|
141
144
|
} else {
|
|
@@ -177,11 +180,8 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
177
180
|
const vectors = nextTables.some(t => tableData(schema.properties[t]).fields.some(([, f]) => f['x-vector']))
|
|
178
181
|
if (vectors && stmts.length) stmts.unshift('CREATE EXTENSION IF NOT EXISTS vector;')
|
|
179
182
|
|
|
180
|
-
for (const stmt of stmts)
|
|
181
|
-
|
|
182
|
-
await query(stmt)
|
|
183
|
-
}
|
|
184
|
-
return { diffs, executed: stmts }
|
|
183
|
+
for (const stmt of stmts) await query(stmt)
|
|
184
|
+
return { diffs, executed: stmts, warnings }
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
async function indexStatements(query, table, nextFields, currFields, { patch = false } = {}) {
|
|
@@ -198,7 +198,7 @@ async function indexStatements(query, table, nextFields, currFields, { patch = f
|
|
|
198
198
|
|
|
199
199
|
for (const [name, prop] of nextFields) {
|
|
200
200
|
if (nextPrimary.has(name)) continue
|
|
201
|
-
const nextKind = secondaryIndexKind(
|
|
201
|
+
const nextKind = secondaryIndexKind(prop)
|
|
202
202
|
const curr = indexes.secondary.find(i => i.column === name)
|
|
203
203
|
const currKind = curr ? curr.unique ? 'UNIQUE INDEX' : 'INDEX' : null
|
|
204
204
|
const changed = curr && currKind !== nextKind
|
|
@@ -209,7 +209,7 @@ async function indexStatements(query, table, nextFields, currFields, { patch = f
|
|
|
209
209
|
|
|
210
210
|
if (!patch) {
|
|
211
211
|
for (const curr of indexes.secondary) {
|
|
212
|
-
const wanted = nextFields.find(([name, prop]) => name === curr.column && secondaryIndexKind(
|
|
212
|
+
const wanted = nextFields.find(([name, prop]) => name === curr.column && secondaryIndexKind(prop))
|
|
213
213
|
if (!wanted) before.push(`DROP INDEX ${quoteId(curr.key)};`)
|
|
214
214
|
}
|
|
215
215
|
}
|
|
@@ -34,8 +34,6 @@ function createBody(table, fields, primaries) {
|
|
|
34
34
|
const solo = soloIntPrimary(fields, primaries)
|
|
35
35
|
const cols = fields.map(([n, f]) => {
|
|
36
36
|
const isPk = n === solo
|
|
37
|
-
if (f['x-autoincrement'] && !isPk)
|
|
38
|
-
console.warn(`Skip AUTOINCREMENT ${table}.${n}: SQLite auto-increments only a sole INTEGER PRIMARY KEY — nothing fills this column`)
|
|
39
37
|
// Only `INTEGER PRIMARY KEY` is the rowid alias, and AUTOINCREMENT is legal nowhere else —
|
|
40
38
|
// so a boolean key keeps the integer spelling, which SQLite would otherwise reject.
|
|
41
39
|
let def = toFieldDef(n, isPk ? { ...f, type: 'integer' } : f)
|
|
@@ -50,11 +48,17 @@ function indexKind(table, name, prop) {
|
|
|
50
48
|
if (prop['x-vector']) return null // sqlite-vec scans; a B-tree over vectors helps nothing
|
|
51
49
|
if (prop['x-index'] === 'unique') return 'UNIQUE INDEX'
|
|
52
50
|
if (prop['x-index'] === true) return 'INDEX'
|
|
53
|
-
if (prop['x-index'] === 'fulltext')
|
|
54
|
-
console.warn(`Skip FULLTEXT INDEX ${table}.${name}: SQLite fulltext requires a virtual FTS table`)
|
|
55
51
|
return null
|
|
56
52
|
}
|
|
57
53
|
|
|
54
|
+
/** What the schema asks of a field that SQLite cannot do; the field is created without it. */
|
|
55
|
+
function fieldWarning(table, name, prop, solo) {
|
|
56
|
+
if (prop['x-autoincrement'] && name !== solo)
|
|
57
|
+
return `Skip AUTOINCREMENT ${table}.${name}: SQLite auto-increments only a sole INTEGER PRIMARY KEY — nothing fills this column`
|
|
58
|
+
if (prop['x-index'] === 'fulltext' && !prop['x-vector'])
|
|
59
|
+
return `Skip FULLTEXT INDEX ${table}.${name}: SQLite fulltext requires a virtual FTS table`
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
function createIndex(table, name, kind) {
|
|
59
63
|
return `CREATE ${kind} ${quoteId(indexName(table, name))} ON ${quoteId(table)} (${quoteId(name)});`
|
|
60
64
|
}
|
|
@@ -94,12 +98,18 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
const stmts = []
|
|
101
|
+
const warnings = []
|
|
97
102
|
const nextTables = Object.keys(schema.properties ?? {})
|
|
98
103
|
const currTables = Object.keys(current.properties ?? {})
|
|
99
104
|
|
|
100
105
|
for (const table of nextTables) {
|
|
101
106
|
const fields = tableFields(schema.properties[table])
|
|
102
107
|
const primaries = fields.filter(([, f]) => f['x-index'] === 'primary').map(([n]) => n)
|
|
108
|
+
const solo = soloIntPrimary(fields, primaries)
|
|
109
|
+
for (const [n, f] of fields) {
|
|
110
|
+
const warning = fieldWarning(table, n, f, solo)
|
|
111
|
+
if (warning) warnings.push(warning)
|
|
112
|
+
}
|
|
103
113
|
|
|
104
114
|
if (!currTables.includes(table)) {
|
|
105
115
|
// Idea: WITHOUT ROWID when the primary key is not a single integer column and all other columns
|
|
@@ -144,9 +154,6 @@ export async function schemaToDb(schema, query, { force = false, patch = false }
|
|
|
144
154
|
}
|
|
145
155
|
}
|
|
146
156
|
|
|
147
|
-
for (const stmt of stmts)
|
|
148
|
-
|
|
149
|
-
await query(stmt)
|
|
150
|
-
}
|
|
151
|
-
return { diffs, executed: stmts }
|
|
157
|
+
for (const stmt of stmts) await query(stmt)
|
|
158
|
+
return { diffs, executed: stmts, warnings }
|
|
152
159
|
}
|