Skip to content

Commit 1a42ab0

Browse files
authored
feat(mysql): Support string bignumbers in mysql (#16)
1 parent 570f4e3 commit 1a42ab0

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ SELECT id, name, bio FROM authors
99
WHERE id = ? LIMIT 1`;
1010

1111
export interface GetAuthorArgs {
12-
id: number;
12+
id: string;
1313
}
1414

1515
export interface GetAuthorRow {
16-
id: number;
16+
id: string;
1717
name: string;
1818
bio: string | null;
1919
}
@@ -40,7 +40,7 @@ SELECT id, name, bio FROM authors
4040
ORDER BY name`;
4141

4242
export interface ListAuthorsRow {
43-
id: number;
43+
id: string;
4444
name: string;
4545
bio: string | null;
4646
}
@@ -104,7 +104,7 @@ DELETE FROM authors
104104
WHERE id = ?`;
105105

106106
export interface DeleteAuthorArgs {
107-
id: number;
107+
id: string;
108108
}
109109

110110
export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise<void> {
@@ -127,8 +127,8 @@ export interface TestRow {
127127
cMediumint: number | null;
128128
cInt: number | null;
129129
cInteger: number | null;
130-
cBigint: number | null;
131-
cSerial: number;
130+
cBigint: string | null;
131+
cSerial: string;
132132
cDecimal: string | null;
133133
cDec: string | null;
134134
cNumeric: string | null;

examples/node-mysql2/src/main.ts

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ async function main() {
2222
user: url.username,
2323
password: url.password,
2424
database: url.pathname.substring(1),
25+
supportBigNumbers: true,
26+
bigNumberStrings: true,
2527
ssl: {
2628
// TODO: FIXME
2729
rejectUnauthorized: false,

examples/sqlc.dev.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ sql:
4949
options:
5050
runtime: node
5151
driver: mysql2
52+
mysql2:
53+
big_number_strings: true
54+
support_big_numbers: true
5255
- schema: "authors/mysql/schema.sql"
5356
queries: "authors/mysql/query.sql"
5457
engine: "mysql"

src/app.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { argName, colName } from "./drivers/utlis";
3131
import { Driver as Sqlite3Driver } from "./drivers/better-sqlite3";
3232
import { Driver as PgDriver } from "./drivers/pg";
3333
import { Driver as PostgresDriver } from "./drivers/postgres";
34-
import { Driver as MysqlDriver } from "./drivers/mysql2";
34+
import { Mysql2Options, Driver as MysqlDriver } from "./drivers/mysql2";
3535

3636
// Read input from stdin
3737
const input = readInput();
@@ -43,6 +43,7 @@ writeOutput(result);
4343
interface Options {
4444
runtime?: string;
4545
driver?: string;
46+
mysql2?: Mysql2Options
4647
}
4748

4849
interface Driver {
@@ -78,10 +79,10 @@ interface Driver {
7879
) => Node;
7980
}
8081

81-
function createNodeGenerator(driver?: string): Driver {
82-
switch (driver) {
82+
function createNodeGenerator(options: Options): Driver {
83+
switch (options.driver) {
8384
case "mysql2": {
84-
return new MysqlDriver();
85+
return new MysqlDriver(options.mysql2);
8586
}
8687
case "pg": {
8788
return new PgDriver();
@@ -93,7 +94,7 @@ function createNodeGenerator(driver?: string): Driver {
9394
return new Sqlite3Driver();
9495
}
9596
}
96-
throw new Error(`unknown driver: ${driver}`);
97+
throw new Error(`unknown driver: ${options.driver}`);
9798
}
9899

99100
function codegen(input: GenerateRequest): GenerateResponse {
@@ -105,7 +106,7 @@ function codegen(input: GenerateRequest): GenerateResponse {
105106
options = JSON.parse(text) as Options;
106107
}
107108

108-
const driver = createNodeGenerator(options.driver);
109+
const driver = createNodeGenerator(options);
109110

110111
// TODO: Verify options, parse them from protobuf honestly
111112

@@ -146,17 +147,15 @@ ${query.text}`
146147
)
147148
);
148149

149-
const ctype = driver.columnType;
150-
151150
let argIface = undefined;
152151
let returnIface = undefined;
153152
if (query.params.length > 0) {
154153
argIface = `${query.name}Args`;
155-
nodes.push(argsDecl(argIface, ctype, query.params));
154+
nodes.push(argsDecl(argIface, driver, query.params));
156155
}
157156
if (query.columns.length > 0) {
158157
returnIface = `${query.name}Row`;
159-
nodes.push(rowDecl(returnIface, ctype, query.columns));
158+
nodes.push(rowDecl(returnIface, driver, query.columns));
160159
}
161160

162161
switch (query.cmd) {
@@ -240,7 +239,7 @@ function queryDecl(name: string, sql: string) {
240239

241240
function argsDecl(
242241
name: string,
243-
ctype: (c?: Column) => TypeNode,
242+
driver: Driver,
244243
params: Parameter[]
245244
) {
246245
return factory.createInterfaceDeclaration(
@@ -253,15 +252,15 @@ function argsDecl(
253252
undefined,
254253
factory.createIdentifier(argName(i, param.column)),
255254
undefined,
256-
ctype(param.column)
255+
driver.columnType(param.column)
257256
)
258257
)
259258
);
260259
}
261260

262261
function rowDecl(
263262
name: string,
264-
ctype: (c?: Column) => TypeNode,
263+
driver: Driver,
265264
columns: Column[]
266265
) {
267266
return factory.createInterfaceDeclaration(
@@ -274,7 +273,7 @@ function rowDecl(
274273
undefined,
275274
factory.createIdentifier(colName(i, column)),
276275
undefined,
277-
ctype(column)
276+
driver.columnType(column)
278277
)
279278
)
280279
);

src/drivers/mysql2.ts

+23
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import { SyntaxKind, NodeFlags, TypeNode, factory } from "typescript";
55
import { Parameter, Column, Query } from "../gen/plugin/codegen_pb";
66
import { argName, colName } from "./utlis";
77

8+
export interface Mysql2Options {
9+
support_big_numbers?: boolean;
10+
big_number_strings?: boolean;
11+
}
12+
813
function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
914
let funcParams = [
1015
factory.createParameterDeclaration(
@@ -40,6 +45,12 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
4045
}
4146

4247
export class Driver {
48+
private readonly options: Mysql2Options
49+
50+
constructor(options?: Mysql2Options) {
51+
this.options = options ?? {}
52+
}
53+
4354
columnType(column?: Column): TypeNode {
4455
if (column === undefined || column.type === undefined) {
4556
return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
@@ -49,6 +60,18 @@ export class Driver {
4960
switch (column.type.name) {
5061
case "bigint": {
5162
typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword);
63+
64+
if (this.options.support_big_numbers) {
65+
if (this.options.big_number_strings) {
66+
typ = factory.createKeywordTypeNode(SyntaxKind.StringKeyword)
67+
} else {
68+
typ = factory.createUnionTypeNode([
69+
factory.createKeywordTypeNode(SyntaxKind.NumberKeyword),
70+
factory.createKeywordTypeNode(SyntaxKind.StringKeyword)
71+
])
72+
}
73+
}
74+
5275
break;
5376
}
5477
case "binary": {

0 commit comments

Comments
 (0)