@crvouga/sqlite-mem 1.6.0 → 1.8.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/COMPATIBILITY-AUDIT.md +41 -16
- package/dist/ast/nodes.d.ts +5 -0
- package/dist/index.js +312 -181
- package/dist/index.js.map +2 -2
- package/dist/unstable.js +47 -20
- package/dist/unstable.js.map +2 -2
- package/package.json +3 -2
package/dist/unstable.js
CHANGED
|
@@ -99,32 +99,46 @@ function applyAffinity(value, affinity) {
|
|
|
99
99
|
if (value === null) return null;
|
|
100
100
|
switch (affinity) {
|
|
101
101
|
case "TEXT":
|
|
102
|
-
if (value instanceof Uint8Array) return
|
|
102
|
+
if (value instanceof Uint8Array) return value;
|
|
103
103
|
if (value instanceof SqlJsonText) return value.value;
|
|
104
104
|
if (typeof value === "string") return value;
|
|
105
|
-
if (value instanceof SqlReal) return
|
|
105
|
+
if (value instanceof SqlReal) return formatRealAsText(value.value);
|
|
106
|
+
if (typeof value === "number") return String(canonicalizeNumber(value));
|
|
107
|
+
if (typeof value === "bigint") return value.toString();
|
|
106
108
|
return String(value);
|
|
107
109
|
case "INTEGER": {
|
|
110
|
+
if (value instanceof Uint8Array) return value;
|
|
108
111
|
const n = coerceToNumber(value);
|
|
109
112
|
if (n === null) return value;
|
|
110
113
|
if (typeof value === "bigint") return value;
|
|
111
114
|
return Number.isInteger(n) && Number.isSafeInteger(n) ? Math.trunc(n) : canonicalizeNumber(n);
|
|
112
115
|
}
|
|
113
116
|
case "REAL": {
|
|
117
|
+
if (value instanceof Uint8Array) return value;
|
|
114
118
|
const n = coerceToNumber(value);
|
|
115
119
|
return n === null ? value : asSqlReal(n);
|
|
116
120
|
}
|
|
117
121
|
case "NUMERIC": {
|
|
122
|
+
if (value instanceof Uint8Array) return value;
|
|
118
123
|
const n = coerceToNumber(value);
|
|
119
124
|
if (n === null) return value;
|
|
120
125
|
if (Number.isInteger(n) && Number.isSafeInteger(n)) return Math.trunc(n);
|
|
121
126
|
return canonicalizeNumber(n);
|
|
122
127
|
}
|
|
123
128
|
case "BLOB":
|
|
124
|
-
if (typeof value === "number") return canonicalizeNumber(value);
|
|
125
129
|
return value;
|
|
126
130
|
}
|
|
127
131
|
}
|
|
132
|
+
function formatRealAsText(value) {
|
|
133
|
+
const n = canonicalizeNumber(value);
|
|
134
|
+
if (Object.is(n, -0) || n === 0) return "0.0";
|
|
135
|
+
if (Number.isInteger(n) && Number.isSafeInteger(n)) return `${n}.0`;
|
|
136
|
+
const abs = Math.abs(n);
|
|
137
|
+
if (abs >= 1e16 || abs > 0 && abs < 1e-4) {
|
|
138
|
+
return n.toExponential(1).replace(/e([+-])(\d)$/, "e$10$2").replace(/e\+/, "e+");
|
|
139
|
+
}
|
|
140
|
+
return String(n);
|
|
141
|
+
}
|
|
128
142
|
function applyComparisonAffinity(left, right, leftAffinity, rightAffinity) {
|
|
129
143
|
const leftNumeric = leftAffinity === "INTEGER" || leftAffinity === "REAL" || leftAffinity === "NUMERIC";
|
|
130
144
|
const rightNumeric = rightAffinity === "INTEGER" || rightAffinity === "REAL" || rightAffinity === "NUMERIC";
|
|
@@ -3176,8 +3190,14 @@ function evalExpr(expr, ctx) {
|
|
|
3176
3190
|
return truth === null ? null : booleanValue(!truth);
|
|
3177
3191
|
}
|
|
3178
3192
|
if (value === null) return null;
|
|
3179
|
-
if (expr.op === "+")
|
|
3180
|
-
|
|
3193
|
+
if (expr.op === "+") {
|
|
3194
|
+
const n = asNumber(numberValue(value));
|
|
3195
|
+
return storageClassOf(value) === "real" ? asSqlReal(n) : n;
|
|
3196
|
+
}
|
|
3197
|
+
if (expr.op === "-") {
|
|
3198
|
+
const n = asNumber(-numberValue(value));
|
|
3199
|
+
return storageClassOf(value) === "real" ? asSqlReal(n) : n;
|
|
3200
|
+
}
|
|
3181
3201
|
return ~integerValue(value);
|
|
3182
3202
|
}
|
|
3183
3203
|
case "is_bool": {
|
|
@@ -4317,7 +4337,7 @@ var Parser = class {
|
|
|
4317
4337
|
if (this.at("SELECT") || this.at("WITH") || this.at("VALUES")) {
|
|
4318
4338
|
const select = this.at("SELECT") || this.at("WITH") ? this.parseSelectStmt() : this.parseValuesAsSelect();
|
|
4319
4339
|
this.expect("RPAREN");
|
|
4320
|
-
const alias3 = this.optionalAlias() ?? this.
|
|
4340
|
+
const alias3 = this.optionalAlias() ?? `__subq_${this.pos}`;
|
|
4321
4341
|
return { type: "subquery", select, alias: alias3 };
|
|
4322
4342
|
}
|
|
4323
4343
|
const item = this.parseFromItem();
|
|
@@ -4544,13 +4564,15 @@ var Parser = class {
|
|
|
4544
4564
|
// ── DELETE ──────────────────────────────────────────────────────────────
|
|
4545
4565
|
parseDeleteStmt(withClause = this.parseOptionalWith()) {
|
|
4546
4566
|
this.expect("DELETE");
|
|
4567
|
+
const or = this.parseOrConflict();
|
|
4547
4568
|
this.expect("FROM");
|
|
4548
4569
|
const table = this.parseTableName();
|
|
4549
4570
|
const alias = this.optionalAlias();
|
|
4550
4571
|
let where = null;
|
|
4551
4572
|
if (this.match("WHERE")) where = this.parseExpr();
|
|
4552
4573
|
const returning = this.parseReturning();
|
|
4553
|
-
|
|
4574
|
+
const orMode = or === null ? null : or === "REPLACE" ? "replace" : or === "IGNORE" ? "ignore" : or === "ABORT" ? "abort" : or === "ROLLBACK" ? "rollback" : "fail";
|
|
4575
|
+
return { type: "delete", with: withClause, or: orMode, table, alias, where, returning };
|
|
4554
4576
|
}
|
|
4555
4577
|
// ── CREATE ──────────────────────────────────────────────────────────────
|
|
4556
4578
|
parseCreateStmt() {
|
|
@@ -4839,9 +4861,9 @@ var Parser = class {
|
|
|
4839
4861
|
} while (this.match("COMMA"));
|
|
4840
4862
|
this.expect("RPAREN");
|
|
4841
4863
|
}
|
|
4842
|
-
const { onDelete, onUpdate } = this.parseFkActions();
|
|
4864
|
+
const { onDelete, onUpdate, match } = this.parseFkActions();
|
|
4843
4865
|
const { deferrable, initiallyDeferred } = this.parseDeferrable();
|
|
4844
|
-
return { type: "references", table, columns, onDelete, onUpdate, deferrable, initiallyDeferred };
|
|
4866
|
+
return { type: "references", table, columns, onDelete, onUpdate, match, deferrable, initiallyDeferred };
|
|
4845
4867
|
}
|
|
4846
4868
|
parseTableConstraint() {
|
|
4847
4869
|
let name = null;
|
|
@@ -4887,7 +4909,7 @@ var Parser = class {
|
|
|
4887
4909
|
} while (this.match("COMMA"));
|
|
4888
4910
|
this.expect("RPAREN");
|
|
4889
4911
|
}
|
|
4890
|
-
const { onDelete, onUpdate } = this.parseFkActions();
|
|
4912
|
+
const { onDelete, onUpdate, match } = this.parseFkActions();
|
|
4891
4913
|
const { deferrable, initiallyDeferred } = this.parseDeferrable();
|
|
4892
4914
|
return {
|
|
4893
4915
|
type: "foreign_key",
|
|
@@ -4896,6 +4918,7 @@ var Parser = class {
|
|
|
4896
4918
|
refColumns,
|
|
4897
4919
|
onDelete,
|
|
4898
4920
|
onUpdate,
|
|
4921
|
+
match,
|
|
4899
4922
|
name,
|
|
4900
4923
|
deferrable,
|
|
4901
4924
|
initiallyDeferred
|
|
@@ -4957,21 +4980,24 @@ var Parser = class {
|
|
|
4957
4980
|
parseFkActions() {
|
|
4958
4981
|
let onDelete = null;
|
|
4959
4982
|
let onUpdate = null;
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4983
|
+
let match = "SIMPLE";
|
|
4984
|
+
const readMatch = () => {
|
|
4985
|
+
while (this.match("MATCH")) {
|
|
4986
|
+
const word = this.parseIdent().toUpperCase();
|
|
4987
|
+
if (word === "FULL") match = "FULL";
|
|
4988
|
+
else if (word === "PARTIAL") match = "PARTIAL";
|
|
4989
|
+
else match = "SIMPLE";
|
|
4990
|
+
}
|
|
4991
|
+
};
|
|
4992
|
+
readMatch();
|
|
4963
4993
|
while (this.at("ON")) {
|
|
4964
4994
|
if (this.peek().kind === "DELETE") onDelete = this.parseFkAction("DELETE");
|
|
4965
4995
|
else if (this.peek().kind === "UPDATE") onUpdate = this.parseFkAction("UPDATE");
|
|
4966
4996
|
else this.syntaxError("expected ON DELETE or ON UPDATE");
|
|
4967
|
-
|
|
4968
|
-
this.parseIdent();
|
|
4969
|
-
}
|
|
4970
|
-
}
|
|
4971
|
-
while (this.match("MATCH")) {
|
|
4972
|
-
this.parseIdent();
|
|
4997
|
+
readMatch();
|
|
4973
4998
|
}
|
|
4974
|
-
|
|
4999
|
+
readMatch();
|
|
5000
|
+
return { onDelete, onUpdate, match };
|
|
4975
5001
|
}
|
|
4976
5002
|
parseDeferrable() {
|
|
4977
5003
|
let deferrable = false;
|
|
@@ -8265,6 +8291,7 @@ var DatabaseState = class _DatabaseState {
|
|
|
8265
8291
|
refColumns: constraint.columns,
|
|
8266
8292
|
onDelete: constraint.onDelete,
|
|
8267
8293
|
onUpdate: constraint.onUpdate,
|
|
8294
|
+
match: constraint.match,
|
|
8268
8295
|
name: null,
|
|
8269
8296
|
deferrable: constraint.deferrable,
|
|
8270
8297
|
initiallyDeferred: constraint.initiallyDeferred
|