@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/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 utf8Decode(value);
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 String(value.value);
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 === "+") return asNumber(numberValue(value));
3180
- if (expr.op === "-") return asNumber(-numberValue(value));
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.syntaxError("subquery in FROM requires an alias");
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
- return { type: "delete", with: withClause, table, alias, where, returning };
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
- while (this.match("MATCH")) {
4961
- this.parseIdent();
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
- while (this.match("MATCH")) {
4968
- this.parseIdent();
4969
- }
4970
- }
4971
- while (this.match("MATCH")) {
4972
- this.parseIdent();
4997
+ readMatch();
4973
4998
  }
4974
- return { onDelete, onUpdate };
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