1.1.0
This commit is contained in:
parent
13c3d86a10
commit
20ac2da081
6 changed files with 47 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@endeavorance/prequel",
|
"name": "@endeavorance/prequel",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -105,6 +105,8 @@ export class Prequel {
|
||||||
public db: Database;
|
public db: Database;
|
||||||
public kv: PrequelKVStore;
|
public kv: PrequelKVStore;
|
||||||
public tables: Record<string, Table<unknown>> = {};
|
public tables: Record<string, Table<unknown>> = {};
|
||||||
|
public query: typeof Database.prototype.query;
|
||||||
|
public uncachedQuery: typeof Database.prototype.prepare;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Prequel database instance.
|
* Creates a new Prequel database instance.
|
||||||
|
@ -112,6 +114,8 @@ export class Prequel {
|
||||||
*/
|
*/
|
||||||
constructor(filename = ":memory:") {
|
constructor(filename = ":memory:") {
|
||||||
this.db = new Database(filename);
|
this.db = new Database(filename);
|
||||||
|
this.query = this.db.query.bind(this.db);
|
||||||
|
this.uncachedQuery = this.db.prepare.bind(this.db);
|
||||||
this.db.exec("PRAGMA foreign_keys=ON");
|
this.db.exec("PRAGMA foreign_keys=ON");
|
||||||
this.kv = new PrequelKVStore(this, "PrequelManagedKVStore");
|
this.kv = new PrequelKVStore(this, "PrequelManagedKVStore");
|
||||||
}
|
}
|
||||||
|
|
17
src/table.ts
17
src/table.ts
|
@ -27,12 +27,10 @@ export class PrequelEmptyResultsError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An arbitrarily shaped Row */
|
/** An arbitrarily shaped Row */
|
||||||
interface ArbitraryRow {
|
type ArbitraryRow = Record<string, ColumnValue>;
|
||||||
[key: string]: ColumnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
function shapeForQuery<T>(obj: Partial<T>): Record<string, ColumnValue> {
|
function shapeForQuery<T>(obj: Partial<T>): ArbitraryRow {
|
||||||
const asInsertDataShape: Record<string, ColumnValue> = {};
|
const asInsertDataShape: ArbitraryRow = {};
|
||||||
|
|
||||||
const keys = Object.keys(obj);
|
const keys = Object.keys(obj);
|
||||||
|
|
||||||
|
@ -72,6 +70,8 @@ export class Table<RowShape> {
|
||||||
private _sizeQuery: Statement<{ count: number }, []>;
|
private _sizeQuery: Statement<{ count: number }, []>;
|
||||||
private _truncateQuery: Statement<void, []>;
|
private _truncateQuery: Statement<void, []>;
|
||||||
|
|
||||||
|
public query: typeof Database.prototype.query;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
db: Database | Prequel,
|
db: Database | Prequel,
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -85,6 +85,7 @@ export class Table<RowShape> {
|
||||||
this._name = name;
|
this._name = name;
|
||||||
this._columnDefinitions = normalizeColumns(cols);
|
this._columnDefinitions = normalizeColumns(cols);
|
||||||
this._columnNames = Object.keys(this._columnDefinitions);
|
this._columnNames = Object.keys(this._columnDefinitions);
|
||||||
|
this.query = this._db.query.bind(this._db);
|
||||||
|
|
||||||
const columnSQLParts: string[] = [];
|
const columnSQLParts: string[] = [];
|
||||||
const updateColumnSQLParts: string[] = [];
|
const updateColumnSQLParts: string[] = [];
|
||||||
|
@ -211,6 +212,12 @@ export class Table<RowShape> {
|
||||||
return query.get(asInsertDataShape) as RowShape;
|
return query.get(asInsertDataShape) as RowShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public insertWithout<OmitKeys extends keyof RowShape>(
|
||||||
|
rowWithKeysOmitted: Omit<RowShape, OmitKeys>,
|
||||||
|
): RowShape {
|
||||||
|
return this.insertPartial(rowWithKeysOmitted as Partial<RowShape>);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a row in the table with the provided data.
|
* Updates a row in the table with the provided data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -135,3 +135,11 @@ test("kv store can set and retrieve arbitrary values", () => {
|
||||||
expect(pq.kv.get<{ enabled: boolean }>("config")).toEqual({ enabled: true });
|
expect(pq.kv.get<{ enabled: boolean }>("config")).toEqual({ enabled: true });
|
||||||
expect(pq.kv.get<string[]>("list")).toEqual(["a", "b", "c"]);
|
expect(pq.kv.get<string[]>("list")).toEqual(["a", "b", "c"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(".query() creates a cached statement", () => {
|
||||||
|
const pq = new Prequel();
|
||||||
|
const query = pq.query("SELECT 1");
|
||||||
|
|
||||||
|
expect(query).toBeDefined();
|
||||||
|
expect(query).toBe(pq.query("SELECT 1"));
|
||||||
|
});
|
||||||
|
|
|
@ -138,6 +138,22 @@ test(".insertPartial() inserts a partial row", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(".insertWithout() inserts a partial row with type safety", () => {
|
||||||
|
const table = makeTestTable();
|
||||||
|
table.insertWithout<"user_id">({
|
||||||
|
name: "Jack",
|
||||||
|
});
|
||||||
|
|
||||||
|
const lookup = table.db.prepare<UserWithID, string>(
|
||||||
|
`SELECT * FROM ${table} WHERE name = ?`,
|
||||||
|
);
|
||||||
|
const found = lookup.get("Jack");
|
||||||
|
expect(found).toEqual({
|
||||||
|
user_id: 1,
|
||||||
|
name: "Jack",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test(".count() gets the current number of rows in the table", () => {
|
test(".count() gets the current number of rows in the table", () => {
|
||||||
const table = makeTestTable();
|
const table = makeTestTable();
|
||||||
table.insertPartial({ name: "Jack" });
|
table.insertPartial({ name: "Jack" });
|
||||||
|
@ -167,6 +183,12 @@ test(".findAll() returns the full table", () => {
|
||||||
expect(allUsers[2]).toEqual({ user_id: 3, name: "Sayid" });
|
expect(allUsers[2]).toEqual({ user_id: 3, name: "Sayid" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(".query() returns a prepared statement for the table", () => {
|
||||||
|
const table = makeTestTable();
|
||||||
|
const query = table.query("SELECT * FROM Users WHERE name = ?");
|
||||||
|
expect(query).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
test(".findOneWhere() returns a row based on basic criteria", () => {
|
test(".findOneWhere() returns a row based on basic criteria", () => {
|
||||||
const table = makeTestTable();
|
const table = makeTestTable();
|
||||||
table.insertPartial({ name: "Jack" });
|
table.insertPartial({ name: "Jack" });
|
||||||
|
|
|
@ -7,10 +7,6 @@ interface User {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SerializedUser {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const db = new Database();
|
const db = new Database();
|
||||||
const table = new Table<User>(db, "Users", {
|
const table = new Table<User>(db, "Users", {
|
||||||
id: {
|
id: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue