mirror of
https://github.com/theoludwig/kysely-typegen.git
synced 2026-10-09 21:20:04 +02:00
103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
import { sql } from "kysely"
|
|
|
|
import type { IntrospectedEnums } from "./index.ts"
|
|
import { KyselyTypegenDialect } from "./index.ts"
|
|
|
|
export class KyselyTypegenMySQLDialect extends KyselyTypegenDialect {
|
|
// Keys are lowercase values returned by information_schema.COLUMNS.DATA_TYPE,
|
|
// which is what Kysely's MysqlIntrospector forwards as column.dataType.
|
|
public override readonly scalars: Record<string, string> = {
|
|
bigint: "Int8",
|
|
binary: "Buffer",
|
|
bit: "string",
|
|
blob: "Buffer",
|
|
bool: "boolean",
|
|
boolean: "boolean",
|
|
char: "string",
|
|
date: "Timestamp",
|
|
datetime: "Timestamp",
|
|
decimal: "Numeric",
|
|
double: "number",
|
|
enum: "string",
|
|
float: "number",
|
|
int: "number",
|
|
json: "Json",
|
|
longblob: "Buffer",
|
|
longtext: "string",
|
|
mediumblob: "Buffer",
|
|
mediumint: "number",
|
|
mediumtext: "string",
|
|
numeric: "Numeric",
|
|
set: "string",
|
|
smallint: "number",
|
|
text: "string",
|
|
time: "string",
|
|
timestamp: "Timestamp",
|
|
tinyblob: "Buffer",
|
|
tinyint: "number",
|
|
tinytext: "string",
|
|
varbinary: "Buffer",
|
|
varchar: "string",
|
|
year: "number",
|
|
}
|
|
|
|
protected override async introspectEnums(): Promise<IntrospectedEnums> {
|
|
const rows = await this.database
|
|
.withoutPlugins()
|
|
.selectFrom("information_schema.columns as columns")
|
|
.select([
|
|
"columns.TABLE_NAME as tableName",
|
|
"columns.COLUMN_NAME as columnName",
|
|
"columns.COLUMN_TYPE as columnType",
|
|
])
|
|
.where("columns.TABLE_SCHEMA", "=", sql`database()`)
|
|
.where("columns.DATA_TYPE", "in", ["enum", "set"])
|
|
.$castTo<{ tableName: string; columnName: string; columnType: string }>()
|
|
.execute()
|
|
|
|
const inline = new Map<string, string[]>()
|
|
for (const row of rows) {
|
|
inline.set(`${row.tableName}.${row.columnName}`, parseMysqlEnumColumnType(row.columnType))
|
|
}
|
|
return { named: [], inline }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses MySQL `enum(...)` / `set(...)` column type definitions into the list of declared values. MySQL doubles single quotes inside string literals.
|
|
*
|
|
* @example
|
|
* parseMysqlEnumColumnType("enum('a','b','c''d')") // ["a", "b", "c'd"]
|
|
*/
|
|
const parseMysqlEnumColumnType = (columnType: string): string[] => {
|
|
const open = columnType.indexOf("(")
|
|
const close = columnType.lastIndexOf(")")
|
|
if (open === -1 || close === -1 || close <= open) {
|
|
return []
|
|
}
|
|
const inner = columnType.slice(open + 1, close)
|
|
const values: string[] = []
|
|
let current = ""
|
|
let insideString = false
|
|
for (let index = 0; index < inner.length; index++) {
|
|
const character = inner[index]
|
|
if (insideString) {
|
|
if (character === "'" && inner[index + 1] === "'") {
|
|
current += "'"
|
|
index++
|
|
continue
|
|
}
|
|
if (character === "'") {
|
|
insideString = false
|
|
values.push(current)
|
|
current = ""
|
|
continue
|
|
}
|
|
current += character
|
|
} else if (character === "'") {
|
|
insideString = true
|
|
}
|
|
}
|
|
return values
|
|
}
|