UNPKG

@nivinjoseph/n-data

Version:

Data access library for Postgres based on Knex

505 lines (446 loc) 17.5 kB
import assert from "node:assert"; import test, { after, before, describe } from "node:test"; import { Db, DbConnectionConfig, DbConnectionFactory, KnexPgDb, KnexPgDbConnectionFactory, KnexPgUnitOfWork } from "../src/index.js"; await describe("Db tests", async () => { let dbConnectionFactory: DbConnectionFactory; let db: Db; before(async () => { const config: DbConnectionConfig = { host: "localhost", port: "5432", database: "testdb", username: "postgres", password: "p@ssw0rd" }; dbConnectionFactory = new KnexPgDbConnectionFactory(config); db = new KnexPgDb(dbConnectionFactory); }); after(async () => { await dbConnectionFactory.dispose(); }); await describe("Query tests", async () => { before(async () => { await db.executeCommand(` drop table if exists products; create table products( id int primary key, name varchar(10) ); insert into products(id, name) values(1, 'cheese'), (2, 'wine'); `); }); after(async () => { await db.executeCommand(`drop table if exists products`); }); await test("query should return multiple results", async () => { const result = await db.executeQuery(`select * from products`); assert.strictEqual(2, result.rows.length); assert.deepEqual(result.rows, [{ id: 1, name: "cheese" }, { id: 2, name: "wine" }]); }); await test("query with filter should return one result", async () => { const result = await db.executeQuery(`select * from products where id = ?`, 1); assert.strictEqual(1, result.rows.length); assert.deepEqual(result.rows, [{ id: 1, name: "cheese" }]); }); await test("query should return count", async () => { const result = await db.executeQuery<any>(`select cast(count(*) as int) from products`); assert.strictEqual(1, result.rows.length); assert.strictEqual(result.rows[0].count, 2); }); await test("query with in clause should return results", async () => { const result = await db.executeQuery(`select * from products where id in (?, ?)`, 1, 2); assert.strictEqual(2, result.rows.length); assert.deepEqual(result.rows, [{ id: 1, name: "cheese" }, { id: 2, name: "wine" }]); }); }); await describe("Command tests", async () => { before(async () => { await db.executeCommand(` drop table if exists products; create table products( id int primary key, name varchar(10) ); `); }); after(async () => { await db.executeCommand(`drop table if exists products`); }); await test("command should execute successfully", async () => { await db.executeCommand(`insert into products(id, name) values(?, ?)`, 3, "milk"); const result = await db.executeQuery("select * from products where id = ?", 3); assert.strictEqual(result.rows.length, 1); assert.deepEqual(result.rows, [{ id: 3, name: "milk" }]); }); await test("multiple commands should execute independently", async () => { await db.executeCommand(`insert into products(id, name) values(?, ?)`, 4, "pasta"); try { await db.executeCommand(`insert into products(id, name) values(?, ?)`, 5, "012345678901234567890123456789012345678901234567890123456789"); } catch (error) { // console.log(error); } const result = await db.executeQuery("select * from products order by id"); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [{ id: 3, name: "milk" }, { id: 4, name: "pasta" }]); }); }); await describe("Versioning tests", async () => { before(async () => { // console.log("creating table"); await db.executeCommand(` drop table if exists products; create table products( id int primary key, version int not null, name varchar(100) ); `); // console.log("Inserting 2"); await db.executeCommand(` insert into products(id, version, name) values(1, 1, 'cheese'), (2, 1, 'bread'); `); // console.log("updating 1"); // await db.executeCommand(`update products set version = ?, name = ? where id = ? and version = ?;`, // 2, "brie cheese", 1, 1); // console.log("updating 2"); // await db.executeCommand(`update products set version = ? where id in (?, ?);`, // 3, 1, 2); // console.log("deleting 1"); // await db.executeCommand(`delete from products where id = 1;`); }); // test("nothing", () => // { // assert.ok(true); // }); await test("Should successfully update record", async () => { const sql = `update products set version = ?, name = ? where id = ? and version = ?;`; await db.executeCommand(sql, 2, "brie cheese", 1, 1); const result = await db.executeQuery("select * from products order by id;"); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [{ id: 1, version: 2, name: "brie cheese" }, { id: 2, version: 1, name: "bread" }]); }); await test("Should fail and not update the record", async () => { const sql = `update products set version = ?, name = ? where id = ? and version = ?;`; let exceptionThrown = false; try { await db.executeCommand(sql, 2, "provolone cheese", 1, 1); } catch (error) { exceptionThrown = true; // console.log(error); } assert.strictEqual(exceptionThrown, true); const result = await db.executeQuery("select * from products order by id;"); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [{ id: 1, version: 2, name: "brie cheese" }, { id: 2, version: 1, name: "bread" }]); }); }); await describe("UnitOfWork tests", async () => { before(async () => { await db.executeCommand(` drop table if exists products; create table products( id int primary key, name varchar(10) ); `); }); after(async () => { await db.executeCommand(`drop table if exists products`); }); await test("commands should execute successfully if committed", async () => { let isCommitted = false; let isRolledback = false; const unitOfWork = new KnexPgUnitOfWork(dbConnectionFactory); unitOfWork.onCommit(async () => { isCommitted = true; }); unitOfWork.onRollback(async () => { isRolledback = true; }); try { await db.executeCommandWithinUnitOfWork(unitOfWork, `insert into products(id, name) values(?, ?)`, 3, "milk"); await db.executeCommandWithinUnitOfWork(unitOfWork, `insert into products(id, name) values(?, ?)`, 4, "pasta"); await unitOfWork.commit(); } catch (error) { await unitOfWork.rollback(); } const result = await db.executeQuery(`select * from products where id in (3, 4)`); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [{ id: 3, name: "milk" }, { id: 4, name: "pasta" }]); assert.strictEqual(isCommitted, true); assert.strictEqual(isRolledback, false); }); await test("no commands should execute successfully if rolledback", async () => { let isCommitted = false; let isRolledback = false; const unitOfWork = new KnexPgUnitOfWork(dbConnectionFactory); unitOfWork.onCommit(async () => { isCommitted = true; }); unitOfWork.onRollback(async () => { isRolledback = true; }); try { await db.executeCommandWithinUnitOfWork(unitOfWork, `insert into products(id, name) values(?, ?)`, 5, "fish"); await db.executeCommandWithinUnitOfWork(unitOfWork, `insert into products(id, name) values(?, ?)`, 6, "012345678901234567890123456789012345678901234567890123456789"); await unitOfWork.commit(); } catch (error) { await unitOfWork.rollback(); } const result = await db.executeQuery<any>(`select cast(count(*) as int) from products where id in (5, 6)`); assert.strictEqual(result.rows[0].count, 0); assert.strictEqual(isCommitted, false); assert.strictEqual(isRolledback, true); }); }); await describe("Object tree tests", async () => { before(async () => { await db.executeCommand(` drop table if exists orders; drop table if exists customers; `); await db.executeCommand(` create table customers( id int primary key, name varchar(50) ); `); await db.executeCommand(` create table orders( id int primary key, customer_id int references customers(id), amount numeric not null check(amount > 0) ); `); await db.executeCommand(` insert into customers(id, name) values(1, 'nivin'); insert into orders(id, customer_id, amount) values(1, 1, 50.00), (2, 1, 30.00); insert into customers(id, name) values(2, 'shrey'); insert into orders(id, customer_id, amount) values(3, 2, 10.00), (4, 2, 20.00), (5, 2, 35.00); `); }); after(async () => { await db.executeCommand(` drop table if exists orders; drop table if exists customers; `); }); await test("Produce single object tree from query", async () => { const result = await db.executeQuery(` select c.id as id, c.name as name, o.id as "orders:id", o.amount as "orders:amount" from customers as c inner join orders as o on c.id = o.customer_id where c.id = 1 `); const data = result.toObjectTree(); assert.deepEqual(data, [ { id: 1, name: "nivin", orders: [ { id: 1, amount: 50.00 }, { id: 2, amount: 30.00 } ] } ]); }); await test("Produce multiple object trees from query", async () => { const result = await db.executeQuery(` select c.id as id, c.name as name, o.id as "orders:id", o.amount as "orders:amount" from customers as c inner join orders as o on c.id = o.customer_id `); const data = result.toObjectTree(); assert.deepEqual(data, [ { id: 1, name: "nivin", orders: [ { id: 1, amount: 50.00 }, { id: 2, amount: 30.00 } ] }, { id: 2, name: "shrey", orders: [ { id: 3, amount: 10.00 }, { id: 4, amount: 20.00 }, { id: 5, amount: 35.00 } ] } ]); }); }); await describe("JsonB query tests", async () => { const createdOn = Date.now(); before(async () => { await db.executeCommand(` drop table if exists assets; create table assets( id int primary key, body jsonb ); `); await db.executeCommand(` insert into assets(id, body) values(?,?), (?,?) `, 1, { name: "txt1.txt", ext: "txt", createdOn: createdOn, tags: ["baz", "bar"] }, 2, { name: "import.xls", ext: "xls", tags: ["foo", "bar"] }); }); after(async () => { await db.executeCommand(` drop table if exists assets; `); }); await test("successfully retrieve jsonb data when queried by id", async () => { const result = await db.executeQuery("select * from assets where id = ?", 1); assert.strictEqual(result.rows.length, 1); assert.deepEqual(result.rows, [ { id: 1, body: { name: "txt1.txt", ext: "txt", createdOn: createdOn, tags: ["baz", "bar"] } }]); }); await test("successfully retrieve jsonb data when queried by jsonb scalar field", async () => { const result = await db.executeQuery(`select * from assets where body @> ?;`, { ext: "xls" }); assert.strictEqual(result.rows.length, 1); assert.deepEqual(result.rows, [ { id: 2, body: { name: "import.xls", ext: "xls", tags: ["foo", "bar"] } }]); }); await test("successfully retrieve jsonb data when queried by jsonb array field", async () => { const result = await db.executeQuery(`select * from assets where body @> ?;`, { tags: ["bar"] }); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [ { id: 1, body: { name: "txt1.txt", ext: "txt", createdOn: createdOn, tags: ["baz", "bar"] } }, { id: 2, body: { name: "import.xls", ext: "xls", tags: ["foo", "bar"] } }]); }); }); await describe("JsonB command tests", async () => { before(async () => { await db.executeCommand(` drop table if exists assets; create table assets( id int primary key, body jsonb ); `); }); after(async () => { await db.executeCommand(` drop table if exists assets; `); }); await test("successfully insert jsonb data", async () => { await db.executeCommand(` insert into assets(id, body) values(?,?), (?,?) `, 1, { name: "txt1.txt", ext: "txt" }, 2, { name: "import.xls", ext: "xls" }); const result = await db.executeQuery("select * from assets"); assert.strictEqual(result.rows.length, 2); assert.deepEqual(result.rows, [{ id: 1, body: { name: "txt1.txt", ext: "txt" } }, { id: 2, body: { name: "import.xls", ext: "xls" } }]); }); }); });