@possumtech/sqlrite 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -183,3 +183,5 @@ const sql = new SqlRite({ path: "path/to/your/database.sqlite3" });
183
183
 
184
184
  Additional arguments will be passed to the options object of the native sqlite
185
185
  module.
186
+
187
+ To close the database connection, call the `.close()` method:
package/SqlRite.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { Database, DatabaseSync, Statement } from 'node:sqlite';
2
+
3
+ interface SqlRiteOptions {
4
+ path?: string;
5
+ dir?: string;
6
+ }
7
+
8
+ interface SqlRiteAsyncPreparedStatements {
9
+ all: (params?: Record<string, any>) => Promise<any[]>;
10
+ get: (params?: Record<string, any>) => Promise<any>;
11
+ run: (params?: Record<string, any>) => Promise<void>;
12
+ }
13
+
14
+ interface SqlRiteAsyncMethods {
15
+ [key: string]: (() => Promise<void>) | SqlRiteAsyncPreparedStatements;
16
+ }
17
+
18
+ export default class SqlRite {
19
+ constructor(options?: SqlRiteOptions);
20
+ async: SqlRiteAsyncMethods;
21
+ [key: string]: (() => void) | Statement | SqlRiteAsyncMethods | any;
22
+ }
package/SqlRite.js CHANGED
@@ -12,6 +12,8 @@ export default class SqlRite {
12
12
 
13
13
  const db = new DatabaseSync(merged.path, merged);
14
14
 
15
+ this.close = () => db.close();
16
+
15
17
  // allow multiple directories
16
18
  if (!Array.isArray(merged.dir)) merged.dir = [merged.dir];
17
19
  const files = merged.dir.flatMap((d) => this.getFiles(d));
@@ -45,18 +47,26 @@ export default class SqlRite {
45
47
  });
46
48
 
47
49
  prepChunks.forEach((prep) => {
48
- this[prep.name] = db.prepare(prep.sql);
50
+ const stmt = db.prepare(prep.sql);
51
+ this[prep.name] = {};
52
+
53
+ this[prep.name].all = (params = {}) => stmt.all(this.doJsonify(params));
54
+ this[prep.name].get = (params = {}) => stmt.get(this.doJsonify(params));
55
+ this[prep.name].run = (params = {}) => stmt.run(this.doJsonify(params));
49
56
 
50
57
  this.async[prep.name] = {};
51
58
 
52
- this.async[prep.name].all = async (params = {}) =>
53
- this[prep.name].all(params);
59
+ this.async[prep.name].all = async (params = {}) => {
60
+ return stmt.all(this.doJsonify(params));
61
+ };
54
62
 
55
- this.async[prep.name].get = async (params = {}) =>
56
- this[prep.name].get(params);
63
+ this.async[prep.name].get = async (params = {}) => {
64
+ return stmt.get(this.doJsonify(params));
65
+ };
57
66
 
58
- this.async[prep.name].run = async (params = {}) =>
59
- this[prep.name].run(params);
67
+ this.async[prep.name].run = async (params = {}) => {
68
+ return stmt.run(this.doJsonify(params));
69
+ };
60
70
  });
61
71
  }
62
72
 
@@ -72,4 +82,14 @@ export default class SqlRite {
72
82
 
73
83
  return files.sort();
74
84
  }
85
+
86
+ doJsonify(params) {
87
+ for (const param in params) {
88
+ if (Array.isArray(params[param])) {
89
+ params[param] = JSON.stringify(params[param]);
90
+ }
91
+ }
92
+
93
+ return params;
94
+ }
75
95
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@possumtech/sqlrite",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "SQL Done Right",
5
5
  "keywords": [
6
6
  "node",
@@ -22,7 +22,8 @@
22
22
  "type": "module",
23
23
  "main": "SqlRite.js",
24
24
  "scripts": {
25
- "syntax": "npx @biomejs/biome check",
26
- "test": "node --test"
25
+ "lint": "npx @biomejs/biome check *.js",
26
+ "test": "node --experimental-test-coverage --inspect --test",
27
+ "debug": "node --experimental-test-coverage --inspect-brk --test"
27
28
  }
28
29
  }
package/sql/test.sql CHANGED
@@ -26,3 +26,10 @@ SELECT name, position FROM employees;
26
26
 
27
27
  -- PREP: getHighestPaidEmployee
28
28
  SELECT name FROM employees ORDER BY salary DESC LIMIT 1;
29
+
30
+ -- PREP: getMultiEmployees
31
+ SELECT name, position, salary FROM
32
+ employees WHERE name IN (SELECT value FROM json_each($names));
33
+
34
+ -- PREP: deleteEmployees
35
+ DELETE FROM employees WHERE name IN (SELECT value FROM json_each($names));
package/test/test.js CHANGED
@@ -1,19 +1,58 @@
1
1
  import assert from "node:assert";
2
+ import test from "node:test";
2
3
  import SqlRite from "../SqlRite.js";
3
4
 
4
- const sql = new SqlRite();
5
+ test("SqlRite.js", (t) => {
6
+ t.test("constructor()", () => {
7
+ const sql = new SqlRite();
8
+ assert(sql instanceof SqlRite, "sql is an instance of SqlRite");
9
+ });
5
10
 
6
- sql.addEmployee.run({ name: "John", position: "CEO", salary: 99999 });
7
- sql.addEmployee.run({ name: "Jane", position: "COO", salary: 49998 });
8
- sql.addEmployee.run({ name: "Jack", position: "CFO", salary: 49997 });
9
- sql.addEmployee.run({ name: "Jill", position: "CIO", salary: 49996 });
11
+ const sql = new SqlRite();
10
12
 
11
- const employee = sql.getHighestPaidEmployee.get();
13
+ t.test("run()", () => {
14
+ sql.addEmployee.run({ name: "John", position: "CEO", salary: 99999 });
15
+ sql.addEmployee.run({ name: "Jane", position: "COO", salary: 49998 });
16
+ sql.addEmployee.run({ name: "Jack", position: "CFO", salary: 49997 });
17
+ sql.addEmployee.run({ name: "Jill", position: "CIO", salary: 49996 });
18
+ });
12
19
 
13
- assert(employee?.name === "John", "The highest paid employee should be John");
20
+ t.test("get()", () => {
21
+ const employee = sql.getHighestPaidEmployee.get();
22
+ assert(employee?.name === "John", "Highest paid employee should be John");
23
+ });
14
24
 
15
- sql.async.getPositions.all().then((positions) => console.log(positions));
25
+ t.test("all()", () => {
26
+ const positionsSync = sql.getPositions.all();
27
+ assert(positionsSync.length === 4, "There should be four positions");
28
+ });
16
29
 
17
- console.log(`The highest paid employee is ${employee.name}.`);
30
+ t.test("async", async () => {
31
+ const positionsAsync = await sql.async.getPositions.all();
32
+ assert(positionsAsync.length === 4, "There should be four positions");
33
+ });
18
34
 
19
- sql.deleteTable();
35
+ t.test("json_each operations", () => {
36
+ sql.deleteEmployees.run({ names: ["Jane", "Jack"] });
37
+ const remaining = sql.getPositions.all();
38
+ assert(remaining.length === 2, "There should be two employees remaining");
39
+ });
40
+
41
+ t.test("exec operations", () => {
42
+ sql.deleteTable();
43
+ });
44
+
45
+ t.test("getFiles()", () => {
46
+ const files = sql.getFiles("sql");
47
+
48
+ assert(files.length > 0, "At least one SQL file in the sql directory?");
49
+ });
50
+
51
+ t.test("close()", () => {
52
+ const sql = new SqlRite();
53
+
54
+ sql.close();
55
+
56
+ assert(true, "Database closed without error");
57
+ });
58
+ });