Skip to content

Commit

Permalink
feat: support RETURNING clause (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
ginnwork authored Jan 24, 2025
1 parent 9057f08 commit 61e6c3f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
12 changes: 9 additions & 3 deletions src/database.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { sqlTemplate } from "./template";
import type { Connector, Database } from "./types";
import type { Connector, Database, SQLDialect } from "./types";

const SQL_WITH_RES_RE = /^select/i;
const SQL_SELECT_RE = /^select/i;
const SQL_RETURNING_RE = /[\s]returning[\s]/i;
const DIALECTS_WITH_RET: Set<SQLDialect> = new Set(["postgresql", "sqlite"]);

/**
* Creates and returns a database interface using the specified connector.
Expand Down Expand Up @@ -33,7 +35,11 @@ export function createDatabase<TConnector extends Connector = Connector>(

sql: async (strings, ...values) => {
const [sql, params] = sqlTemplate(strings, ...values);
if (SQL_WITH_RES_RE.test(sql)) {
if (
SQL_SELECT_RE.test(sql) /* select */ ||
// prettier-ignore
(DIALECTS_WITH_RET.has(connector.dialect) && SQL_RETURNING_RE.test(sql)) /* returning */
) {
const rows = await connector.prepare(sql).all(...params);
return {
rows,
Expand Down
33 changes: 22 additions & 11 deletions test/connectors/_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ export function testConnector<TConnector extends Connector = Connector>(opts: {
});

const userId = "1001";
const userSnapshot = `
[
{
"email": "",
"firstName": "John",
"id": "1001",
"lastName": "Doe",
},
]
`;

it("instance matches", async () => {
const instance = await db.getInstance();
Expand All @@ -34,20 +44,21 @@ export function testConnector<TConnector extends Connector = Connector>(opts: {
});

it("insert", async () => {
await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;
switch(opts.dialect) {
case "mysql": {
await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;
break;
}
default: {
const { rows } = await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '') RETURNING *`;
expect(rows).toMatchInlineSnapshot(userSnapshot);
break;
}
}
});

it("select", async () => {
const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;
expect(rows).toMatchInlineSnapshot(`
[
{
"email": "",
"firstName": "John",
"id": "1001",
"lastName": "Doe",
},
]
`);
expect(rows).toMatchInlineSnapshot(userSnapshot);
});
}

0 comments on commit 61e6c3f

Please sign in to comment.