From bcebb8919b7d47b169b3b483b8da51100aa3851d Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Sat, 2 Mar 2024 20:31:59 -0800 Subject: [PATCH 1/3] WIP --- src/app.ts | 4 +- src/drivers/pg.ts | 1450 ++++++++++++++++++++++----------------------- 2 files changed, 727 insertions(+), 727 deletions(-) diff --git a/src/app.ts b/src/app.ts index 36e1ddd..3dc80ec 100644 --- a/src/app.ts +++ b/src/app.ts @@ -29,7 +29,7 @@ import { import { argName, colName } from "./drivers/utlis"; import betterSQLite3 from "./drivers/better-sqlite3"; -import pg from "./drivers/pg"; +import { Driver as PgDriver } from "./drivers/pg"; import postgres from "./drivers/postgres"; import mysql2 from "./drivers/mysql2"; @@ -84,7 +84,7 @@ function createNodeGenerator(driver?: string): Driver { return mysql2; } case "pg": { - return pg; + return new PgDriver(); } case "postgres": { return postgres; diff --git a/src/drivers/pg.ts b/src/drivers/pg.ts index 9272035..95828cf 100644 --- a/src/drivers/pg.ts +++ b/src/drivers/pg.ts @@ -1,394 +1,15 @@ -import { SyntaxKind, NodeFlags, Node, TypeNode, factory, FunctionDeclaration } from "typescript"; +import { + SyntaxKind, + NodeFlags, + Node, + TypeNode, + factory, + FunctionDeclaration, +} from "typescript"; import { Parameter, Column, Query } from "../gen/plugin/codegen_pb"; import { argName, colName } from "./utlis"; -export function columnType(column?: Column): TypeNode { - if (column === undefined || column.type === undefined) { - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - } - // Some of the type names have the `pgcatalog.` prefix. Remove this. - let typeName = column.type.name; - const pgCatalog = "pg_catalog."; - if (typeName.startsWith(pgCatalog)) { - typeName = typeName.slice(pgCatalog.length); - } - let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); - switch (typeName) { - case "aclitem": { - // string - break; - } - case "bigserial": { - // string - break; - } - case "bit": { - // string - break; - } - case "bool": { - typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); - break; - } - case "box": { - // string - break; - } - case "bpchar": { - // string - break; - } - case "bytea": { - // TODO: Is this correct or node-specific? - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "cid": { - // string - break; - } - case "cidr": { - // string - break; - } - case "circle": { - typ = factory.createTypeLiteralNode([ - factory.createPropertySignature( - undefined, - factory.createIdentifier("x"), - undefined, - factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) - ), - factory.createPropertySignature( - undefined, - factory.createIdentifier("y"), - undefined, - factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) - ), - factory.createPropertySignature( - undefined, - factory.createIdentifier("radius"), - undefined, - factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) - ), - ]); - break; - } - case "date": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "float4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "float8": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "inet": { - // string - break; - } - case "int2": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "int4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "int8": { - // string - break; - } - case "interval": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("IPostgresInterval"), - undefined - ); - break; - } - case "json": { - typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - break; - } - case "jsonb": { - typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - break; - } - case "line": { - // string - break; - } - case "lseg": { - // string - break; - } - case "madaddr": { - // string - break; - } - case "madaddr8": { - // string - break; - } - case "money": { - // string - break; - } - case "oid": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "path": { - // string - break; - } - case "pg_node_tree": { - // string - break; - } - case "pg_snapshot": { - // string - break; - } - case "point": { - typ = factory.createTypeLiteralNode([ - factory.createPropertySignature( - undefined, - factory.createIdentifier("x"), - undefined, - factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) - ), - factory.createPropertySignature( - undefined, - factory.createIdentifier("y"), - undefined, - factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) - ), - ]); - break; - } - case "polygon": { - // string - break; - } - case "regproc": { - // string - break; - } - case "regrole": { - // string - break; - } - case "serial": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial2": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial8": { - // string - break; - } - case "smallserial": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "tid": { - // string - break; - } - case "text": { - // string - break; - } - case "time": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "timetz": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "timestamp": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "timestamptz": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "tsquery": { - // string - break; - } - case "tsvector": { - // string - break; - } - case "txid_snapshot": { - // string - break; - } - case "uuid": { - // string - break; - } - case "varbit": { - // string - break; - } - case "varchar": { - // string - break; - } - case "xid": { - // string - break; - } - case "xml": { - // string - break; - } - } - if (column.isArray || column.arrayDims > 0) { - let dims = Math.max(column.arrayDims || 1); - for (let i = 0; i < dims; i++) { - typ = factory.createArrayTypeNode(typ); - } - } - if (column.notNull) { - return typ; - } - return factory.createUnionTypeNode([ - typ, - factory.createLiteralTypeNode(factory.createNull()), - ]); -} - -export function preamble(queries: Query[]) { - const imports: Node[] = [ - factory.createImportDeclaration( - undefined, - factory.createImportClause( - false, - undefined, - factory.createNamedImports([ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("QueryArrayConfig") - ), - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("QueryArrayResult") - ), - ]) - ), - factory.createStringLiteral("pg"), - undefined - ), - ]; - - const hasInterval = queries.some( - (query) => - query.params.some((p) => p.column?.type?.name === "interval") || - query.columns.some((c) => c.type?.name === "interval") - ); - - if (hasInterval) { - imports.push( - factory.createImportDeclaration( - undefined, - factory.createImportClause( - false, - undefined, - factory.createNamedImports([ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("IPostgresInterval") - ), - ]) - ), - factory.createStringLiteral("postgres-interval"), - undefined - ) - ); - } - - imports.push( - factory.createInterfaceDeclaration( - undefined, - factory.createIdentifier("Client"), - undefined, - undefined, - [ - factory.createPropertySignature( - undefined, - factory.createIdentifier("query"), - undefined, - factory.createFunctionTypeNode( - undefined, - [ - factory.createParameterDeclaration( - undefined, - undefined, - factory.createIdentifier("config"), - undefined, - factory.createTypeReferenceNode( - factory.createIdentifier("QueryArrayConfig"), - undefined - ), - undefined - ), - ], - factory.createTypeReferenceNode( - factory.createIdentifier("Promise"), - [ - factory.createTypeReferenceNode( - factory.createIdentifier("QueryArrayResult"), - undefined - ), - ] - ) - ) - ), - ] - ) - ); - - return imports; -} - function funcParamsDecl(iface: string | undefined, params: Parameter[]) { let funcParams = [ factory.createParameterDeclaration( @@ -423,375 +44,754 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) { return funcParams; } -export function execDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -) { - const funcParams = funcParamsDecl(argIface, params); +export class Driver { + columnType(column?: Column): TypeNode { + if (column === undefined || column.type === undefined) { + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + // Some of the type names have the `pgcatalog.` prefix. Remove this. + let typeName = column.type.name; + const pgCatalog = "pg_catalog."; + if (typeName.startsWith(pgCatalog)) { + typeName = typeName.slice(pgCatalog.length); + } + let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); + switch (typeName) { + case "aclitem": { + // string + break; + } + case "bigserial": { + // string + break; + } + case "bit": { + // string + break; + } + case "bool": { + typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); + break; + } + case "box": { + // string + break; + } + case "bpchar": { + // string + break; + } + case "bytea": { + // TODO: Is this correct or node-specific? + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "cid": { + // string + break; + } + case "cidr": { + // string + break; + } + case "circle": { + typ = factory.createTypeLiteralNode([ + factory.createPropertySignature( + undefined, + factory.createIdentifier("x"), + undefined, + factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) + ), + factory.createPropertySignature( + undefined, + factory.createIdentifier("y"), + undefined, + factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) + ), + factory.createPropertySignature( + undefined, + factory.createIdentifier("radius"), + undefined, + factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) + ), + ]); + break; + } + case "date": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "float4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "float8": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "inet": { + // string + break; + } + case "int2": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "int4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "int8": { + // string + break; + } + case "interval": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("IPostgresInterval"), + undefined + ); + break; + } + case "json": { + typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + break; + } + case "jsonb": { + typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + break; + } + case "line": { + // string + break; + } + case "lseg": { + // string + break; + } + case "madaddr": { + // string + break; + } + case "madaddr8": { + // string + break; + } + case "money": { + // string + break; + } + case "oid": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "path": { + // string + break; + } + case "pg_node_tree": { + // string + break; + } + case "pg_snapshot": { + // string + break; + } + case "point": { + typ = factory.createTypeLiteralNode([ + factory.createPropertySignature( + undefined, + factory.createIdentifier("x"), + undefined, + factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) + ), + factory.createPropertySignature( + undefined, + factory.createIdentifier("y"), + undefined, + factory.createKeywordTypeNode(SyntaxKind.NumberKeyword) + ), + ]); + break; + } + case "polygon": { + // string + break; + } + case "regproc": { + // string + break; + } + case "regrole": { + // string + break; + } + case "serial": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial2": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial8": { + // string + break; + } + case "smallserial": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "tid": { + // string + break; + } + case "text": { + // string + break; + } + case "time": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "timetz": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "timestamp": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "timestamptz": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "tsquery": { + // string + break; + } + case "tsvector": { + // string + break; + } + case "txid_snapshot": { + // string + break; + } + case "uuid": { + // string + break; + } + case "varbit": { + // string + break; + } + case "varchar": { + // string + break; + } + case "xid": { + // string + break; + } + case "xml": { + // string + break; + } + } + if (column.isArray || column.arrayDims > 0) { + let dims = Math.max(column.arrayDims || 1); + for (let i = 0; i < dims; i++) { + typ = factory.createArrayTypeNode(typ); + } + } + if (column.notNull) { + return typ; + } + return factory.createUnionTypeNode([ + typ, + factory.createLiteralTypeNode(factory.createNull()), + ]); + } - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), - ]), - factory.createBlock( - [ - factory.createExpressionStatement( - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") + preamble(queries: Query[]) { + const imports: Node[] = [ + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, + undefined, + factory.createNamedImports([ + factory.createImportSpecifier( + false, + undefined, + factory.createIdentifier("QueryArrayConfig") + ), + factory.createImportSpecifier( + false, + undefined, + factory.createIdentifier("QueryArrayResult") + ), + ]) + ), + factory.createStringLiteral("pg"), + undefined + ), + ]; + + const hasInterval = queries.some( + (query) => + query.params.some((p) => p.column?.type?.name === "interval") || + query.columns.some((c) => c.type?.name === "interval") + ); + + if (hasInterval) { + imports.push( + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, + undefined, + factory.createNamedImports([ + factory.createImportSpecifier( + false, + undefined, + factory.createIdentifier("IPostgresInterval") ), + ]) + ), + factory.createStringLiteral("postgres-interval"), + undefined + ) + ); + } + + imports.push( + factory.createInterfaceDeclaration( + undefined, + factory.createIdentifier("Client"), + undefined, + undefined, + [ + factory.createPropertySignature( + undefined, + factory.createIdentifier("query"), + undefined, + factory.createFunctionTypeNode( undefined, [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("text"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier(argName(i, param.column)) - ) - ), - false - ) - ), - factory.createPropertyAssignment( - factory.createIdentifier("rowMode"), - factory.createStringLiteral("array") - ), - ], - true + factory.createParameterDeclaration( + undefined, + undefined, + factory.createIdentifier("config"), + undefined, + factory.createTypeReferenceNode( + factory.createIdentifier("QueryArrayConfig"), + undefined + ), + undefined ), - ] + ], + factory.createTypeReferenceNode( + factory.createIdentifier("Promise"), + [ + factory.createTypeReferenceNode( + factory.createIdentifier("QueryArrayResult"), + undefined + ), + ] + ) ) - ) - ), - ], - true - ) - ); -} + ), + ] + ) + ); -export function oneDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + return imports; + } - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createUnionTypeNode([ - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ), - factory.createLiteralTypeNode(factory.createNull()), - ]), - ]), - factory.createBlock( + execDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("result"), - undefined, + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), + ]), + factory.createBlock( + [ + factory.createExpressionStatement( + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") + ), undefined, - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") - ), - undefined, + [ + factory.createObjectLiteralExpression( [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("text"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) - ) - ) - ), - false + factory.createPropertyAssignment( + factory.createIdentifier("text"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) ) ), - factory.createPropertyAssignment( - factory.createIdentifier("rowMode"), - factory.createStringLiteral("array") - ), - ], - true + false + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("rowMode"), + factory.createStringLiteral("array") ), - ] + ], + true + ), + ] + ) + ) + ), + ], + true + ) + ); + } + + oneDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createUnionTypeNode([ + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined + ), + factory.createLiteralTypeNode(factory.createNull()), + ]), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("result"), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") + ), + undefined, + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier("text"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) + ) + ), + false + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("rowMode"), + factory.createStringLiteral("array") + ), + ], + true + ), + ] + ) ) - ) - ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createIfStatement( - factory.createBinaryExpression( - factory.createPropertyAccessExpression( + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createIfStatement( + factory.createBinaryExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("result"), - factory.createIdentifier("rows") + factory.createPropertyAccessExpression( + factory.createIdentifier("result"), + factory.createIdentifier("rows") + ), + factory.createIdentifier("length") ), - factory.createIdentifier("length") + factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), + factory.createNumericLiteral("1") ), - factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), - factory.createNumericLiteral("1") - ), - factory.createBlock( - [factory.createReturnStatement(factory.createNull())], - true + factory.createBlock( + [factory.createReturnStatement(factory.createNull())], + true + ), + undefined ), - undefined - ), - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("row"), - undefined, - undefined, - factory.createElementAccessExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("result"), - factory.createIdentifier("rows") - ), - factory.createNumericLiteral("0") - ) - ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createReturnStatement( - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) - ) - ) - ), - true - ) - ), - ], - true - ) - ); -} - -export function manyDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); - - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ) - ), - ]), - factory.createBlock( - [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("result"), - undefined, - undefined, - factory.createAwaitExpression( - factory.createCallExpression( + undefined, + undefined, + factory.createElementAccessExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") + factory.createIdentifier("result"), + factory.createIdentifier("rows") ), - undefined, - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("text"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) - ) - ) - ), - false - ) - ), - factory.createPropertyAssignment( - factory.createIdentifier("rowMode"), - factory.createStringLiteral("array") - ), - ], - true - ), - ] + factory.createNumericLiteral("0") + ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createReturnStatement( + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) ) ) ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags + true + ) + ), + ], + true + ) + ); + } + + manyDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined ) ), - factory.createReturnStatement( - factory.createCallExpression( - factory.createPropertyAccessExpression( + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("result"), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") + ), + undefined, + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier("text"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) + ) + ), + false + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("rowMode"), + factory.createStringLiteral("array") + ), + ], + true + ), + ] + ) + ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createReturnStatement( + factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("result"), - factory.createIdentifier("rows") + factory.createPropertyAccessExpression( + factory.createIdentifier("result"), + factory.createIdentifier("rows") + ), + factory.createIdentifier("map") ), - factory.createIdentifier("map") - ), - undefined, - [ - factory.createArrowFunction( - undefined, - undefined, - [ - factory.createParameterDeclaration( - undefined, - undefined, - factory.createIdentifier("row"), - undefined, - undefined, - undefined - ), - ], - undefined, - factory.createToken(SyntaxKind.EqualsGreaterThanToken), - factory.createBlock( + undefined, + [ + factory.createArrowFunction( + undefined, + undefined, [ - factory.createReturnStatement( - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( - factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) - ) - ) - ), - true - ) + factory.createParameterDeclaration( + undefined, + undefined, + factory.createIdentifier("row"), + undefined, + undefined, + undefined ), ], - true - ) - ), - ] - ) - ), - ], - true - ) - ); -} + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createBlock( + [ + factory.createReturnStatement( + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) + ) + ) + ), + true + ) + ), + ], + true + ) + ), + ] + ) + ), + ], + true + ) + ); + } -export function execlastidDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -): FunctionDeclaration { - throw new Error('pg driver currently does not support :execlastid') + execlastidDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ): FunctionDeclaration { + throw new Error("pg driver currently does not support :execlastid"); + } } - -export default { - columnType, - execDecl, - manyDecl, - oneDecl, - preamble, - execlastidDecl, -}; From f6c2c387dc539b496bb8916b0f8ca579492dc2f0 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Sat, 2 Mar 2024 20:40:00 -0800 Subject: [PATCH 2/3] postgres --- src/app.ts | 6 +- src/drivers/postgres.ts | 1059 ++++++++++++++++++++------------------- 2 files changed, 533 insertions(+), 532 deletions(-) diff --git a/src/app.ts b/src/app.ts index 3dc80ec..842ba12 100644 --- a/src/app.ts +++ b/src/app.ts @@ -30,7 +30,7 @@ import { import { argName, colName } from "./drivers/utlis"; import betterSQLite3 from "./drivers/better-sqlite3"; import { Driver as PgDriver } from "./drivers/pg"; -import postgres from "./drivers/postgres"; +import { Driver as PostgresDriver } from "./drivers/postgres"; import mysql2 from "./drivers/mysql2"; // Read input from stdin @@ -87,7 +87,7 @@ function createNodeGenerator(driver?: string): Driver { return new PgDriver(); } case "postgres": { - return postgres; + return new PostgresDriver(); } case "better-sqlite3": { return betterSQLite3; @@ -169,7 +169,7 @@ ${query.text}` case ":execlastid": { nodes.push( driver.execlastidDecl(lowerName, textName, argIface, query.params) - ) + ); break; } case ":one": { diff --git a/src/drivers/postgres.ts b/src/drivers/postgres.ts index f9d7bc8..68d23f2 100644 --- a/src/drivers/postgres.ts +++ b/src/drivers/postgres.ts @@ -1,283 +1,15 @@ -import { SyntaxKind, NodeFlags, TypeNode, factory, FunctionDeclaration } from "typescript"; +import { + SyntaxKind, + NodeFlags, + TypeNode, + factory, + FunctionDeclaration, +} from "typescript"; import { Parameter, Column } from "../gen/plugin/codegen_pb"; import { argName, colName } from "./utlis"; import { log } from "../logger"; -export function columnType(column?: Column): TypeNode { - if (column === undefined || column.type === undefined) { - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - } - // Some of the type names have the `pgcatalog.` prefix. Remove this. - let typeName = column.type.name; - const pgCatalog = "pg_catalog."; - if (typeName.startsWith(pgCatalog)) { - typeName = typeName.slice(pgCatalog.length); - } - let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); - switch (typeName) { - case "aclitem": { - // string - break; - } - case "bigserial": { - // string - break; - } - case "bit": { - // string - break; - } - case "bool": { - typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); - break; - } - case "box": { - // string - break; - } - case "bpchar": { - // string - break; - } - case "bytea": { - // TODO: Is this correct or node-specific? - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "cid": { - // string - break; - } - case "cidr": { - // string - break; - } - case "circle": { - // string - break; - } - case "date": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "float4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "float8": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "inet": { - // string - break; - } - case "int2": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "int4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "int8": { - // string - break; - } - case "interval": { - // string - break; - } - case "json": { - typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - break; - } - case "jsonb": { - typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - break; - } - case "line": { - // string - break; - } - case "lseg": { - // string - break; - } - case "madaddr": { - // string - break; - } - case "madaddr8": { - // string - break; - } - case "money": { - // string - break; - } - case "oid": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "path": { - // string - break; - } - case "pg_node_tree": { - // string - break; - } - case "pg_snapshot": { - // string - break; - } - case "point": { - // string - break; - } - case "polygon": { - // string - break; - } - case "regproc": { - // string - break; - } - case "regrole": { - // string - break; - } - case "serial": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial2": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial4": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "serial8": { - // string - break; - } - case "smallserial": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "tid": { - // string - break; - } - case "text": { - // string - break; - } - case "time": { - // string - break; - } - case "timetz": { - // string - break; - } - case "timestamp": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "timestamptz": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "tsquery": { - // string - break; - } - case "tsvector": { - // string - break; - } - case "txid_snapshot": { - // string - break; - } - case "uuid": { - // string - break; - } - case "varbit": { - // string - break; - } - case "varchar": { - // string - break; - } - case "xid": { - // string - break; - } - case "xml": { - // string - break; - } - default: { - log(`unknown type ${column.type?.name}`); - break; - } - } - if (column.isArray || column.arrayDims > 0) { - let dims = Math.max(column.arrayDims || 1); - for (let i = 0; i < dims; i++) { - typ = factory.createArrayTypeNode(typ); - } - } - if (column.notNull) { - return typ; - } - return factory.createUnionTypeNode([ - typ, - factory.createLiteralTypeNode(factory.createNull()), - ]); -} - -export function preamble(queries: unknown) { - return [ - factory.createImportDeclaration( - undefined, - factory.createImportClause( - false, - undefined, - factory.createNamedImports([ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("Sql") - ), - ]) - ), - factory.createStringLiteral("postgres"), - undefined - ), - ]; -} - function funcParamsDecl(iface: string | undefined, params: Parameter[]) { let funcParams = [ factory.createParameterDeclaration( @@ -312,193 +44,364 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) { return funcParams; } -export function execDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -) { - const funcParams = funcParamsDecl(argIface, params); +export class Driver { + columnType(column?: Column): TypeNode { + if (column === undefined || column.type === undefined) { + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + // Some of the type names have the `pgcatalog.` prefix. Remove this. + let typeName = column.type.name; + const pgCatalog = "pg_catalog."; + if (typeName.startsWith(pgCatalog)) { + typeName = typeName.slice(pgCatalog.length); + } + let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); + switch (typeName) { + case "aclitem": { + // string + break; + } + case "bigserial": { + // string + break; + } + case "bit": { + // string + break; + } + case "bool": { + typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); + break; + } + case "box": { + // string + break; + } + case "bpchar": { + // string + break; + } + case "bytea": { + // TODO: Is this correct or node-specific? + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "cid": { + // string + break; + } + case "cidr": { + // string + break; + } + case "circle": { + // string + break; + } + case "date": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "float4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "float8": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "inet": { + // string + break; + } + case "int2": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "int4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "int8": { + // string + break; + } + case "interval": { + // string + break; + } + case "json": { + typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + break; + } + case "jsonb": { + typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + break; + } + case "line": { + // string + break; + } + case "lseg": { + // string + break; + } + case "madaddr": { + // string + break; + } + case "madaddr8": { + // string + break; + } + case "money": { + // string + break; + } + case "oid": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "path": { + // string + break; + } + case "pg_node_tree": { + // string + break; + } + case "pg_snapshot": { + // string + break; + } + case "point": { + // string + break; + } + case "polygon": { + // string + break; + } + case "regproc": { + // string + break; + } + case "regrole": { + // string + break; + } + case "serial": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial2": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial4": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "serial8": { + // string + break; + } + case "smallserial": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "tid": { + // string + break; + } + case "text": { + // string + break; + } + case "time": { + // string + break; + } + case "timetz": { + // string + break; + } + case "timestamp": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "timestamptz": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "tsquery": { + // string + break; + } + case "tsvector": { + // string + break; + } + case "txid_snapshot": { + // string + break; + } + case "uuid": { + // string + break; + } + case "varbit": { + // string + break; + } + case "varchar": { + // string + break; + } + case "xid": { + // string + break; + } + case "xml": { + // string + break; + } + default: { + log(`unknown type ${column.type?.name}`); + break; + } + } + if (column.isArray || column.arrayDims > 0) { + let dims = Math.max(column.arrayDims || 1); + for (let i = 0; i < dims; i++) { + typ = factory.createArrayTypeNode(typ); + } + } + if (column.notNull) { + return typ; + } + return factory.createUnionTypeNode([ + typ, + factory.createLiteralTypeNode(factory.createNull()), + ]); + } - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), - ]), - factory.createBlock( - [ - factory.createExpressionStatement( - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("sql"), - factory.createIdentifier("unsafe") - ), + preamble(queries: unknown) { + return [ + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, + undefined, + factory.createNamedImports([ + factory.createImportSpecifier( + false, undefined, - [ - factory.createIdentifier(queryName), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier(argName(i, param.column)) - ) - ), - false - ), - ] - ) - ) + factory.createIdentifier("Sql") + ), + ]) ), - ], - true - ) - ); -} + factory.createStringLiteral("postgres"), + undefined + ), + ]; + } -export function manyDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + execDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ) - ), - ]), - factory.createBlock( + return factory.createFunctionDeclaration( [ - factory.createReturnStatement( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("sql"), - factory.createIdentifier("unsafe") - ), - undefined, - [ - factory.createIdentifier(queryName), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier(argName(i, param.column)) - ) - ), - false - ), - ] - ), - factory.createIdentifier("values") - ), - undefined, - undefined - ) - ), - factory.createIdentifier("map") - ), - undefined, - [ - factory.createArrowFunction( - undefined, + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), + ]), + factory.createBlock( + [ + factory.createExpressionStatement( + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("sql"), + factory.createIdentifier("unsafe") + ), undefined, [ - factory.createParameterDeclaration( - undefined, - undefined, - "row" - ), - ], - undefined, - factory.createToken(SyntaxKind.EqualsGreaterThanToken), - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( - factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) + factory.createIdentifier(queryName), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) ) - ) + ), + false ), - true - ) - ), - ] - ) - ), - ], - true - ) - ); -} + ] + ) + ) + ), + ], + true + ) + ); + } -export function oneDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + manyDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createUnionTypeNode([ - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined + ) ), - factory.createLiteralTypeNode(factory.createNull()), ]), - ]), - factory.createBlock( - [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("rows"), - undefined, - undefined, + factory.createBlock( + [ + factory.createReturnStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression( factory.createAwaitExpression( factory.createCallExpression( factory.createPropertyAccessExpression( @@ -528,94 +431,192 @@ export function oneDecl( undefined, undefined ) - ) + ), + factory.createIdentifier("map") ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createIfStatement( - factory.createBinaryExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("rows"), - factory.createIdentifier("length") - ), - factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), - factory.createNumericLiteral("1") + undefined, + [ + factory.createArrowFunction( + undefined, + undefined, + [ + factory.createParameterDeclaration( + undefined, + undefined, + "row" + ), + ], + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) + ) + ) + ), + true + ) + ), + ] + ) ), - factory.createBlock( - [factory.createReturnStatement(factory.createNull())], - true + ], + true + ) + ); + } + + oneDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createUnionTypeNode([ + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined ), - undefined - ), - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - "row", - undefined, - undefined, - factory.createElementAccessExpression( + factory.createLiteralTypeNode(factory.createNull()), + ]), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( factory.createIdentifier("rows"), - factory.createNumericLiteral("0") - ) + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("sql"), + factory.createIdentifier("unsafe") + ), + undefined, + [ + factory.createIdentifier(queryName), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) + ) + ), + false + ), + ] + ), + factory.createIdentifier("values") + ), + undefined, + undefined + ) + ) + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createIfStatement( + factory.createBinaryExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("rows"), + factory.createIdentifier("length") ), - ], - NodeFlags.Const - ) - ), - factory.createIfStatement( - factory.createPrefixUnaryExpression( - SyntaxKind.ExclamationToken, - factory.createIdentifier("row") + factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), + factory.createNumericLiteral("1") + ), + factory.createBlock( + [factory.createReturnStatement(factory.createNull())], + true + ), + undefined ), - factory.createBlock( - [factory.createReturnStatement(factory.createNull())], - true + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + "row", + undefined, + undefined, + factory.createElementAccessExpression( + factory.createIdentifier("rows"), + factory.createNumericLiteral("0") + ) + ), + ], + NodeFlags.Const + ) ), - undefined - ), - factory.createReturnStatement( - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( - factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) - ) - ) + factory.createIfStatement( + factory.createPrefixUnaryExpression( + SyntaxKind.ExclamationToken, + factory.createIdentifier("row") ), - true - ) - ), - ], - true - ) - ); -} + factory.createBlock( + [factory.createReturnStatement(factory.createNull())], + true + ), + undefined + ), + factory.createReturnStatement( + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) + ) + ) + ), + true + ) + ), + ], + true + ) + ); + } -export function execlastidDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -): FunctionDeclaration { - throw new Error('postgres driver currently does not support :execlastid') + execlastidDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ): FunctionDeclaration { + throw new Error("postgres driver currently does not support :execlastid"); + } } - -export default { - columnType, - preamble, - execDecl, - manyDecl, - oneDecl, - execlastidDecl -}; From 35e8ad14d20a58e7eb3e590d7dd2c9259adb30c9 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Sat, 2 Mar 2024 20:43:11 -0800 Subject: [PATCH 3/3] Change driver from module to class --- src/app.ts | 8 +- src/drivers/better-sqlite3.ts | 730 +++++++++--------- src/drivers/mysql2.ts | 1299 ++++++++++++++++----------------- 3 files changed, 1012 insertions(+), 1025 deletions(-) diff --git a/src/app.ts b/src/app.ts index 842ba12..e1dec6f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -28,10 +28,10 @@ import { } from "./gen/plugin/codegen_pb"; import { argName, colName } from "./drivers/utlis"; -import betterSQLite3 from "./drivers/better-sqlite3"; +import { Driver as Sqlite3Driver } from "./drivers/better-sqlite3"; import { Driver as PgDriver } from "./drivers/pg"; import { Driver as PostgresDriver } from "./drivers/postgres"; -import mysql2 from "./drivers/mysql2"; +import { Driver as MysqlDriver } from "./drivers/mysql2"; // Read input from stdin const input = readInput(); @@ -81,7 +81,7 @@ interface Driver { function createNodeGenerator(driver?: string): Driver { switch (driver) { case "mysql2": { - return mysql2; + return new MysqlDriver(); } case "pg": { return new PgDriver(); @@ -90,7 +90,7 @@ function createNodeGenerator(driver?: string): Driver { return new PostgresDriver(); } case "better-sqlite3": { - return betterSQLite3; + return new Sqlite3Driver(); } } throw new Error(`unknown driver: ${driver}`); diff --git a/src/drivers/better-sqlite3.ts b/src/drivers/better-sqlite3.ts index 8665b91..c6210e8 100644 --- a/src/drivers/better-sqlite3.ts +++ b/src/drivers/better-sqlite3.ts @@ -1,96 +1,15 @@ -import { SyntaxKind, NodeFlags, Node, TypeNode, factory, FunctionDeclaration } from "typescript"; +import { + SyntaxKind, + NodeFlags, + Node, + TypeNode, + factory, + FunctionDeclaration, +} from "typescript"; import { Parameter, Column, Query } from "../gen/plugin/codegen_pb"; import { argName } from "./utlis"; -/** - * {@link https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/api.md#binding-parameters} - * {@link https://github.com/sqlc-dev/sqlc/blob/v1.25.0/internal/codegen/golang/sqlite_type.go} - */ -export function columnType(column?: Column): TypeNode { - if (column === undefined || column.type === undefined) { - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - } - - let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - switch (column.type.name) { - case "int": - case "integer": - case "tinyint": - case "smallint": - case "mediumint": - case "bigint": - case "unsignedbigint": - case "int2": - case "int8": { - // TODO: Improve `BigInt` handling (https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/integer.md) - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "blob": { - // TODO: Is this correct or node-specific? - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "real": - case "double": - case "doubleprecision": - case "float": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "boolean": - case "bool": { - typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); - break; - } - case "date": - case "datetime": - case "timestamp": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - } - - if (column.notNull) { - return typ; - } - - return factory.createUnionTypeNode([ - typ, - factory.createLiteralTypeNode(factory.createNull()), - ]); -} - -export function preamble(queries: Query[]) { - const imports: Node[] = [ - factory.createImportDeclaration( - undefined, - factory.createImportClause( - false, - undefined, - factory.createNamedImports([ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("Database") - ), - ]) - ), - factory.createStringLiteral("better-sqlite3"), - undefined - ), - ]; - - return imports; -} - function funcParamsDecl(iface: string | undefined, params: Parameter[]) { let funcParams = [ factory.createParameterDeclaration( @@ -125,322 +44,395 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) { return funcParams; } -export function execDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -) { - const funcParams = funcParamsDecl(argIface, params); +export class Driver { + /** + * {@link https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/api.md#binding-parameters} + * {@link https://github.com/sqlc-dev/sqlc/blob/v1.25.0/internal/codegen/golang/sqlite_type.go} + */ + columnType(column?: Column): TypeNode { + if (column === undefined || column.type === undefined) { + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + } - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), - ]), - factory.createBlock( - [ - factory.createVariableStatement( + let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + switch (column.type.name) { + case "int": + case "integer": + case "tinyint": + case "smallint": + case "mediumint": + case "bigint": + case "unsignedbigint": + case "int2": + case "int8": { + // TODO: Improve `BigInt` handling (https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/integer.md) + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "blob": { + // TODO: Is this correct or node-specific? + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "real": + case "double": + case "doubleprecision": + case "float": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "boolean": + case "bool": { + typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); + break; + } + case "date": + case "datetime": + case "timestamp": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + } + + if (column.notNull) { + return typ; + } + + return factory.createUnionTypeNode([ + typ, + factory.createLiteralTypeNode(factory.createNull()), + ]); + } + + preamble(queries: Query[]) { + const imports: Node[] = [ + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("stmt"), - undefined, - undefined, - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("database"), - factory.createIdentifier("prepare") - ), - undefined, - [ - factory.createIdentifier(queryName) - ] - ) - ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - // NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - // NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createExpressionStatement( - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("stmt"), - factory.createIdentifier("run") - ), + factory.createNamedImports([ + factory.createImportSpecifier( + false, undefined, - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier(argName(i, param.column)) - ) - ), - ) - ) + factory.createIdentifier("Database") + ), + ]) ), - ], - true - ) - ); -} + factory.createStringLiteral("better-sqlite3"), + undefined + ), + ]; -export function oneDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + return imports; + } - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createUnionTypeNode([ - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ), - factory.createLiteralTypeNode(factory.createNull()), - ]), - ]), - factory.createBlock( + execDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("stmt"), - undefined, + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("stmt"), + undefined, + undefined, + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("database"), + factory.createIdentifier("prepare") + ), + undefined, + [factory.createIdentifier(queryName)] + ) + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + // NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + // NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createExpressionStatement( + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("stmt"), + factory.createIdentifier("run") + ), undefined, - factory.createCallExpression( + params.map((param, i) => factory.createPropertyAccessExpression( - factory.createIdentifier("database"), - factory.createIdentifier("prepare") - ), - undefined, - [ - factory.createIdentifier(queryName) - ] + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) + ) ) - ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - // NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - // NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("result"), - undefined, - undefined, - factory.createAwaitExpression( + ) + ) + ), + ], + true + ) + ); + } + + oneDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createUnionTypeNode([ + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined + ), + factory.createLiteralTypeNode(factory.createNull()), + ]), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("stmt"), + undefined, + undefined, factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("stmt"), - factory.createIdentifier("get") + factory.createIdentifier("database"), + factory.createIdentifier("prepare") ), undefined, - params.map((param, i) => + [factory.createIdentifier(queryName)] + ) + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + // NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + // NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("result"), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) + factory.createIdentifier("stmt"), + factory.createIdentifier("get") + ), + undefined, + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) ) ) - ), + ) ) - ) - ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createIfStatement( - factory.createBinaryExpression( - factory.createIdentifier("result"), - factory.createToken(SyntaxKind.EqualsEqualsToken), - factory.createIdentifier("undefined") + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) ), - factory.createBlock( - [factory.createReturnStatement(factory.createNull())], - true + factory.createIfStatement( + factory.createBinaryExpression( + factory.createIdentifier("result"), + factory.createToken(SyntaxKind.EqualsEqualsToken), + factory.createIdentifier("undefined") + ), + factory.createBlock( + [factory.createReturnStatement(factory.createNull())], + true + ), + undefined ), - undefined - ), - factory.createReturnStatement( - factory.createAsExpression( - factory.createIdentifier("result"), - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined + factory.createReturnStatement( + factory.createAsExpression( + factory.createIdentifier("result"), + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined + ) ) - ) - ), - ], - true - ) - ); -} + ), + ], + true + ) + ); + } -export function manyDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + manyDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ) - ), - ]), - factory.createBlock( + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("stmt"), - undefined, - undefined, - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("database"), - factory.createIdentifier("prepare") - ), - undefined, - [ - factory.createIdentifier(queryName) - ] - ) - ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - // NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - // NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined ) ), - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("result"), - undefined, - undefined, - factory.createAwaitExpression( + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("stmt"), + undefined, + undefined, factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("stmt"), - factory.createIdentifier("all") + factory.createIdentifier("database"), + factory.createIdentifier("prepare") ), undefined, - params.map((param, i) => + [factory.createIdentifier(queryName)] + ) + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + // NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + // NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("result"), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) + factory.createIdentifier("stmt"), + factory.createIdentifier("all") + ), + undefined, + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) ) ) - ), + ) ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createReturnStatement( + factory.createAsExpression( + factory.createIdentifier("result"), + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined ) - ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createReturnStatement( - factory.createAsExpression( - factory.createIdentifier("result"), - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined ) ) - ) - ), - ], - true - ) - ); -} + ), + ], + true + ) + ); + } -export function execlastidDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -): FunctionDeclaration { - throw new Error('better-sqlite3 driver currently does not support :execlastid') + execlastidDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ): FunctionDeclaration { + throw new Error( + "better-sqlite3 driver currently does not support :execlastid" + ); + } } - -export default { - columnType, - execDecl, - manyDecl, - oneDecl, - preamble, - execlastidDecl, -}; diff --git a/src/drivers/mysql2.ts b/src/drivers/mysql2.ts index bc052bb..731db8d 100644 --- a/src/drivers/mysql2.ts +++ b/src/drivers/mysql2.ts @@ -5,218 +5,6 @@ import { SyntaxKind, NodeFlags, TypeNode, factory } from "typescript"; import { Parameter, Column, Query } from "../gen/plugin/codegen_pb"; import { argName, colName } from "./utlis"; -export function columnType(column?: Column): TypeNode { - if (column === undefined || column.type === undefined) { - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - } - let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); - - switch (column.type.name) { - case "bigint": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "binary": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "bit": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "blob": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "char": { - // string - break; - } - case "date": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "datetime": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "decimal": { - // string - break; - } - case "double": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "float": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "int": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "longblob": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "longtext": { - // string - break; - } - case "mediumblob": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "mediumint": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "mediumtext": { - // string - break; - } - case "smallint": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "text": { - // string - break; - } - case "time": { - // string - break; - } - case "timestamp": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Date"), - undefined - ); - break; - } - case "tinyblob": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "tinyint": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - case "tinytext": { - // string - break; - } - case "json": { - typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - break; - } - case "varbinary": { - typ = factory.createTypeReferenceNode( - factory.createIdentifier("Buffer"), - undefined - ); - break; - } - case "varchar": { - // string - break; - } - case "year": { - typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); - break; - } - // default: { - // const output = new TextEncoder().encode(column.type.name + "\n"); - // const buffer = new Uint8Array(output); - // writeFileSync(STDIO.Stderr, buffer); - // } - } - if (column.notNull) { - return typ; - } - return factory.createUnionTypeNode([ - typ, - factory.createLiteralTypeNode(factory.createNull()), - ]); -} - -export function preamble(queries: Query[]) { - const hasExecLastIdCmd = queries.some((query) => query.cmd === ":execlastid"); - return [ - factory.createImportDeclaration( - undefined, - factory.createImportClause( - false, - factory.createIdentifier("mysql"), - factory.createNamedImports([ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("RowDataPacket") - ), - ...(hasExecLastIdCmd - ? [ - factory.createImportSpecifier( - false, - undefined, - factory.createIdentifier("ResultSetHeader") - ), - ] - : []), - ]) - ), - factory.createStringLiteral("mysql2/promise"), - undefined - ), - factory.createTypeAliasDeclaration( - undefined, - factory.createIdentifier("Client"), - undefined, - factory.createUnionTypeNode([ - factory.createTypeReferenceNode( - factory.createQualifiedName( - factory.createIdentifier("mysql"), - factory.createIdentifier("Connection") - ), - undefined - ), - factory.createTypeReferenceNode( - factory.createQualifiedName( - factory.createIdentifier("mysql"), - factory.createIdentifier("Pool") - ), - undefined - ), - ]) - ), - ]; -} - function funcParamsDecl(iface: string | undefined, params: Parameter[]) { let funcParams = [ factory.createParameterDeclaration( @@ -251,484 +39,691 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) { return funcParams; } -export function execDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -) { - const funcParams = funcParamsDecl(argIface, params); +export class Driver { + columnType(column?: Column): TypeNode { + if (column === undefined || column.type === undefined) { + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), - ]), - factory.createBlock( - [ - factory.createExpressionStatement( - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") - ), + switch (column.type.name) { + case "bigint": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "binary": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "bit": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "blob": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "char": { + // string + break; + } + case "date": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "datetime": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "decimal": { + // string + break; + } + case "double": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "float": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "int": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "longblob": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "longtext": { + // string + break; + } + case "mediumblob": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "mediumint": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "mediumtext": { + // string + break; + } + case "smallint": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "text": { + // string + break; + } + case "time": { + // string + break; + } + case "timestamp": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Date"), + undefined + ); + break; + } + case "tinyblob": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "tinyint": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + case "tinytext": { + // string + break; + } + case "json": { + typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + break; + } + case "varbinary": { + typ = factory.createTypeReferenceNode( + factory.createIdentifier("Buffer"), + undefined + ); + break; + } + case "varchar": { + // string + break; + } + case "year": { + typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + break; + } + // default: { + // const output = new TextEncoder().encode(column.type.name + "\n"); + // const buffer = new Uint8Array(output); + // writeFileSync(STDIO.Stderr, buffer); + // } + } + if (column.notNull) { + return typ; + } + return factory.createUnionTypeNode([ + typ, + factory.createLiteralTypeNode(factory.createNull()), + ]); + } + + preamble(queries: Query[]) { + const hasExecLastIdCmd = queries.some( + (query) => query.cmd === ":execlastid" + ); + return [ + factory.createImportDeclaration( + undefined, + factory.createImportClause( + false, + factory.createIdentifier("mysql"), + factory.createNamedImports([ + factory.createImportSpecifier( + false, undefined, - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("sql"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier(argName(i, param.column)) - ) - ), - false - ) - ), - ], - true - ), - ] - ) - ) + factory.createIdentifier("RowDataPacket") + ), + ...(hasExecLastIdCmd + ? [ + factory.createImportSpecifier( + false, + undefined, + factory.createIdentifier("ResultSetHeader") + ), + ] + : []), + ]) ), - ], - true - ) - ); -} + factory.createStringLiteral("mysql2/promise"), + undefined + ), + factory.createTypeAliasDeclaration( + undefined, + factory.createIdentifier("Client"), + undefined, + factory.createUnionTypeNode([ + factory.createTypeReferenceNode( + factory.createQualifiedName( + factory.createIdentifier("mysql"), + factory.createIdentifier("Connection") + ), + undefined + ), + factory.createTypeReferenceNode( + factory.createQualifiedName( + factory.createIdentifier("mysql"), + factory.createIdentifier("Pool") + ), + undefined + ), + ]) + ), + ]; + } -export function manyDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + execDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ) - ), - ]), - factory.createBlock( + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createArrayBindingPattern([ - factory.createBindingElement( - undefined, - undefined, - factory.createIdentifier("rows"), - undefined - ), - ]), - undefined, + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), + ]), + factory.createBlock( + [ + factory.createExpressionStatement( + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") + ), undefined, - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") - ), + [ + factory.createObjectLiteralExpression( [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier("RowDataPacket"), - undefined - ) + factory.createPropertyAssignment( + factory.createIdentifier("sql"), + factory.createIdentifier(queryName) ), - ], - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("sql"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) - ) - ) - ), - false + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier(argName(i, param.column)) ) ), - factory.createPropertyAssignment( - factory.createIdentifier("rowsAsArray"), - factory.createTrue() - ), - ], - true + false + ) ), - ] - ) - ) - ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags + ], + true + ), + ] + ) + ) + ), + ], + true + ) + ); + } + + manyDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); + + return factory.createFunctionDeclaration( + [ + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined ) ), - factory.createReturnStatement( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("rows"), - factory.createIdentifier("map") - ), + ]), + factory.createBlock( + [ + factory.createVariableStatement( undefined, - [ - factory.createArrowFunction( - undefined, - undefined, - [ - factory.createParameterDeclaration( - undefined, - undefined, - factory.createIdentifier("row"), - undefined, - undefined, - undefined - ), - ], - undefined, - factory.createToken(SyntaxKind.EqualsGreaterThanToken), - factory.createBlock( - [ - factory.createReturnStatement( - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( - factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) - ) + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createArrayBindingPattern([ + factory.createBindingElement( + undefined, + undefined, + factory.createIdentifier("rows"), + undefined + ), + ]), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") + ), + [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier("RowDataPacket"), + undefined ) ), - true - ) + ], + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier("sql"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) + ) + ), + false + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("rowsAsArray"), + factory.createTrue() + ), + ], + true + ), + ] + ) + ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createReturnStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("rows"), + factory.createIdentifier("map") + ), + undefined, + [ + factory.createArrowFunction( + undefined, + undefined, + [ + factory.createParameterDeclaration( + undefined, + undefined, + factory.createIdentifier("row"), + undefined, + undefined, + undefined ), ], - true - ) - ), - ] - ) - ), - ], - true - ) - ); -} + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createBlock( + [ + factory.createReturnStatement( + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) + ) + ) + ), + true + ) + ), + ], + true + ) + ), + ] + ) + ), + ], + true + ) + ); + } -export function oneDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - returnIface: string, - params: Parameter[], - columns: Column[] -) { - const funcParams = funcParamsDecl(argIface, params); + oneDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + returnIface: string, + params: Parameter[], + columns: Column[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createUnionTypeNode([ - factory.createTypeReferenceNode( - factory.createIdentifier(returnIface), - undefined - ), - factory.createLiteralTypeNode(factory.createNull()), - ]), - ]), - factory.createBlock( + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createArrayBindingPattern([ - factory.createBindingElement( - undefined, - undefined, - factory.createIdentifier("rows"), - undefined - ), - ]), - undefined, - undefined, - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createUnionTypeNode([ + factory.createTypeReferenceNode( + factory.createIdentifier(returnIface), + undefined + ), + factory.createLiteralTypeNode(factory.createNull()), + ]), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createArrayBindingPattern([ + factory.createBindingElement( + undefined, + undefined, + factory.createIdentifier("rows"), + undefined ), - [ - factory.createArrayTypeNode( - factory.createTypeReferenceNode( - factory.createIdentifier("RowDataPacket"), - undefined - ) + ]), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") ), - ], - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("sql"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) + [ + factory.createArrayTypeNode( + factory.createTypeReferenceNode( + factory.createIdentifier("RowDataPacket"), + undefined + ) + ), + ], + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier("sql"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) ) - ) - ), - false - ) - ), - factory.createPropertyAssignment( - factory.createIdentifier("rowsAsArray"), - factory.createTrue() - ), - ], - true - ), - ] + ), + false + ) + ), + factory.createPropertyAssignment( + factory.createIdentifier("rowsAsArray"), + factory.createTrue() + ), + ], + true + ), + ] + ) ) - ) + ), + ], + NodeFlags.Const | + // ts.NodeFlags.Constant | + NodeFlags.AwaitContext | + // ts.NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createIfStatement( + factory.createBinaryExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("rows"), + factory.createIdentifier("length") ), - ], - NodeFlags.Const | - // ts.NodeFlags.Constant | - NodeFlags.AwaitContext | - // ts.NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createIfStatement( - factory.createBinaryExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("rows"), - factory.createIdentifier("length") + factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), + factory.createNumericLiteral("1") + ), + factory.createBlock( + [factory.createReturnStatement(factory.createNull())], + true ), - factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), - factory.createNumericLiteral("1") + undefined ), - factory.createBlock( - [factory.createReturnStatement(factory.createNull())], - true + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier("row"), + undefined, + undefined, + factory.createElementAccessExpression( + factory.createIdentifier("rows"), + factory.createNumericLiteral("0") + ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) ), - undefined - ), - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createIdentifier("row"), - undefined, - undefined, - factory.createElementAccessExpression( - factory.createIdentifier("rows"), - factory.createNumericLiteral("0") + factory.createReturnStatement( + factory.createObjectLiteralExpression( + columns.map((col, i) => + factory.createPropertyAssignment( + factory.createIdentifier(colName(i, col)), + factory.createElementAccessExpression( + factory.createIdentifier("row"), + factory.createNumericLiteral(`${i}`) + ) ) ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createReturnStatement( - factory.createObjectLiteralExpression( - columns.map((col, i) => - factory.createPropertyAssignment( - factory.createIdentifier(colName(i, col)), - factory.createElementAccessExpression( - factory.createIdentifier("row"), - factory.createNumericLiteral(`${i}`) - ) - ) - ), - true - ) - ), - ], - true - ) - ); -} + true + ) + ), + ], + true + ) + ); + } -export function execlastidDecl( - funcName: string, - queryName: string, - argIface: string | undefined, - params: Parameter[] -) { - const funcParams = funcParamsDecl(argIface, params); + execlastidDecl( + funcName: string, + queryName: string, + argIface: string | undefined, + params: Parameter[] + ) { + const funcParams = funcParamsDecl(argIface, params); - return factory.createFunctionDeclaration( - [ - factory.createToken(SyntaxKind.ExportKeyword), - factory.createToken(SyntaxKind.AsyncKeyword), - ], - undefined, - factory.createIdentifier(funcName), - undefined, - funcParams, - factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ - factory.createTypeReferenceNode("number", undefined), - ]), - factory.createBlock( + return factory.createFunctionDeclaration( [ - factory.createVariableStatement( - undefined, - factory.createVariableDeclarationList( - [ - factory.createVariableDeclaration( - factory.createArrayBindingPattern([ - factory.createBindingElement( - undefined, - undefined, - factory.createIdentifier("result"), - undefined - ), - ]), - undefined, - undefined, - factory.createAwaitExpression( - factory.createCallExpression( - factory.createPropertyAccessExpression( - factory.createIdentifier("client"), - factory.createIdentifier("query") + factory.createToken(SyntaxKind.ExportKeyword), + factory.createToken(SyntaxKind.AsyncKeyword), + ], + undefined, + factory.createIdentifier(funcName), + undefined, + funcParams, + factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ + factory.createTypeReferenceNode("number", undefined), + ]), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createArrayBindingPattern([ + factory.createBindingElement( + undefined, + undefined, + factory.createIdentifier("result"), + undefined ), - [ - factory.createTypeReferenceNode( - factory.createIdentifier("ResultSetHeader"), - undefined + ]), + undefined, + undefined, + factory.createAwaitExpression( + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("client"), + factory.createIdentifier("query") ), - ], - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier("sql"), - factory.createIdentifier(queryName) - ), - factory.createPropertyAssignment( - factory.createIdentifier("values"), - factory.createArrayLiteralExpression( - params.map((param, i) => - factory.createPropertyAccessExpression( - factory.createIdentifier("args"), - factory.createIdentifier( - argName(i, param.column) + [ + factory.createTypeReferenceNode( + factory.createIdentifier("ResultSetHeader"), + undefined + ), + ], + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier("sql"), + factory.createIdentifier(queryName) + ), + factory.createPropertyAssignment( + factory.createIdentifier("values"), + factory.createArrayLiteralExpression( + params.map((param, i) => + factory.createPropertyAccessExpression( + factory.createIdentifier("args"), + factory.createIdentifier( + argName(i, param.column) + ) ) - ) - ), - false - ) - ), - ], - true - ), - ] + ), + false + ) + ), + ], + true + ), + ] + ) ) - ) + ), + ], + NodeFlags.Const | + // NodeFlags.Constant | + NodeFlags.AwaitContext | + // NodeFlags.Constant | + NodeFlags.ContextFlags | + NodeFlags.TypeExcludesFlags + ) + ), + factory.createReturnStatement( + factory.createBinaryExpression( + factory.createPropertyAccessChain( + factory.createIdentifier("result"), + factory.createToken(SyntaxKind.QuestionDotToken), + factory.createIdentifier("insertId") ), - ], - NodeFlags.Const | - // NodeFlags.Constant | - NodeFlags.AwaitContext | - // NodeFlags.Constant | - NodeFlags.ContextFlags | - NodeFlags.TypeExcludesFlags - ) - ), - factory.createReturnStatement( - factory.createBinaryExpression( - factory.createPropertyAccessChain( - factory.createIdentifier("result"), - factory.createToken(SyntaxKind.QuestionDotToken), - factory.createIdentifier("insertId") - ), - factory.createToken(SyntaxKind.QuestionQuestionToken), - factory.createNumericLiteral(0) - ) - ), - ], - true - ) - ); + factory.createToken(SyntaxKind.QuestionQuestionToken), + factory.createNumericLiteral(0) + ) + ), + ], + true + ) + ); + } } - -export default { - columnType, - preamble, - execDecl, - manyDecl, - oneDecl, - execlastidDecl, -};