@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxodin/item",
3
- "version": "0.6.18",
3
+ "version": "0.6.19",
4
4
  "description": "Reactive state library",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,10 +40,7 @@ function secondaryIndexKind(prop) {
40
40
 
41
41
  function usableIndexKind(table, name, prop) {
42
42
  const kind = secondaryIndexKind(prop);
43
- const issue = kind && indexIssue(table, name, prop, kind);
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
- console.log(stmt);
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(table, name, prop) {
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(table, n, f)
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
- console.log(stmt)
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(table, name, prop)
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(table, name, prop))
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
- console.log(stmt)
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
  }