Skip to content

Commit 8982c25

Browse files
committed
add execlastid implementation for mysql
1 parent daaf539 commit 8982c25

File tree

5 files changed

+179
-8
lines changed

5 files changed

+179
-8
lines changed

examples/authors/mysql/query.sql

+9-2
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

+22-2
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 | null> {
93+
const [result] = await client.query<ResultSetHeader>({
94+
sql: createAuthorReturnIdQuery,
95+
values: [args.name, args.bio]
96+
});
97+
return result?.insertId ?? null;
98+
}
99+
80100
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec
81101
DELETE FROM authors
82102
WHERE id = ?`;

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

+22-2
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 | null> {
93+
const [result] = await client.query<ResultSetHeader>({
94+
sql: createAuthorReturnIdQuery,
95+
values: [args.name, args.bio]
96+
});
97+
return result?.insertId ?? null;
98+
}
99+
80100
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec
81101
DELETE FROM authors
82102
WHERE id = ?`;

src/app.ts

+14-2
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

+112
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,117 @@ 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.createUnionTypeNode([
638+
factory.createTypeReferenceNode('number', undefined),
639+
factory.createLiteralTypeNode(factory.createNull()),
640+
])
641+
]),
642+
factory.createBlock(
643+
[
644+
factory.createVariableStatement(
645+
undefined,
646+
factory.createVariableDeclarationList(
647+
[
648+
factory.createVariableDeclaration(
649+
factory.createArrayBindingPattern([
650+
factory.createBindingElement(
651+
undefined,
652+
undefined,
653+
factory.createIdentifier("result"),
654+
undefined
655+
),
656+
]),
657+
undefined,
658+
undefined,
659+
factory.createAwaitExpression(
660+
factory.createCallExpression(
661+
factory.createPropertyAccessExpression(
662+
factory.createIdentifier("client"),
663+
factory.createIdentifier("query")
664+
),
665+
[
666+
factory.createTypeReferenceNode(
667+
factory.createIdentifier("ResultSetHeader"),
668+
undefined
669+
)
670+
],
671+
[
672+
factory.createObjectLiteralExpression(
673+
[
674+
factory.createPropertyAssignment(
675+
factory.createIdentifier("sql"),
676+
factory.createIdentifier(queryName)
677+
),
678+
factory.createPropertyAssignment(
679+
factory.createIdentifier("values"),
680+
factory.createArrayLiteralExpression(
681+
params.map((param, i) =>
682+
factory.createPropertyAccessExpression(
683+
factory.createIdentifier("args"),
684+
factory.createIdentifier(
685+
argName(i, param.column)
686+
)
687+
)
688+
),
689+
false
690+
)
691+
),
692+
],
693+
true
694+
),
695+
]
696+
)
697+
)
698+
)
699+
],
700+
NodeFlags.Const |
701+
// NodeFlags.Constant |
702+
NodeFlags.AwaitContext |
703+
// NodeFlags.Constant |
704+
NodeFlags.ContextFlags |
705+
NodeFlags.TypeExcludesFlags
706+
)
707+
),
708+
factory.createReturnStatement(
709+
factory.createBinaryExpression(
710+
factory.createPropertyAccessChain(
711+
factory.createIdentifier("result"),
712+
factory.createToken(SyntaxKind.QuestionDotToken),
713+
factory.createIdentifier("insertId")
714+
),
715+
factory.createToken(SyntaxKind.QuestionQuestionToken),
716+
factory.createNull()
717+
)
718+
),
719+
],
720+
true
721+
)
722+
)
723+
}
724+
614725
export default {
615726
columnType,
616727
preamble,
617728
execDecl,
618729
manyDecl,
619730
oneDecl,
731+
execlastidDecl,
620732
};

0 commit comments

Comments
 (0)