Skip to content

Commit 456b2a5

Browse files
committed
add execlastid implementation for mysql
1 parent daaf539 commit 456b2a5

File tree

5 files changed

+176
-8
lines changed

5 files changed

+176
-8
lines changed

examples/authors/mysql/query.sql

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ ORDER BY name;
1010
INSERT INTO authors (
1111
name, bio
1212
) VALUES (
13-
?, ?
13+
?, ?
14+
);
15+
16+
/* name: CreateAuthorReturnId :execlastid */
17+
INSERT INTO authors (
18+
name, bio
19+
) VALUES (
20+
?, ?
1421
);
1522

1623
/* name: DeleteAuthor :exec */
@@ -19,4 +26,4 @@ WHERE id = ?;
1926

2027
/* name: Test :one */
2128
SELECT * FROM node_mysql_types
22-
LIMIT 1;
29+
LIMIT 1;

examples/bun-mysql2/src/db/query_sql.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mysql, { RowDataPacket } from "mysql2/promise";
1+
import mysql, { RowDataPacket, ResultSetHeader } from "mysql2/promise";
22

33
type Client = mysql.Connection | mysql.Pool;
44

@@ -62,7 +62,7 @@ export const createAuthorQuery = `-- name: CreateAuthor :exec
6262
INSERT INTO authors (
6363
name, bio
6464
) VALUES (
65-
?, ?
65+
?, ?
6666
)`;
6767

6868
export interface CreateAuthorArgs {
@@ -77,6 +77,26 @@ export async function createAuthor(client: Client, args: CreateAuthorArgs): Prom
7777
});
7878
}
7979

80+
export const createAuthorReturnIdQuery = `-- name: CreateAuthorReturnId :execlastid
81+
INSERT INTO authors (
82+
name, bio
83+
) VALUES (
84+
?, ?
85+
)`;
86+
87+
export interface CreateAuthorReturnIdArgs {
88+
name: string;
89+
bio: string | null;
90+
}
91+
92+
export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise<number> {
93+
const [result] = await client.query<ResultSetHeader>({
94+
sql: createAuthorReturnIdQuery,
95+
values: [args.name, args.bio]
96+
});
97+
return result?.insertId ?? 0;
98+
}
99+
80100
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec
81101
DELETE FROM authors
82102
WHERE id = ?`;

examples/node-mysql2/src/db/query_sql.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mysql, { RowDataPacket } from "mysql2/promise";
1+
import mysql, { RowDataPacket, ResultSetHeader } from "mysql2/promise";
22

33
type Client = mysql.Connection | mysql.Pool;
44

@@ -62,7 +62,7 @@ export const createAuthorQuery = `-- name: CreateAuthor :exec
6262
INSERT INTO authors (
6363
name, bio
6464
) VALUES (
65-
?, ?
65+
?, ?
6666
)`;
6767

6868
export interface CreateAuthorArgs {
@@ -77,6 +77,26 @@ export async function createAuthor(client: Client, args: CreateAuthorArgs): Prom
7777
});
7878
}
7979

80+
export const createAuthorReturnIdQuery = `-- name: CreateAuthorReturnId :execlastid
81+
INSERT INTO authors (
82+
name, bio
83+
) VALUES (
84+
?, ?
85+
)`;
86+
87+
export interface CreateAuthorReturnIdArgs {
88+
name: string;
89+
bio: string | null;
90+
}
91+
92+
export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise<number> {
93+
const [result] = await client.query<ResultSetHeader>({
94+
sql: createAuthorReturnIdQuery,
95+
values: [args.name, args.bio]
96+
});
97+
return result?.insertId ?? 0;
98+
}
99+
80100
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec
81101
DELETE FROM authors
82102
WHERE id = ?`;

src/app.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ interface Driver {
5353
iface: string | undefined,
5454
params: Parameter[]
5555
) => Node;
56+
execlastidDecl: (
57+
name: string,
58+
text: string,
59+
iface: string | undefined,
60+
params: Parameter[]
61+
) => Node;
5662
manyDecl: (
5763
name: string,
5864
text: string,
@@ -77,10 +83,10 @@ function createNodeGenerator(driver?: string): Driver {
7783
return mysql2;
7884
}
7985
case "pg": {
80-
return pg;
86+
return pg as any;
8187
}
8288
case "postgres": {
83-
return postgres;
89+
return postgres as any;
8490
}
8591
}
8692
throw new Error(`unknown driver: ${driver}`);
@@ -156,6 +162,12 @@ ${query.text}`
156162
);
157163
break;
158164
}
165+
case ":execlastid": {
166+
nodes.push(
167+
driver.execlastidDecl(lowerName, textName, argIface, query.params)
168+
)
169+
break;
170+
}
159171
case ":one": {
160172
nodes.push(
161173
driver.oneDecl(

src/drivers/mysql2.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ export function preamble(queries: unknown) {
178178
undefined,
179179
factory.createIdentifier("RowDataPacket")
180180
),
181+
factory.createImportSpecifier(
182+
false,
183+
undefined,
184+
factory.createIdentifier("ResultSetHeader")
185+
),
181186
])
182187
),
183188
factory.createStringLiteral("mysql2/promise"),
@@ -611,10 +616,114 @@ export function oneDecl(
611616
);
612617
}
613618

619+
export function execlastidDecl(
620+
funcName: string,
621+
queryName: string,
622+
argIface: string | undefined,
623+
params: Parameter[]
624+
) {
625+
const funcParams = funcParamsDecl(argIface, params);
626+
627+
return factory.createFunctionDeclaration(
628+
[
629+
factory.createToken(SyntaxKind.ExportKeyword),
630+
factory.createToken(SyntaxKind.AsyncKeyword),
631+
],
632+
undefined,
633+
factory.createIdentifier(funcName),
634+
undefined,
635+
funcParams,
636+
factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [
637+
factory.createTypeReferenceNode('number', undefined),
638+
]),
639+
factory.createBlock(
640+
[
641+
factory.createVariableStatement(
642+
undefined,
643+
factory.createVariableDeclarationList(
644+
[
645+
factory.createVariableDeclaration(
646+
factory.createArrayBindingPattern([
647+
factory.createBindingElement(
648+
undefined,
649+
undefined,
650+
factory.createIdentifier("result"),
651+
undefined
652+
),
653+
]),
654+
undefined,
655+
undefined,
656+
factory.createAwaitExpression(
657+
factory.createCallExpression(
658+
factory.createPropertyAccessExpression(
659+
factory.createIdentifier("client"),
660+
factory.createIdentifier("query")
661+
),
662+
[
663+
factory.createTypeReferenceNode(
664+
factory.createIdentifier("ResultSetHeader"),
665+
undefined
666+
)
667+
],
668+
[
669+
factory.createObjectLiteralExpression(
670+
[
671+
factory.createPropertyAssignment(
672+
factory.createIdentifier("sql"),
673+
factory.createIdentifier(queryName)
674+
),
675+
factory.createPropertyAssignment(
676+
factory.createIdentifier("values"),
677+
factory.createArrayLiteralExpression(
678+
params.map((param, i) =>
679+
factory.createPropertyAccessExpression(
680+
factory.createIdentifier("args"),
681+
factory.createIdentifier(
682+
argName(i, param.column)
683+
)
684+
)
685+
),
686+
false
687+
)
688+
),
689+
],
690+
true
691+
),
692+
]
693+
)
694+
)
695+
)
696+
],
697+
NodeFlags.Const |
698+
// NodeFlags.Constant |
699+
NodeFlags.AwaitContext |
700+
// NodeFlags.Constant |
701+
NodeFlags.ContextFlags |
702+
NodeFlags.TypeExcludesFlags
703+
)
704+
),
705+
factory.createReturnStatement(
706+
factory.createBinaryExpression(
707+
factory.createPropertyAccessChain(
708+
factory.createIdentifier("result"),
709+
factory.createToken(SyntaxKind.QuestionDotToken),
710+
factory.createIdentifier("insertId")
711+
),
712+
factory.createToken(SyntaxKind.QuestionQuestionToken),
713+
factory.createNumericLiteral(0)
714+
)
715+
),
716+
],
717+
true
718+
)
719+
)
720+
}
721+
614722
export default {
615723
columnType,
616724
preamble,
617725
execDecl,
618726
manyDecl,
619727
oneDecl,
728+
execlastidDecl,
620729
};

0 commit comments

Comments
 (0)