db-studio 1.7.9 → 1.7.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +86 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../shared/src/constants/chat.ts","../../shared/src/constants/column-types-mysql.ts","../../shared/src/constants/column-types-pgsql.ts","../../shared/src/constants/defaults.ts","../../shared/src/constants/links.ts","../../shared/src/constants/meta.ts","../../shared/src/constants/proxy-limits.ts","../../shared/src/constants/index.ts","../../shared/src/types/database.types.ts","../../shared/src/types/add-column.types.ts","../../shared/src/types/add-record.types.ts","../../shared/src/types/delete-column.types.ts","../../shared/src/types/alter-column.types.ts","../../shared/src/types/api-response.types.ts","../../shared/src/types/bulk-insert-records.type.ts","../../shared/src/types/chat.types.ts","../../shared/src/types/cmd-args.types.ts","../../shared/src/types/column-info.types.ts","../../shared/src/types/column.type.ts","../../shared/src/types/create-table.types.ts","../../shared/src/types/database-list.types.ts","../../shared/src/types/database-schema.type.ts","../../shared/src/types/delete-record.types.ts","../../shared/src/types/delete-table.types.ts","../../shared/src/types/execute-query.types.ts","../../shared/src/types/export-table.types.ts","../../shared/src/types/rate-limit-response.type.ts","../../shared/src/types/rename-column.types.ts","../../shared/src/types/table-data.types.ts","../../shared/src/types/table-info.type.ts","../../shared/src/types/table-schema.types.ts","../../shared/src/types/update-recors.types.ts","../../shared/src/types/index.ts","../src/middlewares/error-handler.ts","../src/db-manager.ts","../src/dao/mongo/tables.dao.ts","../src/dao/mongo/schema.dao.ts","../src/db.ts","../src/dao/table-columns.dao.ts","../src/dao/table-details-schema.ts","../src/utils/system-prompt-generator.ts","../src/routes/chat.routes.ts","../src/dao/add-record.dao.ts","../src/dao/bulk-insert-records.dao.ts","../src/dao/create-table.dao.ts","../src/utils/parse-database-url.ts","../src/dao/database-list.dao.ts","../src/dao/delete-column.dao.ts","../src/dao/delete-records.dao.ts","../src/dao/delete-table.dao.ts","../src/dao/export-table.dao.ts","../src/dao/mongo/bulk-insert-records.mongo.dao.ts","../src/dao/mongo/database-list.dao.ts","../src/dao/mongo/query.dao.ts","../src/dao/mongo/records.dao.ts","../src/dao/mongo/table-schema.mongo.dao.ts","../src/dao/mssql/table-columns.mssql.dao.ts","../src/dao/mssql/add-record.mssql.dao.ts","../src/dao/mssql/bulk-insert-records.mssql.dao.ts","../src/dao/mssql/create-table.mssql.dao.ts","../src/dao/mssql/database-list.mssql.dao.ts","../src/dao/mssql/delete-column.mssql.dao.ts","../src/dao/mssql/delete-records.mssql.dao.ts","../src/dao/mssql/delete-table.mssql.dao.ts","../src/dao/mssql/export-table.mssql.dao.ts","../src/dao/mssql/query.mssql.dao.ts","../src/dao/mssql/table-list.mssql.dao.ts","../src/dao/mssql/table-schema.mssql.dao.ts","../src/dao/mssql/tables-data.mssql.dao.ts","../src/dao/mssql/update-records.mssql.dao.ts","../src/dao/mysql/table-columns.mysql.dao.ts","../src/dao/mysql/add-record.mysql.dao.ts","../src/dao/mysql/bulk-insert-records.mysql.dao.ts","../src/dao/mysql/mysql-column.utils.ts","../src/dao/mysql/create-table.mysql.dao.ts","../src/dao/mysql/database-list.mysql.dao.ts","../src/dao/mysql/delete-column.mysql.dao.ts","../src/dao/mysql/delete-records.mysql.dao.ts","../src/dao/mysql/delete-table.mysql.dao.ts","../src/dao/mysql/export-table.mysql.dao.ts","../src/dao/mysql/query.mysql.dao.ts","../src/dao/mysql/table-list.mysql.dao.ts","../src/dao/mysql/table-schema.mysql.dao.ts","../src/utils/build-clauses-mysql.ts","../src/dao/mysql/tables-data.mysql.dao.ts","../src/dao/mysql/update-records.mysql.dao.ts","../src/dao/query.dao.ts","../src/dao/table-list.dao.ts","../src/dao/table-schema.dao.ts","../src/utils/build-clauses.ts","../src/dao/tables-data.dao.ts","../src/dao/update-records.dao.ts","../src/dao/dao-factory.ts","../src/routes/databases.routes.ts","../src/routes/query.routes.ts","../src/routes/records.routes.ts","../src/dao/add-column.dao.ts","../src/dao/alter-column.dao.ts","../src/dao/mongo/add-column.mongo.dao.ts","../src/dao/mongo/alter-column.mongo.dao.ts","../src/dao/mysql/add-column.mysql.dao.ts","../src/dao/mysql/alter-column.mysql.dao.ts","../src/dao/mysql/rename-column.mysql.dao.ts","../src/dao/rename-column.dao.ts","../src/utils/get-export-file.ts","../src/routes/tables.routes.ts","../src/utils/create-server.ts","../src/index.ts","../src/cmd/args.ts","../src/cmd/get-db-url.ts","../src/cmd/load-env.ts","../src/cmd/show-help.ts","../src/cmd/show-status.ts","../src/cmd/show-version.ts","../package.json"],"sourcesContent":["export const CHAT_SUGGESTIONS = [\n\t\"Show me all tables in my database\",\n\t\"What columns are in the users table?\",\n\t\"Write a query to find all active users\",\n\t\"How many orders were placed last month?\",\n\t\"Find top 5 customers by total spend\",\n\t\"Write a JOIN between users and orders\",\n\t\"Users who haven't made any purchase yet\",\n\t\"Generate monthly revenue summary query\",\n\t\"Suggest useful indexes for better performance\",\n\t\"Show schema of the products / inventory table\",\n\t\"Latest 20 orders with customer names\",\n\t\"Help me write a safe UPDATE query\",\n];\n\n// const MODEL_LIST = [\n// \t{\n// \t\tid: \"gpt-4o\",\n// \t\tname: \"GPT-4o\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"gpt-4o-mini\",\n// \t\tname: \"GPT-4o Mini\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"claude-opus-4-20250514\",\n// \t\tname: \"Claude 4 Opus\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"claude-sonnet-4-20250514\",\n// \t\tname: \"Claude 4 Sonnet\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"gemini-2.0-flash-exp\",\n// \t\tname: \"Gemini 2.0 Flash\",\n// \t\tchef: \"Google\",\n// \t\tchefSlug: \"google\",\n// \t},\n// ];\n","export const MYSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"tinyint\", label: \"tinyint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"mediumint\", label: \"mediumint\" },\n\t{ value: \"int\", label: \"int\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"decimal\", label: \"decimal\" },\n\t{ value: \"float\", label: \"float\" },\n\t{ value: \"double\", label: \"double\" },\n\t{ value: \"bit\", label: \"bit\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"char\", label: \"char\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"tinytext\", label: \"tinytext\" },\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"mediumtext\", label: \"mediumtext\" },\n\t{ value: \"longtext\", label: \"longtext\" },\n\t// Binary\n\t{ value: \"binary\", label: \"binary\" },\n\t{ value: \"varbinary\", label: \"varbinary\" },\n\t{ value: \"tinyblob\", label: \"tinyblob\" },\n\t{ value: \"blob\", label: \"blob\" },\n\t{ value: \"mediumblob\", label: \"mediumblob\" },\n\t{ value: \"longblob\", label: \"longblob\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"datetime\", label: \"datetime\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"year\", label: \"year\" },\n\t// Complex\n\t{ value: \"enum\", label: \"enum\" },\n\t{ value: \"set\", label: \"set\" },\n] as const;\n\nexport type MysqlColumnType = (typeof MYSQL_COLUMN_TYPES)[number][\"value\"];\n","export const PGSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"integer\", label: \"integer\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"numeric\", label: \"numeric\" },\n\t{ value: \"real\", label: \"real\" },\n\t{ value: \"double precision\", label: \"double precision\" },\n\t{ value: \"money\", label: \"money\" },\n\t{ value: \"serial\", label: \"serial\" },\n\t{ value: \"bigserial\", label: \"bigserial\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"char\", label: \"char\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t{ value: \"jsonb\", label: \"jsonb\" },\n\t{ value: \"xml\", label: \"xml\" },\n\t// UUID\n\t{ value: \"uuid\", label: \"uuid\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"timestamptz\", label: \"timestamptz\" },\n\t{ value: \"interval\", label: \"interval\" },\n\t// Binary\n\t{ value: \"bytea\", label: \"bytea\" },\n\t// Network\n\t{ value: \"inet\", label: \"inet\" },\n\t{ value: \"cidr\", label: \"cidr\" },\n\t{ value: \"macaddr\", label: \"macaddr\" },\n\t{ value: \"macaddr8\", label: \"macaddr8\" },\n\t// Geometric\n\t{ value: \"point\", label: \"point\" },\n\t{ value: \"line\", label: \"line\" },\n\t{ value: \"polygon\", label: \"polygon\" },\n] as const;\n\nexport type PgsqlColumnType = (typeof PGSQL_COLUMN_TYPES)[number][\"value\"];\n","const nodeEnv = (\n\tglobalThis as typeof globalThis & {\n\t\tprocess?: {\n\t\t\tenv?: {\n\t\t\t\tNODE_ENV?: string;\n\t\t\t};\n\t\t};\n\t}\n).process?.env?.NODE_ENV;\n\nexport const DEFAULTS = {\n\tPORT: 3333,\n\tENV: \".env\",\n\tVAR_NAME: \"DATABASE_URL\",\n\tBASE_URL: \"http://localhost:3333\",\n\tIS_DEV: nodeEnv === \"development\",\n\tPROXY_URL:\n\t\tnodeEnv === \"development\"\n\t\t\t? \"http://localhost:8787\"\n\t\t\t: \"https://db-studio-proxy.husamql3.workers.dev\",\n};\n","export const HEADER_LINKS = [\n\t{ label: \"Home\", href: \"/\" },\n\t{ label: \"Roadmap\", href: \"/roadmap\" },\n\t{ label: \"Docs\", href: \"/docs/$\" },\n\t{ label: \"Changelog\", href: \"/changelog\" },\n];\n","export const META = {\n\t//* author\n\tAUTHOR: \"Hüsam 🥑 <devhsmq@gmail.com>\",\n\tAUTHOR_NAME: \"Hüsam\",\n\tAUTHOR_AVATAR: \"/avocado.png\",\n\tAUTHOR_USERNAME: \"husamql3\",\n\tAUTHOR_GITHUB_LINK: \"https://github.com/husamql3\",\n\t//* site\n\tSITE_DESCRIPTION: \"The modern pgAdmin alternative that works with every database.\",\n\tSITE_KEYWORDS: [\n\t\t\"pgadmin alternative\",\n\t\t\"database client\",\n\t\t\"database gui\",\n\t\t\"database browser\",\n\t\t\"sql editor\",\n\t\t\"postgresql client\",\n\t\t\"mysql client\",\n\t\t\"table editor\",\n\t\t\"ai sql\",\n\t\t\"er diagram\",\n\t],\n\tSITE_TITLE: \"DB Studio\",\n\tSITE_NAME: \"dbstudio.sh\",\n\tSITE_URL: \"https://dbstudio.sh\",\n\tSITE_X_LINK: \"https://x.com/dbstudio_sh\",\n\tSITE_GITHUB_LINK: \"https://github.com/husamql3/db-studio\",\n\tSITE_GITHUB_NEW_ISSUE_LINK: \"https://github.com/husamql3/db-studio/issues/new/choose\",\n\tSITE_DOCS_LINK: \"https://dbstudio.sh/docs\",\n\tSITE_CHANGELOG_LINK: \"https://dbstudio.sh/changelog\",\n\tSITE_ROADMAP_LINK: \"https://dbstudio.sh/roadmap\",\n\tSITE_IMAGE: \"https://dbstudio.sh/og-image.png\",\n\tSITE_IMAGE_WIDTH: \"1200\",\n\tSITE_IMAGE_HEIGHT: \"630\",\n\tSITE_IMAGE_ALT: \"dbstudio.sh – Modern database management studio\",\n\tSITE_COLOR: \"#1447e6\",\n};\n","export const ONE_DAY = 24 * 60 * 60 * 1000;\nexport const LIMIT = 3;\n","export * from \"./chat.js\";\nexport * from \"./column-types-mysql.js\";\nexport * from \"./column-types-pgsql.js\";\nexport * from \"./defaults.js\";\nexport * from \"./links.js\";\nexport * from \"./meta.js\";\nexport * from \"./proxy-limits.js\";\n","import { z } from \"zod\";\n\nexport const databaseSchema = z.object({\n\tdb: z.string(\"Database name is required\"),\n});\n\nexport type DatabaseSchemaType = z.infer<typeof databaseSchema>;\n\nexport const DATABASE_TYPES = [\"pg\", \"mysql\", \"mssql\", \"mongodb\"] as const;\n\nexport const databaseTypeSchema = z.enum(DATABASE_TYPES, {\n\tmessage: \"Invalid database type\",\n});\nexport type DatabaseTypeSchema = z.infer<typeof databaseTypeSchema>;\n\nexport const currentDatabaseSchema = databaseSchema.extend({\n\tdbType: databaseTypeSchema,\n});\nexport type CurrentDatabaseSchemaType = z.infer<typeof currentDatabaseSchema>;\n\nexport const databaseTypeParamSchema = z.object({\n\tdbType: databaseTypeSchema,\n});\n\nexport const tableNameSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n});\n\nexport type TableNameSchemaType = z.infer<typeof tableNameSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema, tableNameSchema } from \"./database.types\";\n\nexport const addColumnSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\n\nexport type AddColumnSchemaType = z.infer<typeof addColumnSchema>;\n\nexport const addColumnParamSchema = tableNameSchema;\n\nexport type AddColumnParamSchemaType = z.infer<typeof addColumnParamSchema>;\n\nexport const addColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: tableNameSchema.shape.tableName,\n\tcolumnName: addColumnSchema.shape.columnName,\n\tcolumnType: addColumnSchema.shape.columnType,\n\tdefaultValue: addColumnSchema.shape.defaultValue,\n\tisPrimaryKey: addColumnSchema.shape.isPrimaryKey,\n\tisNullable: addColumnSchema.shape.isNullable,\n\tisUnique: addColumnSchema.shape.isUnique,\n\tisIdentity: addColumnSchema.shape.isIdentity,\n\tisArray: addColumnSchema.shape.isArray,\n});\n\nexport type AddColumnParamsSchemaType = z.infer<typeof addColumnParamsSchema>;\n","import { z } from \"zod\";\n\nexport const addRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tdata: z.record(z.string(\"Column name is required\"), z.any()),\n});\n\nexport type AddRecordSchemaType = z.infer<typeof addRecordSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\n\nexport const deleteColumnQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteColumnQuerySchemaType = z.infer<typeof deleteColumnQuerySchema>;\n\nexport const deleteColumnParamSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n});\n\nexport const deleteColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcascade: z.boolean().optional(),\n});\n\nexport type DeleteColumnParamsSchemaType = z.infer<typeof deleteColumnParamsSchema>;\n\nexport const deleteColumnSuccessResponseSchema = z.object({\n\tmessage: z.string(\"Message is required\"),\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n\tdeletedCount: z.number(\"Deleted count is required\").default(0),\n});\n\nexport type DeleteColumnResponseType = z.infer<typeof deleteColumnSuccessResponseSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const alterColumnSchema = z.object({\n\tcolumnType: z.string(\"Column type is required\"),\n\tisNullable: z.boolean(),\n\tdefaultValue: z.string().nullable().optional(),\n});\n\nexport type AlterColumnSchemaType = z.infer<typeof alterColumnSchema>;\n\nexport const alterColumnParamSchema = deleteColumnParamSchema;\n\nexport type AlterColumnParamSchemaType = z.infer<typeof alterColumnParamSchema>;\n\nexport const alterColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcolumnType: alterColumnSchema.shape.columnType,\n\tisNullable: alterColumnSchema.shape.isNullable,\n\tdefaultValue: alterColumnSchema.shape.defaultValue,\n});\n\nexport type AlterColumnParamsSchemaType = z.infer<typeof alterColumnParamsSchema>;\n","/**\n * Standard API success response wrapper type\n * Used by both server and client\n */\nexport type BaseResponse<T> = {\n\tdata: T;\n\tmessage?: string;\n};\n\n/**\n * Standard API error response type\n */\nexport type ApiError = {\n\terror: string;\n\tdetails?: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport type BulkInsertRecordsParams = {\n\ttableName: string;\n\trecords: Record<string, unknown>[];\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type BulkInsertResult = {\n\tsuccess: boolean;\n\tmessage: string;\n\tsuccessCount: number;\n\tfailureCount: number;\n\terrors?: Array<{ recordIndex: number; error: string }>;\n};\n\nexport const bulkInsertRecordsSchema = z.object({\n\ttableName: z.string().min(1, \"Table name is required\"),\n\trecords: z.array(z.record(z.string(), z.any())).min(1, \"At least one record is required\"),\n});\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\n// UI message part schema (from @tanstack/ai-react)\nconst messagePart = z\n\t.object({\n\t\ttype: z.string(),\n\t\tcontent: z.string().optional(),\n\t})\n\t.passthrough();\n\n// `@tanstack/ai-react`'s `fetchServerSentEvents` adapter sends UI messages\n// with `parts` (not `content`) and wraps extra body under `data`.\nexport const chatSchema = z.object({\n\tmessages: z.array(\n\t\tz\n\t\t\t.object({\n\t\t\t\tid: z.string(),\n\t\t\t\trole: z.enum([\"user\", \"assistant\", \"system\", \"tool\"]),\n\t\t\t\tparts: z.array(messagePart),\n\t\t\t})\n\t\t\t.passthrough(),\n\t),\n\tdata: z.object({\n\t\tconversationId: z.string().optional(),\n\t\tdb: databaseSchema.shape.db,\n\t}),\n});\n","export type Args = {\n\tenv?: string;\n\tport?: string;\n\tdatabaseUrl?: string;\n\tvarName?: string;\n\tstatus?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n};\n","import { z } from \"zod\";\n\nconst dataTypes = [\"text\", \"boolean\", \"number\", \"enum\", \"json\", \"date\", \"array\"] as const;\n\nexport const dataTypesSchema = z.enum(dataTypes);\nexport type DataTypes = z.infer<typeof dataTypesSchema>;\n\nexport const DataTypes = {\n\ttext: \"text\",\n\tboolean: \"boolean\",\n\tnumber: \"number\",\n\tenum: \"enum\",\n\tjson: \"json\",\n\tdate: \"date\",\n\tarray: \"array\",\n} as const satisfies Record<DataTypes, string>;\n\nconst standardizedDataTypes = [\n\t// PostgreSQL numeric types\n\t\"int\",\n\t\"bigint\",\n\t\"smallint\",\n\t\"numeric\",\n\t\"float\",\n\t\"double\",\n\t\"money\",\n\t// MySQL numeric types\n\t\"tinyint\",\n\t\"mediumint\",\n\t\"bit\",\n\t// Boolean\n\t\"boolean\",\n\t// Text types (shared)\n\t\"text\",\n\t\"varchar\",\n\t\"char\",\n\t// MySQL text types\n\t\"tinytext\",\n\t\"mediumtext\",\n\t\"longtext\",\n\t// JSON types\n\t\"json\",\n\t\"jsonb\",\n\t\"xml\",\n\t// UUID\n\t\"uuid\",\n\t// Date/Time types (shared)\n\t\"date\",\n\t\"time\",\n\t\"timestamp\",\n\t// PostgreSQL date/time\n\t\"timestamptz\",\n\t\"interval\",\n\t// MySQL date/time\n\t\"datetime\",\n\t\"year\",\n\t// PostgreSQL binary/network/geometric types\n\t\"bytea\",\n\t\"inet\",\n\t\"cidr\",\n\t\"macaddr\",\n\t\"macaddr8\",\n\t\"point\",\n\t\"line\",\n\t\"polygon\",\n\t// MySQL binary types\n\t\"binary\",\n\t\"varbinary\",\n\t\"blob\",\n\t\"tinyblob\",\n\t\"mediumblob\",\n\t\"longblob\",\n\t// Complex types (shared)\n\t\"array\",\n\t\"enum\",\n\t// MySQL set type\n\t\"set\",\n] as const;\n\nexport const standardizedDataTypeSchema = z.enum(standardizedDataTypes);\n\nexport const columnInfoSchema = z.object({\n\tcolumnName: z.string(),\n\tdataType: dataTypesSchema,\n\tdataTypeLabel: standardizedDataTypeSchema,\n\tisNullable: z.boolean(),\n\tcolumnDefault: z.string().nullable(),\n\tisPrimaryKey: z.boolean(),\n\tisForeignKey: z.boolean(),\n\treferencedTable: z.string().nullable(),\n\treferencedColumn: z.string().nullable(),\n\tenumValues: z.array(z.string()).nullable(),\n});\n\nexport type ColumnInfoSchemaType = z.infer<typeof columnInfoSchema>;\n","import { DataTypes } from \"./column-info.types.js\";\n\n/**\n * Maps PostgreSQL data types to generic DataType enum\n */\nexport function mapPostgresToDataType(pgType: string): DataTypes {\n\tconst normalized = pgType?.toLowerCase().trim() || \"\";\n\n\t// Handle array types and date/time types\n\tif (\n\t\tnormalized.includes(\"[]\") ||\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\") ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\") ||\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int2\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\") ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"float4\" ||\n\t\tnormalized === \"double precision\" ||\n\t\tnormalized === \"float8\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\" ||\n\t\tnormalized === \"money\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\" || normalized === \"jsonb\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum types and long text types\n\tif (\n\t\tnormalized.startsWith(\"user-defined\") ||\n\t\tnormalized === \"enum\" ||\n\t\tnormalized === \"text\" ||\n\t\tnormalized === \"xml\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Short string types (varchar, char, uuid, etc.)\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\") ||\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\" ||\n\t\tnormalized === \"uuid\" ||\n\t\tnormalized === \"interval\" ||\n\t\tnormalized.startsWith(\"interval\") ||\n\t\tnormalized === \"bytea\" ||\n\t\tnormalized === \"point\" ||\n\t\tnormalized === \"line\" ||\n\t\tnormalized === \"polygon\" ||\n\t\tnormalized === \"inet\" ||\n\t\tnormalized === \"cidr\" ||\n\t\tnormalized === \"macaddr\" ||\n\t\tnormalized === \"macaddr8\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Default to short for unrecognized types\n\treturn DataTypes.text;\n}\n\n/**\n * Standardized data type labels\n */\nexport const StandardizedDataType = {\n\t// PostgreSQL numeric types\n\tint: \"int\",\n\tbigint: \"bigint\",\n\tsmallint: \"smallint\",\n\tnumeric: \"numeric\",\n\tfloat: \"float\",\n\tdouble: \"double\",\n\tmoney: \"money\",\n\t// MySQL numeric types\n\ttinyint: \"tinyint\",\n\tmediumint: \"mediumint\",\n\tbit: \"bit\",\n\t// Boolean\n\tboolean: \"boolean\",\n\t// Text types (shared)\n\ttext: \"text\",\n\tvarchar: \"varchar\",\n\tchar: \"char\",\n\t// MySQL text types\n\ttinytext: \"tinytext\",\n\tmediumtext: \"mediumtext\",\n\tlongtext: \"longtext\",\n\t// JSON types\n\tjson: \"json\",\n\tjsonb: \"jsonb\",\n\txml: \"xml\",\n\t// UUID\n\tuuid: \"uuid\",\n\t// Date/Time types (shared)\n\tdate: \"date\",\n\ttime: \"time\",\n\ttimestamp: \"timestamp\",\n\t// PostgreSQL date/time\n\ttimestamptz: \"timestamptz\",\n\tinterval: \"interval\",\n\t// MySQL date/time\n\tdatetime: \"datetime\",\n\tyear: \"year\",\n\t// PostgreSQL binary/network/geometric types\n\tbytea: \"bytea\",\n\tinet: \"inet\",\n\tcidr: \"cidr\",\n\tmacaddr: \"macaddr\",\n\tmacaddr8: \"macaddr8\",\n\tpoint: \"point\",\n\tline: \"line\",\n\tpolygon: \"polygon\",\n\t// MySQL binary types\n\tbinary: \"binary\",\n\tvarbinary: \"varbinary\",\n\tblob: \"blob\",\n\ttinyblob: \"tinyblob\",\n\tmediumblob: \"mediumblob\",\n\tlongblob: \"longblob\",\n\t// Complex types (shared)\n\tarray: \"array\",\n\tenum: \"enum\",\n\t// MySQL set type\n\tset: \"set\",\n} as const;\n\nexport type StandardizedDataType =\n\t(typeof StandardizedDataType)[keyof typeof StandardizedDataType];\n\n/**\n * Maps PostgreSQL data types to standardized display labels\n */\nexport function standardizeDataTypeLabel(\n\tpgType: string | null | undefined,\n): StandardizedDataType {\n\tif (!pgType) {\n\t\treturn StandardizedDataType.text; // Default fallback\n\t}\n\tconst normalized = pgType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\"\n\t) {\n\t\treturn StandardizedDataType.int;\n\t}\n\n\tif (\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\"\n\t) {\n\t\treturn StandardizedDataType.bigint;\n\t}\n\n\tif (normalized === \"smallint\" || normalized === \"int2\") {\n\t\treturn StandardizedDataType.smallint;\n\t}\n\n\tif (\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\")\n\t) {\n\t\treturn StandardizedDataType.numeric;\n\t}\n\n\tif (normalized === \"real\" || normalized === \"float4\") {\n\t\treturn StandardizedDataType.float;\n\t}\n\n\tif (normalized === \"double precision\" || normalized === \"float8\" || normalized === \"float\") {\n\t\treturn StandardizedDataType.double;\n\t}\n\n\tif (normalized === \"money\") {\n\t\treturn StandardizedDataType.money;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn StandardizedDataType.boolean;\n\t}\n\n\t// Text types\n\tif (normalized === \"text\") {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\")\n\t) {\n\t\treturn StandardizedDataType.varchar;\n\t}\n\n\tif (\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\"\n\t) {\n\t\treturn StandardizedDataType.char;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\") {\n\t\treturn StandardizedDataType.json;\n\t}\n\n\tif (normalized === \"jsonb\") {\n\t\treturn StandardizedDataType.jsonb;\n\t}\n\n\tif (normalized === \"xml\") {\n\t\treturn StandardizedDataType.xml;\n\t}\n\n\t// UUID\n\tif (normalized === \"uuid\") {\n\t\treturn StandardizedDataType.uuid;\n\t}\n\n\t// Date/Time types\n\tif (normalized === \"date\") {\n\t\treturn StandardizedDataType.date;\n\t}\n\n\tif (\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\")\n\t) {\n\t\treturn StandardizedDataType.time;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\")\n\t) {\n\t\treturn StandardizedDataType.timestamp;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn StandardizedDataType.timestamptz;\n\t}\n\n\tif (normalized === \"interval\" || normalized.startsWith(\"interval\")) {\n\t\treturn StandardizedDataType.interval;\n\t}\n\n\t// Binary\n\tif (normalized === \"bytea\") {\n\t\treturn StandardizedDataType.bytea;\n\t}\n\n\t// Network types\n\tif (normalized === \"inet\") {\n\t\treturn StandardizedDataType.inet;\n\t}\n\n\tif (normalized === \"cidr\") {\n\t\treturn StandardizedDataType.cidr;\n\t}\n\n\tif (normalized === \"macaddr\") {\n\t\treturn StandardizedDataType.macaddr;\n\t}\n\n\tif (normalized === \"macaddr8\") {\n\t\treturn StandardizedDataType.macaddr8;\n\t}\n\n\t// Geometric types\n\tif (normalized === \"point\") {\n\t\treturn StandardizedDataType.point;\n\t}\n\n\tif (normalized === \"line\") {\n\t\treturn StandardizedDataType.line;\n\t}\n\n\tif (normalized === \"polygon\") {\n\t\treturn StandardizedDataType.polygon;\n\t}\n\n\t// Array types\n\t// todo: handle array types\n\tif (normalized.startsWith(\"array\") || normalized.includes(\"[]\")) {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\t// User-defined types (enums)\n\tif (normalized.startsWith(\"user-defined\") || normalized === \"enum\") {\n\t\treturn StandardizedDataType.enum;\n\t}\n\n\t// Default: return the original type\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps MySQL data types to generic DataType enum (used for cell rendering)\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\", \"enum('a','b')\") for finer mapping\n */\nexport function mapMysqlToDataType(mysqlDataType: string, columnType?: string): DataTypes {\n\tconst normalized = mysqlDataType?.toLowerCase().trim() || \"\";\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"mediumint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"double\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"bit\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (explicit)\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"year\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum and set (set behaves like enum for display)\n\tif (normalized === \"enum\" || normalized === \"set\") {\n\t\treturn DataTypes.enum;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps MySQL data types to standardized display labels\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\") for finer mapping\n */\nexport function standardizeMysqlDataTypeLabel(\n\tmysqlDataType: string,\n\tcolumnType?: string,\n): StandardizedDataType {\n\tif (!mysqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mysqlDataType.toLowerCase().trim();\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\")\n\t\treturn StandardizedDataType.boolean;\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"mediumint\") return StandardizedDataType.mediumint;\n\tif (normalized === \"int\" || normalized === \"integer\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\" || normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"double\") return StandardizedDataType.double;\n\tif (normalized === \"bit\") return StandardizedDataType.bit;\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"tinytext\") return StandardizedDataType.tinytext;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"mediumtext\") return StandardizedDataType.mediumtext;\n\tif (normalized === \"longtext\") return StandardizedDataType.longtext;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"tinyblob\") return StandardizedDataType.tinyblob;\n\tif (normalized === \"blob\") return StandardizedDataType.blob;\n\tif (normalized === \"mediumblob\") return StandardizedDataType.mediumblob;\n\tif (normalized === \"longblob\") return StandardizedDataType.longblob;\n\n\t// JSON\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"timestamp\") return StandardizedDataType.timestamp;\n\tif (normalized === \"year\") return StandardizedDataType.year;\n\n\t// Complex types\n\tif (normalized === \"enum\") return StandardizedDataType.enum;\n\tif (normalized === \"set\") return StandardizedDataType.set;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps SQL Server data types to generic DataType enum (used for cell rendering)\n * @param mssqlDataType - The data type from sys.columns or information_schema.columns\n */\nexport function mapMssqlToDataType(mssqlDataType: string): DataTypes {\n\tconst normalized = mssqlDataType?.toLowerCase().trim() || \"\";\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"money\" ||\n\t\tnormalized === \"smallmoney\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (bit with length 1)\n\tif (normalized === \"bit\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"datetime2\" ||\n\t\tnormalized === \"smalldatetime\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"datetimeoffset\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON (SQL Server 2016+)\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps SQL Server data types to standardized display labels\n * @param mssqlDataType - The data type from sys.columns or information_schema.columns\n */\nexport function standardizeMssqlDataTypeLabel(mssqlDataType: string): StandardizedDataType {\n\tif (!mssqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mssqlDataType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"int\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\") return StandardizedDataType.float;\n\tif (normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"money\" || normalized === \"smallmoney\") return StandardizedDataType.money;\n\n\t// Boolean\n\tif (normalized === \"bit\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"nchar\") return StandardizedDataType.char;\n\tif (normalized === \"nvarchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"ntext\") return StandardizedDataType.text;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"image\") return StandardizedDataType.blob;\n\n\t// UUID\n\tif (normalized === \"uniqueidentifier\") return StandardizedDataType.uuid;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"datetime2\") return StandardizedDataType.datetime;\n\tif (normalized === \"smalldatetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"datetimeoffset\") return StandardizedDataType.timestamptz;\n\n\t// JSON and XML\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\tif (normalized === \"xml\") return StandardizedDataType.xml;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n","import { z } from \"zod\";\n\nexport const FOREIGN_KEY_ACTIONS = [\n\t\"CASCADE\",\n\t\"SET NULL\",\n\t\"SET DEFAULT\",\n\t\"RESTRICT\",\n\t\"NO ACTION\",\n] as const;\nexport const foreignKeyActionSchema = z.enum(FOREIGN_KEY_ACTIONS);\n\nexport const fieldDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\nexport type FieldDataType = z.infer<typeof fieldDataSchema>;\n\nexport const foreignKeyDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\treferencedTable: z.string(\"Referenced table is required\"),\n\treferencedColumn: z.string(\"Referenced column is required\"),\n\tonUpdate: foreignKeyActionSchema.default(\"NO ACTION\"),\n\tonDelete: foreignKeyActionSchema.default(\"NO ACTION\"),\n});\nexport type ForeignKeyDataType = z.infer<typeof foreignKeyDataSchema>;\n\nexport const createTableSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tfields: z.array(fieldDataSchema).min(1, \"At least one field is required\"),\n\tforeignKeys: z.array(foreignKeyDataSchema).optional(),\n});\n\nexport type CreateTableSchemaType = z.infer<typeof createTableSchema>;\n","import { z } from \"zod\";\nimport { databaseTypeSchema } from \"./database.types.js\";\n\nexport const databaseInfoSchema = z.object({\n\tname: z.string(\"Name is required\"),\n\tsize: z.string(\"Size is required\"),\n\towner: z.string(\"Owner is required\"),\n\tencoding: z.string(\"Encoding is required\"),\n});\n\nexport type DatabaseInfoSchemaType = z.infer<typeof databaseInfoSchema>;\n\nexport const databaseListSchema = z.object({\n\tdatabases: z.array(databaseInfoSchema),\n\tdbType: databaseTypeSchema,\n});\n\nexport type DatabaseListSchemaType = z.infer<typeof databaseListSchema>;\n\nexport const connectionInfoSchema = z.object({\n\tversion: z.string(\"Version is required\"),\n\tdatabase: z.string(\"Database is required\"),\n\tuser: z.string(\"User is required\"),\n\thost: z.string(\"Host is required\").nullable(),\n\tport: z.number(\"Port is required\").nullable(),\n\tactive_connections: z.coerce.number(\"Active connections is required\"),\n\tmax_connections: z.coerce.number(\"Max connections is required\"),\n});\n\nexport type ConnectionInfoSchemaType = z.infer<typeof connectionInfoSchema>;\n","import type { DatabaseTypeSchema } from \"./database.types\";\n\nexport type DatabaseSchema = {\n\tdbType: DatabaseTypeSchema;\n\ttables: Table[];\n\trelationships: Relationship[];\n};\n\nexport type Table = {\n\tname: string;\n\tdescription?: string;\n\tcolumns: Column[];\n\tsampleData?: Record<string, string>[];\n};\n\nexport type Column = {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n\tisPrimaryKey?: boolean;\n\tforeignKey?: string;\n\tdescription?: string;\n\tenumValues?: string[];\n};\n\nexport type Relationship = {\n\tfromTable: string;\n\tfromColumn: string;\n\ttoTable: string;\n\ttoColumn: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport const deleteRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKeys: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\tvalue: z.any(),\n\t\t\t}),\n\t\t)\n\t\t.min(1, \"At least one primary key is required\"),\n});\n\nexport type DeleteRecordSchemaType = z.infer<typeof deleteRecordSchema>;\n\nexport type DeleteRecordParams = DeleteRecordSchemaType & {\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type DeleteRecordResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n\nexport type ForeignKeyConstraint = {\n\tconstraintName: string;\n\treferencingTable: string;\n\treferencingColumn: string;\n\treferencedTable: string;\n\treferencedColumn: string;\n};\n\nexport type ForeignKeyConstraintRow = {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n};\n\nexport type RelatedRecord = {\n\ttableName: string;\n\tcolumnName: string;\n\tconstraintName: string;\n\trecords: Array<Record<string, unknown>>;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport type { RelatedRecord } from \"./delete-record.types\";\n\nexport const deleteTableQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteTableQuerySchemaType = z.infer<typeof deleteTableQuerySchema>;\n\nexport type DeleteTableParams = {\n\ttableName: string;\n\tdb: string;\n\tcascade?: boolean;\n};\n\nexport type DeleteTableResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n","import { z } from \"zod\";\n\nexport const executeQuerySchema = z.object({\n\tquery: z.string(\"Query is required\"),\n});\n\nexport type ExecuteQueryParams = z.infer<typeof executeQuerySchema>;\n\nexport type ExecuteQueryResult = {\n\tcolumns: string[];\n\trows: Record<string, unknown>[];\n\trowCount: number;\n\tduration: number;\n\tmessage?: string;\n\terror?: string;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const FORMAT_TYPES = [\"csv\", \"xlsx\", \"json\"] as const;\nexport type FormatType = (typeof FORMAT_TYPES)[number];\n\nexport const exportTableSchema = databaseSchema.extend({\n\tformat: z.enum(FORMAT_TYPES, {\n\t\tmessage: \"Invalid format. Supported formats: csv, xlsx, json\",\n\t}),\n});\nexport type ExportTableSchemaType = z.infer<typeof exportTableSchema>;\n\nexport type CellValue = string | number | boolean | Date | null | undefined;\n","export type RateLimitResponse = {\n\tlimit: number;\n\tused: number;\n\tremaining: number;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const renameColumnSchema = z.object({\n\tnewColumnName: z.string(\"New column name is required\"),\n});\n\nexport type RenameColumnSchemaType = z.infer<typeof renameColumnSchema>;\n\nexport const renameColumnParamSchema = deleteColumnParamSchema;\n\nexport type RenameColumnParamSchemaType = z.infer<typeof renameColumnParamSchema>;\n\nexport const renameColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tnewColumnName: renameColumnSchema.shape.newColumnName,\n});\n\nexport type RenameColumnParamsSchemaType = z.infer<typeof renameColumnParamsSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const filterSchema = z.object({\n\tcolumnName: z.string(),\n\toperator: z.string(),\n\tvalue: z.string(),\n});\n\nexport type FilterType = z.infer<typeof filterSchema>;\n\nexport const sortDirections = [\"asc\", \"desc\"] as const;\nexport type SortDirection = (typeof sortDirections)[number];\n\nexport const sortSchema = z.object({\n\tcolumnName: z.string(),\n\tdirection: z.enum(sortDirections),\n});\n\nexport type SortType = z.infer<typeof sortSchema>;\n\nexport const tableDataMetaSchema = z.object({\n\tlimit: z.number(),\n\ttotal: z.number(),\n\thasNextPage: z.boolean(),\n\thasPreviousPage: z.boolean(),\n\tnextCursor: z.string().nullable(),\n\tprevCursor: z.string().nullable(),\n});\n\nexport const tableDataResultSchema = z.object({\n\tdata: z.array(z.record(z.string(), z.unknown())),\n\tmeta: tableDataMetaSchema,\n});\n\nexport type TableDataResultSchemaType = z.infer<typeof tableDataResultSchema>;\n\nexport const tableDataQuerySchema = z.object({\n\tdb: databaseSchema.shape.db,\n\tcursor: z.string().optional(), // Base64 encoded cursor for pagination\n\tlimit: z.string().optional().default(\"50\").transform(Number),\n\tdirection: z.enum(sortDirections).optional().default(sortDirections[0]), // Pagination direction\n\tsort: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return \"\";\n\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(val);\n\t\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t} catch {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t}),\n\torder: z.enum(sortDirections).optional(),\n\tfilters: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return [];\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(val);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}),\n});\n\nexport type TableDataQuerySchemaType = z.infer<typeof tableDataQuerySchema>;\n\nexport interface CursorData {\n\tvalues: Record<string, unknown>;\n\tsortColumns: string[];\n}\n","import { z } from \"zod\";\n\nexport const tableInfoSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tschemaName: z.string().optional(),\n\trowCount: z.coerce.number(\"Row count is required\"),\n});\n\nexport type TableInfoSchemaType = z.infer<typeof tableInfoSchema>;\n","import { z } from \"zod\";\n\nexport const tableSchemaResultSchema = z.object({\n\tschema: z.string(),\n});\n\nexport type TableSchemaResult = z.infer<typeof tableSchemaResultSchema>;\n","import { z } from \"zod\";\n\nexport const updateRecordsSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKey: z.string(\"Primary key is required\").default(\"id\"),\n\tupdates: z\n\t\t.array(\n\t\t\tz.object(\n\t\t\t\t{\n\t\t\t\t\trowData: z.record(z.string(\"Column name is required\"), z.any()),\n\t\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\t\tvalue: z.any(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Each update must have a row data, column name, and value.\",\n\t\t\t\t},\n\t\t\t),\n\t\t)\n\t\t.min(1, \"At least one update is required\"),\n});\n\nexport type UpdateRecordsSchemaType = z.infer<typeof updateRecordsSchema>;\n","export * from \"./add-column.types.js\";\nexport * from \"./add-record.types.js\"; // done\nexport * from \"./alter-column.types.js\";\nexport * from \"./api-response.types.js\";\nexport * from \"./bulk-insert-records.type.js\";\nexport * from \"./chat.types.js\"; // done\nexport * from \"./cmd-args.types.js\"; // done\nexport * from \"./column.type.js\";\nexport * from \"./column-info.types.js\";\nexport * from \"./create-table.types.js\"; // done\nexport * from \"./database.types.js\"; // done\nexport * from \"./database-list.types.js\"; // done\nexport * from \"./database-schema.type.js\"; // done\nexport * from \"./delete-column.types.js\"; // done\nexport * from \"./delete-record.types.js\"; // done\nexport * from \"./delete-table.types.js\"; // done\nexport * from \"./execute-query.types.js\"; // done\nexport * from \"./export-table.types.js\";\nexport * from \"./rate-limit-response.type.js\";\nexport * from \"./rename-column.types.js\";\nexport * from \"./table-data.types.js\"; // done\nexport * from \"./table-info.type.js\"; // done\nexport * from \"./table-schema.types.js\"; // done\nexport * from \"./update-recors.types.js\"; // done\n","import type { Context } from \"hono\";\nimport { HTTPException } from \"hono/http-exception\";\nimport { DatabaseError } from \"pg\";\nimport type { ApiError } from \"shared/types/api-response.types.js\";\nimport { ZodError } from \"zod\";\n\n/**\n * Centralized error handler for the application\n */\nexport function handleError(e: Error | unknown, c: Context) {\n\tconsole.error(\"handleError:\", e);\n\n\tif (e instanceof HTTPException) {\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: e.message ?? \"Internal server error\",\n\t\t\t},\n\t\t\te.status,\n\t\t);\n\t}\n\n\tif (e instanceof ZodError) {\n\t\tconst issue = e.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue.message,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tif (e instanceof Error) {\n\t\t// MySQL-specific error codes\n\t\tconst mysqlError = e as { code?: string; errno?: number };\n\t\tconst isMysqlConnectionError =\n\t\t\tmysqlError.code === \"ECONNREFUSED\" ||\n\t\t\tmysqlError.code === \"ENOTFOUND\" ||\n\t\t\tmysqlError.code === \"ETIMEDOUT\" ||\n\t\t\tmysqlError.code === \"ER_ACCESS_DENIED_ERROR\" ||\n\t\t\tmysqlError.code === \"ER_BAD_HOST_ERROR\" ||\n\t\t\tmysqlError.code === \"ECONNRESET\" ||\n\t\t\tmysqlError.errno === 1045 || // ER_ACCESS_DENIED_ERROR\n\t\t\tmysqlError.errno === 2003 || // Can't connect to MySQL server\n\t\t\tmysqlError.errno === 2002; // Can't connect to local MySQL server\n\n\t\tconst isConnectionError =\n\t\t\tisMysqlConnectionError ||\n\t\t\te.message.includes(\"ECONNREFUSED\") ||\n\t\t\te.message.includes(\"connection refused\") ||\n\t\t\te.message.includes(\"timeout expired\") ||\n\t\t\te.message.includes(\"Connection terminated\") ||\n\t\t\te.message.includes(\"MongoNetworkError\") ||\n\t\t\te.message.includes(\"MongoServerSelectionError\") ||\n\t\t\t(e instanceof DatabaseError && e.code?.startsWith(\"08\")); // PostgreSQL connection exception class\n\n\t\tif (isConnectionError) {\n\t\t\treturn c.json<ApiError>(\n\t\t\t\t{ error: \"Database connection failed\", details: e.message },\n\t\t\t\t503,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn c.json<ApiError>(\n\t\t{\n\t\t\terror: e instanceof Error ? e.message : \"Internal server error\",\n\t\t},\n\t\t500,\n\t);\n}\n\nexport const validationHook = (\n\tresult: {\n\t\tsuccess: boolean;\n\t\tdata?: unknown;\n\t\terror?: { issues: { message: string }[] };\n\t},\n\tc: Context,\n): Response | undefined => {\n\tif (!result.success) {\n\t\tconst issue = result.error?.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue?.message ?? \"Unknown validation error\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n","import { MongoClient, ObjectId } from \"mongodb\";\nimport type { ConnectionPool as MssqlPool } from \"mssql\";\nimport mssql from \"mssql\";\nimport type { Pool as MysqlPool } from \"mysql2/promise\";\nimport { createPool as createMysqlPool } from \"mysql2/promise\";\nimport { Pool, type PoolConfig } from \"pg\";\nimport type { DatabaseTypeSchema } from \"shared/types\";\n\n/**\n * DatabaseManager - Manages multiple database connection pools for PostgreSQL, MySQL, SQL Server, and MongoDB\n */\nclass DatabaseManager {\n\tprivate pgPools: Map<string, Pool> = new Map();\n\tprivate mysqlPools: Map<string, MysqlPool> = new Map();\n\tprivate mssqlPools: Map<string, MssqlPool> = new Map();\n\tprivate mongoClient: MongoClient | null = null;\n\tprivate baseConfig: {\n\t\turl: string;\n\t\thost: string;\n\t\tport: number;\n\t\tuser: string;\n\t\tpassword: string;\n\t\tdbType: DatabaseTypeSchema;\n\t} | null = null;\n\n\tconstructor() {\n\t\tthis.initializeBaseConfig();\n\t}\n\n\t/**\n\t * Detect database type from URL protocol\n\t */\n\tprivate detectDbType(url: URL): DatabaseTypeSchema {\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tswitch (protocol) {\n\t\t\tcase \"postgres\":\n\t\t\tcase \"postgresql\":\n\t\t\t\treturn \"pg\";\n\t\t\tcase \"mysql\":\n\t\t\tcase \"mysql2\":\n\t\t\t\treturn \"mysql\";\n\t\t\tcase \"mssql\":\n\t\t\tcase \"sqlserver\":\n\t\t\t\treturn \"mssql\";\n\t\t\tcase \"mongodb\":\n\t\t\tcase \"mongodb+srv\":\n\t\t\t\treturn \"mongodb\";\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unsupported database type: ${protocol}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://).`,\n\t\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Parse DATABASE_URL and extract connection details\n\t */\n\tprivate initializeBaseConfig() {\n\t\tconst databaseUrl = process.env.DATABASE_URL;\n\t\tif (!databaseUrl) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(databaseUrl);\n\t\t\tthis.baseConfig = {\n\t\t\t\turl: databaseUrl,\n\t\t\t\thost: url.hostname,\n\t\t\t\tport:\n\t\t\t\t\tNumber.parseInt(url.port, 10) ||\n\t\t\t\t\t(this.detectDbType(url) === \"mysql\"\n\t\t\t\t\t\t? 3306\n\t\t\t\t\t\t: this.detectDbType(url) === \"mssql\"\n\t\t\t\t\t\t\t? 1433\n\t\t\t\t\t\t\t: 5432),\n\t\t\t\tuser: url.username,\n\t\t\t\tpassword: url.password,\n\t\t\t\tdbType: this.detectDbType(url),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new Error(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/**\n\t * Get the detected database type\n\t */\n\tgetDbType(): DatabaseTypeSchema {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\treturn this.baseConfig.dbType;\n\t}\n\n\t/**\n\t * Build a connection string for the specified database\n\t */\n\tbuildConnectionString(database?: string): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tif (!database) {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\tdatabase = url.pathname.slice(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\turl.pathname = `/${database}`;\n\t\t\treturn url.toString();\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to build connection string for database \"${database}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get or create a PostgreSQL connection pool for the specified database\n\t */\n\tgetPgPool(database?: string): Pool {\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.pgPools.has(connectionString)) {\n\t\t\tconst poolConfig: PoolConfig = {\n\t\t\t\tconnectionString,\n\t\t\t\tmax: 10,\n\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\tconnectionTimeoutMillis: 2000,\n\t\t\t};\n\n\t\t\tconst pool = new Pool(poolConfig);\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on PostgreSQL pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.pgPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.pgPools.get(connectionString) ?? new Pool({ connectionString });\n\t}\n\n\t/**\n\t * Get or create a MySQL connection pool for the specified database\n\t */\n\tgetMysqlPool(database?: string): MysqlPool {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mysqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst pool = createMysqlPool({\n\t\t\t\thost: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\twaitForConnections: true,\n\t\t\t\tconnectionLimit: 10,\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t// Enable multiple statements for raw query support\n\t\t\t\tmultipleStatements: false,\n\t\t\t});\n\n\t\t\tthis.mysqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created MySQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mysqlPools.get(connectionString) as MysqlPool;\n\t}\n\n\t/**\n\t * Get or create a SQL Server connection pool for the specified database\n\t */\n\tasync getMssqlPool(database?: string): Promise<MssqlPool> {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mssqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst config: mssql.config = {\n\t\t\t\tserver: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\toptions: {\n\t\t\t\t\tencrypt: false, // Use true for Azure\n\t\t\t\t\ttrustServerCertificate: true,\n\t\t\t\t\tenableArithAbort: true,\n\t\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t},\n\t\t\t\tpool: {\n\t\t\t\t\tmax: 10,\n\t\t\t\t\tmin: 0,\n\t\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst pool = await new mssql.ConnectionPool(config).connect();\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on SQL Server pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.mssqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created SQL Server connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mssqlPools.get(connectionString) as MssqlPool;\n\t}\n\n\t/**\n\t * Get the appropriate pool based on database type (legacy/PG-only helper)\n\t */\n\tgetPool(database?: string): Pool {\n\t\treturn this.getPgPool(database);\n\t}\n\n\t/**\n\t * Close a specific PostgreSQL pool by connection string\n\t */\n\tasync closePgPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.pgPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.pgPools.delete(connectionString);\n\t\t\tconsole.log(`Closed PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific MySQL pool by connection string\n\t */\n\tasync closeMysqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mysqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.mysqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed MySQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific SQL Server pool by connection string\n\t */\n\tasync closeMssqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mssqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.close();\n\t\t\tthis.mssqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed SQL Server connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific database pool by connection string (both types)\n\t */\n\tasync closePool(connectionString: string): Promise<void> {\n\t\tawait this.closePgPool(connectionString);\n\t\tawait this.closeMysqlPool(connectionString);\n\t\tawait this.closeMssqlPool(connectionString);\n\t}\n\n\t/**\n\t * Close a specific database pool by database name\n\t */\n\tasync closePoolByDatabase(database: string): Promise<void> {\n\t\tconst connectionString = this.buildConnectionString(database);\n\t\tawait this.closePool(connectionString);\n\t}\n\n\t/**\n\t * Get or create a MongoDB client\n\t */\n\tasync getMongoClient(): Promise<MongoClient> {\n\t\tif (!this.mongoClient) {\n\t\t\tif (!this.baseConfig) {\n\t\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t\t}\n\t\t\tconst nextClient = new MongoClient(this.baseConfig.url);\n\t\t\ttry {\n\t\t\t\tawait nextClient.connect();\n\t\t\t\tthis.mongoClient = nextClient;\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait nextClient.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore close errors\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn this.mongoClient;\n\t}\n\n\t/**\n\t * Get the MongoDB database name from the connection URL\n\t */\n\tgetMongoDbName(): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\tconst path = new URL(this.baseConfig.url).pathname?.replace(/^\\//, \"\");\n\t\treturn path || \"admin\";\n\t}\n\n\t/**\n\t * Get a MongoDB database instance\n\t */\n\tasync getMongoDb(dbName?: string) {\n\t\tconst mongoClient = await this.getMongoClient();\n\t\treturn mongoClient.db(dbName ?? this.getMongoDbName());\n\t}\n\n\t/**\n\t * Close all database pools\n\t */\n\tasync closeAll(): Promise<void> {\n\t\tconst pgClosePromises = Array.from(this.pgPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed PostgreSQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mysqlClosePromises = Array.from(this.mysqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed MySQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mssqlClosePromises = Array.from(this.mssqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.close();\n\t\t\t\tconsole.log(`Closed SQL Server pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all([...pgClosePromises, ...mysqlClosePromises, ...mssqlClosePromises]);\n\t\tthis.pgPools.clear();\n\t\tthis.mysqlPools.clear();\n\t\tthis.mssqlPools.clear();\n\t\tif (this.mongoClient) {\n\t\t\tawait this.mongoClient.close();\n\t\t\tthis.mongoClient = null;\n\t\t}\n\t}\n\n\t/**\n\t * Get all active pool connection strings\n\t */\n\tgetActivePools(): string[] {\n\t\treturn [\n\t\t\t...Array.from(this.pgPools.keys()),\n\t\t\t...Array.from(this.mysqlPools.keys()),\n\t\t\t...Array.from(this.mssqlPools.keys()),\n\t\t];\n\t}\n}\n\n// Singleton instance\nconst databaseManager = new DatabaseManager();\n\n/**\n * Get a PostgreSQL pool for the specified database\n */\nexport const getDbPool = (database?: string): Pool => {\n\treturn databaseManager.getPgPool(database);\n};\n\n/**\n * Get a MySQL pool for the specified database\n */\nexport const getMysqlPool = (database?: string): MysqlPool => {\n\treturn databaseManager.getMysqlPool(database);\n};\n\n/**\n * Get a SQL Server pool for the specified database\n */\nexport const getMssqlPool = async (database?: string): Promise<MssqlPool> => {\n\treturn databaseManager.getMssqlPool(database);\n};\n\n/**\n * Get the detected database type from DATABASE_URL\n */\nexport const getDbType = (): DatabaseTypeSchema => {\n\treturn databaseManager.getDbType();\n};\n\n/**\n * Build a connection string for the specified database\n */\nconst _buildDbConnectionString = (database?: string): string => {\n\treturn databaseManager.buildConnectionString(database);\n};\n\n/**\n * Close a specific database pool by database name\n */\nconst _closeDbPool = async (database: string): Promise<void> => {\n\treturn databaseManager.closePoolByDatabase(database);\n};\n\n/**\n * Close a specific database pool by connection string\n */\nconst _closeDbPoolByConnectionString = async (connectionString: string): Promise<void> => {\n\treturn databaseManager.closePool(connectionString);\n};\n\n/**\n * Close all database pools\n */\nconst _closeAllDbPools = async (): Promise<void> => {\n\treturn databaseManager.closeAll();\n};\n\n/**\n * Get list of active pool connection strings\n */\nconst _getActivePools = (): string[] => {\n\treturn databaseManager.getActivePools();\n};\n\n/**\n * Get or create the MongoDB client\n */\nexport const getMongoClient = (): Promise<MongoClient> => {\n\treturn databaseManager.getMongoClient();\n};\n\n/**\n * Get the MongoDB database name from the connection URL\n */\nexport const getMongoDbName = (): string => {\n\treturn databaseManager.getMongoDbName();\n};\n\n/**\n * Get a MongoDB database instance\n */\nexport const getMongoDb = (dbName?: string) => {\n\treturn databaseManager.getMongoDb(dbName);\n};\n\nexport const isValidObjectId = (value: unknown): value is string => {\n\treturn typeof value === \"string\" && ObjectId.isValid(value);\n};\n\nexport const coerceObjectId = (value: unknown): unknown => {\n\tif (typeof value === \"string\" && ObjectId.isValid(value)) {\n\t\treturn new ObjectId(value);\n\t}\n\treturn value;\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tColumnInfoSchemaType,\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tDataTypes,\n\tFilterType,\n\tSortType,\n\tTableDataQuerySchemaType,\n\tTableDataResultSchemaType,\n\tTableInfoSchemaType,\n} from \"shared/types\";\nimport { coerceObjectId, getMongoDb, isValidObjectId } from \"@/db-manager.js\";\n\nconst MONGO_BSON_TYPES = new Set([\n\t\"double\",\n\t\"string\",\n\t\"object\",\n\t\"array\",\n\t\"binData\",\n\t\"undefined\",\n\t\"objectId\",\n\t\"bool\",\n\t\"date\",\n\t\"null\",\n\t\"regex\",\n\t\"dbPointer\",\n\t\"javascript\",\n\t\"symbol\",\n\t\"javascriptWithScope\",\n\t\"int\",\n\t\"timestamp\",\n\t\"long\",\n\t\"decimal\",\n\t\"minKey\",\n\t\"maxKey\",\n]);\n\nconst mapMongoBsonType = (rawType: string): string => {\n\tconst normalized = rawType.trim();\n\tif (MONGO_BSON_TYPES.has(normalized)) return normalized;\n\n\tswitch (normalized.toLowerCase()) {\n\t\tcase \"boolean\":\n\t\t\treturn \"bool\";\n\t\tcase \"objectid\":\n\t\t\treturn \"objectId\";\n\t\tcase \"binary\":\n\t\t\treturn \"binData\";\n\t\tdefault:\n\t\t\treturn normalized;\n\t}\n};\n\nconst SAMPLE_LIMIT = 200;\nconst encodeCursor = (offset: number): string =>\n\tBuffer.from(JSON.stringify({ offset })).toString(\"base64url\");\nconst decodeCursor = (cursor?: string): number => {\n\tif (!cursor) return 0;\n\ttry {\n\t\tconst parsed = JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\")) as {\n\t\t\toffset?: number;\n\t\t};\n\t\treturn typeof parsed.offset === \"number\" ? parsed.offset : 0;\n\t} catch {\n\t\treturn 0;\n\t}\n};\n\nconst normalizeValue = (value: unknown): unknown => {\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\tif (typeof value === \"bigint\") {\n\t\treturn value.toString();\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tif (\"_bsontype\" in value && (value as { _bsontype?: string })._bsontype === \"ObjectId\") {\n\t\t\treturn (value as { toHexString: () => string }).toHexString();\n\t\t}\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value.map((item) => normalizeValue(item));\n\t\t}\n\t\tconst entries = Object.entries(value as Record<string, unknown>).map(([k, v]) => [\n\t\t\tk,\n\t\t\tnormalizeValue(v),\n\t\t]);\n\t\treturn Object.fromEntries(entries);\n\t}\n\treturn value;\n};\n\nconst inferDataType = (value: unknown): DataTypes => {\n\tif (value instanceof Date) return \"date\";\n\tif (value && typeof value === \"object\") {\n\t\tif (Array.isArray(value)) return \"array\";\n\t\tif (\"_bsontype\" in value) return \"text\";\n\t\treturn \"json\";\n\t}\n\tif (typeof value === \"boolean\") return \"boolean\";\n\tif (typeof value === \"number\" || typeof value === \"bigint\") return \"number\";\n\treturn \"text\";\n};\n\nconst mapDataTypeLabel = (dataType: DataTypes): ColumnInfoSchemaType[\"dataTypeLabel\"] => {\n\tswitch (dataType) {\n\t\tcase \"number\":\n\t\t\treturn \"numeric\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"json\":\n\t\t\treturn \"json\";\n\t\tcase \"date\":\n\t\t\treturn \"date\";\n\t\tcase \"array\":\n\t\t\treturn \"array\";\n\t\tcase \"enum\":\n\t\t\treturn \"enum\";\n\t\tdefault:\n\t\t\treturn \"text\";\n\t}\n};\n\nconst buildMongoFilters = (filters: FilterType[]): Record<string, unknown> => {\n\tif (!filters || filters.length === 0) return {};\n\tconst andConditions: Record<string, unknown>[] = [];\n\tconst escapeRegex = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\tconst parseValue = (raw: string) => {\n\t\tconst trimmed = raw.trim();\n\t\tif (trimmed === \"null\") return null;\n\t\tif (trimmed === \"true\") return true;\n\t\tif (trimmed === \"false\") return false;\n\t\tconst asNumber = Number(trimmed);\n\t\tif (!Number.isNaN(asNumber) && trimmed !== \"\") return asNumber;\n\t\tif (isValidObjectId(trimmed)) return coerceObjectId(trimmed);\n\t\treturn trimmed;\n\t};\n\n\tfor (const filter of filters) {\n\t\tconst field = filter.columnName;\n\t\tconst value = parseValue(filter.value);\n\t\tconst op = filter.operator.toLowerCase();\n\n\t\tif (!field) continue;\n\n\t\tswitch (op) {\n\t\t\tcase \"=\":\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t\tcase \"!=\":\n\t\t\t\tandConditions.push({ [field]: { $ne: value } });\n\t\t\t\tbreak;\n\t\t\tcase \">\":\n\t\t\t\tandConditions.push({ [field]: { $gt: value } });\n\t\t\t\tbreak;\n\t\t\tcase \">=\":\n\t\t\t\tandConditions.push({ [field]: { $gte: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"<\":\n\t\t\t\tandConditions.push({ [field]: { $lt: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"<=\":\n\t\t\t\tandConditions.push({ [field]: { $lte: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tandConditions.push({ [field]: { $ne: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$regex: escapeRegex(String(value)),\n\t\t\t\t\t\t$options: \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$not: { $regex: escapeRegex(String(value)), $options: \"\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$regex: escapeRegex(String(value)),\n\t\t\t\t\t\t$options: \"i\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$not: { $regex: escapeRegex(String(value)), $options: \"i\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn andConditions.length ? { $and: andConditions } : {};\n};\n\nconst buildMongoSort = (\n\tsort: TableDataQuerySchemaType[\"sort\"],\n\torder?: TableDataQuerySchemaType[\"order\"],\n): Record<string, 1 | -1> => {\n\tif (!sort) return { _id: 1 };\n\n\tif (Array.isArray(sort)) {\n\t\tconst sortEntries = (sort as SortType[]).map((s) => [\n\t\t\ts.columnName,\n\t\t\ts.direction === \"desc\" ? -1 : 1,\n\t\t]);\n\t\treturn Object.fromEntries(sortEntries);\n\t}\n\n\tif (typeof sort === \"string\" && sort.length > 0) {\n\t\treturn { [sort]: order === \"desc\" ? -1 : 1 };\n\t}\n\n\treturn { _id: 1 };\n};\n\nexport async function getMongoTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections().toArray();\n\n\tconst results: TableInfoSchemaType[] = [];\n\tfor (const collection of collections) {\n\t\tconst name = collection.name;\n\t\tconst rowCount = await mongoDb.collection(name).estimatedDocumentCount();\n\t\tresults.push({ tableName: name, rowCount });\n\t}\n\n\treturn results;\n}\n\nexport async function getMongoTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst documents = await collection.find({}).limit(SAMPLE_LIMIT).toArray();\n\tconst totalDocs = documents.length;\n\n\tconst columnMap = new Map<\n\t\tstring,\n\t\t{\n\t\t\ttypes: Set<DataTypes>;\n\t\t\tnullable: boolean;\n\t\t\tpresentCount: number;\n\t\t}\n\t>();\n\n\tconst ensureColumn = (columnName: string, value: unknown) => {\n\t\tconst dataType = inferDataType(value);\n\t\tif (!columnMap.has(columnName)) {\n\t\t\tcolumnMap.set(columnName, {\n\t\t\t\ttypes: new Set([dataType]),\n\t\t\t\tnullable: false,\n\t\t\t\tpresentCount: 1,\n\t\t\t});\n\t\t} else {\n\t\t\tconst entry = columnMap.get(columnName);\n\t\t\tif (entry) {\n\t\t\t\tentry.types.add(dataType);\n\t\t\t\tentry.presentCount += 1;\n\t\t\t}\n\t\t}\n\t};\n\n\tfor (const doc of documents) {\n\t\tfor (const [key, value] of Object.entries(doc)) {\n\t\t\tif (value === null || value === undefined) {\n\t\t\t\tif (!columnMap.has(key)) {\n\t\t\t\t\tcolumnMap.set(key, {\n\t\t\t\t\t\ttypes: new Set([\"text\"]),\n\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\tpresentCount: 1,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst entry = columnMap.get(key);\n\t\t\t\t\tif (entry) entry.nullable = true;\n\t\t\t\t\tif (entry) entry.presentCount += 1;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tensureColumn(key, value);\n\t\t}\n\t}\n\n\tif (totalDocs > 0) {\n\t\tfor (const entry of columnMap.values()) {\n\t\t\tif (entry.presentCount < totalDocs) {\n\t\t\t\tentry.nullable = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!columnMap.has(\"_id\")) {\n\t\tcolumnMap.set(\"_id\", {\n\t\t\ttypes: new Set([\"text\"]),\n\t\t\tnullable: false,\n\t\t\tpresentCount: totalDocs,\n\t\t});\n\t}\n\n\treturn Array.from(columnMap.entries()).map(([columnName, meta]) => {\n\t\tconst dataType = meta.types.values().next().value ?? \"text\";\n\t\treturn {\n\t\t\tcolumnName,\n\t\t\tdataType,\n\t\t\tdataTypeLabel: mapDataTypeLabel(dataType),\n\t\t\tisNullable: meta.nullable,\n\t\t\tcolumnDefault: null,\n\t\t\tisPrimaryKey: columnName === \"_id\",\n\t\t\tisForeignKey: false,\n\t\t\treferencedTable: null,\n\t\t\treferencedColumn: null,\n\t\t\tenumValues: null,\n\t\t};\n\t});\n}\n\nexport async function getMongoTableData({\n\ttableName,\n\tcursor,\n\tlimit,\n\tdirection,\n\tsort,\n\torder,\n\tfilters,\n\tdb,\n}: {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: TableDataQuerySchemaType[\"direction\"];\n\tsort?: TableDataQuerySchemaType[\"sort\"];\n\torder?: TableDataQuerySchemaType[\"order\"];\n\tfilters?: TableDataQuerySchemaType[\"filters\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<TableDataResultSchemaType> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst filterObject = buildMongoFilters(filters ?? []);\n\tconst sortObject = buildMongoSort(sort ?? \"\", order);\n\n\tconst safeLimit = limit && limit > 0 ? limit : 50;\n\tconst decodedCursor = decodeCursor(cursor);\n\tconst offset = Number.isFinite(decodedCursor) && decodedCursor >= 0 ? decodedCursor : 0;\n\tconst skip = direction === \"desc\" ? Math.max(offset - safeLimit, 0) : offset;\n\n\tconst [total, rows] = await Promise.all([\n\t\tcollection.countDocuments(filterObject),\n\t\tcollection.find(filterObject).sort(sortObject).skip(skip).limit(safeLimit).toArray(),\n\t]);\n\n\tconst normalizedRows = rows.map((row) => normalizeValue(row) as Record<string, unknown>);\n\tconst nextOffset = skip + safeLimit;\n\tconst prevOffset = Math.max(skip - safeLimit, 0);\n\n\treturn {\n\t\tdata: normalizedRows,\n\t\tmeta: {\n\t\t\tlimit: safeLimit,\n\t\t\ttotal,\n\t\t\thasNextPage: nextOffset < total,\n\t\t\thasPreviousPage: skip > 0,\n\t\t\tnextCursor: nextOffset < total ? encodeCursor(nextOffset) : null,\n\t\t\tprevCursor: skip > 0 ? encodeCursor(prevOffset) : null,\n\t\t},\n\t};\n}\n\nexport async function createMongoCollection({\n\ttableName,\n\ttableData,\n\tdb,\n}: {\n\ttableName: string;\n\ttableData?: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length > 0) {\n\t\tthrow new HTTPException(400, { message: `Collection \"${tableName}\" already exists` });\n\t}\n\n\tconst fields = tableData?.fields ?? [];\n\tif (fields.length === 0) {\n\t\tawait mongoDb.createCollection(tableName);\n\t\treturn;\n\t}\n\n\tconst properties: Record<string, unknown> = {};\n\tconst required: string[] = [];\n\n\tfor (const field of fields) {\n\t\tconst bsonType = mapMongoBsonType(field.columnType);\n\t\tif (!MONGO_BSON_TYPES.has(bsonType)) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Unsupported MongoDB BSON type \"${field.columnType}\" for field \"${field.columnName}\"`,\n\t\t\t});\n\t\t}\n\n\t\tif (field.isArray) {\n\t\t\tproperties[field.columnName] = {\n\t\t\t\tbsonType: \"array\",\n\t\t\t\t...(bsonType !== \"array\" ? { items: { bsonType } } : {}),\n\t\t\t};\n\t\t} else {\n\t\t\tproperties[field.columnName] = { bsonType };\n\t\t}\n\n\t\tif (!field.isNullable) {\n\t\t\trequired.push(field.columnName);\n\t\t}\n\t}\n\n\tawait mongoDb.createCollection(tableName, {\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\tbsonType: \"object\",\n\t\t\t\trequired,\n\t\t\t\tproperties,\n\t\t\t\tadditionalProperties: true,\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"error\",\n\t});\n}\n\nexport async function deleteMongoColumn({\n\ttableName,\n\tcolumnName,\n\tdb,\n}: {\n\ttableName: string;\n\tcolumnName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ deletedCount: number }> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst result = await collection.updateMany({}, { $unset: { [columnName]: \"\" } });\n\treturn { deletedCount: result.modifiedCount };\n}\n\nexport async function exportMongoTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, unknown>[] }> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst rows = await collection.find({}).limit(10000).toArray();\n\tconst normalized = rows.map((row) => normalizeValue(row) as Record<string, unknown>);\n\tconst cols = Array.from(new Set(normalized.flatMap((row) => Object.keys(row))));\n\treturn { cols, rows: normalized };\n}\n\nexport const normalizeMongoDocument = normalizeValue;\nexport const buildMongoFiltersForQuery = buildMongoFilters;\nexport const buildMongoSortForQuery = buildMongoSort;\nexport const toMongoId = coerceObjectId;\nexport const canCoerceObjectId = isValidObjectId;\n","import type { Column, DatabaseSchema, DatabaseSchemaType, Table } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { getMongoTableColumns, normalizeMongoDocument } from \"./tables.dao.js\";\n\nconst convertColumn = (col: {\n\tcolumnName: string;\n\tdataTypeLabel: string;\n\tisNullable: boolean;\n\tisPrimaryKey: boolean;\n}): Column => ({\n\tname: col.columnName,\n\ttype: col.dataTypeLabel,\n\tnullable: col.isNullable,\n\tisPrimaryKey: col.isPrimaryKey,\n});\n\nexport async function getMongoDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tconst { includeSampleData = false, maxTables } = options;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections().toArray();\n\tconst limitedCollections =\n\t\ttypeof maxTables === \"number\" && maxTables > 0\n\t\t\t? collections.slice(0, maxTables)\n\t\t\t: collections;\n\n\tconst tablePromises = limitedCollections.map(async (collection) => {\n\t\tconst name = collection.name;\n\t\tconst columns = await getMongoTableColumns({ tableName: name, db });\n\t\tconst table: Table = {\n\t\t\tname,\n\t\t\tcolumns: columns.map(convertColumn),\n\t\t};\n\n\t\tif (includeSampleData) {\n\t\t\tconst rows = await mongoDb.collection(name).find({}).limit(3).toArray();\n\t\t\tconst normalized = rows.map(\n\t\t\t\t(row) => normalizeMongoDocument(row) as Record<string, unknown>,\n\t\t\t);\n\t\t\ttable.sampleData = normalized.map((row) =>\n\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t);\n\t\t}\n\n\t\treturn table;\n\t});\n\n\tconst tables = await Promise.all(tablePromises);\n\n\treturn {\n\t\tdbType: \"mongodb\",\n\t\ttables,\n\t\trelationships: [],\n\t};\n}\n","import { Pool } from \"pg\";\n\nlet dbInstance: Pool | null = null;\n\nconst getPool = (): Pool => {\n\tif (!dbInstance) {\n\t\tif (!process.env.DATABASE_URL) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\t\ttry {\n\t\t\tdbInstance = new Pool({\n\t\t\t\tconnectionString: process.env.DATABASE_URL,\n\t\t\t});\n\n\t\t\t// Handle pool errors to prevent server crashes\n\t\t\t// This catches connection errors, idle client errors, etc.\n\t\t\tdbInstance.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\"Unexpected database pool error:\", err.message);\n\t\t\t\t// Don't throw - just log the error to prevent server crash\n\t\t\t\t// The pool will automatically retry connections\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to create database pool:\", error);\n\t\t\t// Re-throw initialization errors as they indicate a configuration problem\n\t\t\tthrow error;\n\t\t}\n\t}\n\treturn dbInstance;\n};\n\n// Export db as a Proxy that lazily initializes the pool\n// This allows process.env.DATABASE_URL to be set after module import\nexport const db = new Proxy({} as Pool, {\n\tget(_target, prop) {\n\t\ttry {\n\t\t\treturn getPool()[prop as keyof Pool];\n\t\t} catch (error) {\n\t\t\t// If pool initialization fails, log and re-throw\n\t\t\tconsole.error(\"Database pool access error:\", error);\n\t\t\tthrow error;\n\t\t}\n\t},\n});\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\ttype DatabaseSchemaType,\n\tmapPostgresToDataType,\n\tstandardizeDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n SELECT \n c.column_name as \"columnName\",\n c.data_type as \"dataType\",\n c.udt_name as \"udtName\",\n c.is_nullable = 'YES' as \"isNullable\",\n c.column_default as \"columnDefault\",\n CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as \"isPrimaryKey\",\n CASE WHEN fk.column_name IS NOT NULL THEN true ELSE false END as \"isForeignKey\",\n fk.referenced_table as \"referencedTable\",\n fk.referenced_column as \"referencedColumn\",\n CASE \n WHEN c.data_type = 'USER-DEFINED' THEN \n (SELECT array_agg(e.enumlabel ORDER BY e.enumsortorder)\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE t.typname = c.udt_name)\n ELSE NULL\n END as \"enumValues\"\n FROM information_schema.columns c\n LEFT JOIN (\n SELECT ku.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage ku\n ON tc.constraint_name = ku.constraint_name\n AND tc.table_schema = ku.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) pk ON c.column_name = pk.column_name\n LEFT JOIN (\n SELECT \n kcu.column_name,\n ccu.table_name AS referenced_table,\n ccu.column_name AS referenced_column\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) fk ON c.column_name = fk.column_name\n WHERE c.table_schema = 'public'\n AND c.table_name = $1\n ORDER BY c.ordinal_position;\n `;\n\n\tconst { rows } = await pool.query(query, [tableName]);\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\t// Parse enumValues to always return string[] | null\n\t\tlet parsedEnumValues: string[] | null = null;\n\t\tif (r.enumValues) {\n\t\t\tif (Array.isArray(r.enumValues)) {\n\t\t\t\t// Already an array, use as-is\n\t\t\t\tparsedEnumValues = r.enumValues;\n\t\t\t} else if (typeof r.enumValues === \"string\") {\n\t\t\t\t// Parse PostgreSQL array format: \"{VALUE1,VALUE2,VALUE3}\"\n\t\t\t\tparsedEnumValues = r.enumValues.replace(/[{}]/g, \"\").split(\",\").filter(Boolean);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapPostgresToDataType(r.dataType),\n\t\t\tdataTypeLabel: standardizeDataTypeLabel(r.dataType),\n\t\t\tisNullable: r.isNullable,\n\t\t\tcolumnDefault: r.columnDefault,\n\t\t\tisPrimaryKey: r.isPrimaryKey,\n\t\t\tisForeignKey: r.isForeignKey,\n\t\t\treferencedTable: r.referencedTable,\n\t\t\treferencedColumn: r.referencedColumn,\n\t\t\tenumValues: parsedEnumValues,\n\t\t};\n\t});\n}\n","import type {\n\tColumn,\n\tColumnInfoSchemaType,\n\tDatabaseSchema,\n\tDatabaseSchemaType,\n\tRelationship,\n\tTable,\n} from \"shared/types\";\nimport { getMongoDatabaseSchema } from \"@/dao/mongo/schema.dao.js\";\nimport { db } from \"@/db.js\";\nimport { getDbPool, getDbType } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.dao.js\";\n\n/**\n * Get all table names from the database\n */\nasync function getTableNames(db: DatabaseSchemaType[\"db\"]): Promise<string[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n\t\tSELECT table_name\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t\tAND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\tconst { rows } = await pool.query(query);\n\treturn rows.map((r) => r.table_name);\n}\n\n/**\n * Get table comment/description if available\n */\nasync function getTableDescription(tableName: string): Promise<string | undefined> {\n\tconst client = await db.connect();\n\ttry {\n\t\tconst res = await client.query(\n\t\t\t`\n SELECT obj_description(oid) as description\n FROM pg_class\n WHERE relname = $1\n AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');\n `,\n\t\t\t[tableName],\n\t\t);\n\t\treturn res.rows[0]?.description || undefined;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Get sample data from a table (first 3 rows)\n */\nasync function getSampleData(tableName: string): Promise<Record<string, unknown>[]> {\n\tconst client = await db.connect();\n\ttry {\n\t\t// Sanitize table name to prevent SQL injection\n\t\t// In production, validate tableName against known tables list\n\t\tconst res = await client.query(`SELECT * FROM \"${tableName}\" LIMIT 3`);\n\t\treturn res.rows;\n\t} catch (error) {\n\t\tconsole.warn(`Could not fetch sample data for table ${tableName}:`, error);\n\t\treturn [];\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Convert ColumnInfo to the schema Column format\n */\nfunction convertColumnInfo(col: ColumnInfoSchemaType): Column {\n\tconst column: Column = {\n\t\tname: col.columnName,\n\t\ttype: col.dataTypeLabel,\n\t\tnullable: col.isNullable,\n\t};\n\n\tif (col.isPrimaryKey) {\n\t\tcolumn.isPrimaryKey = true;\n\t}\n\n\tif (col.isForeignKey && col.referencedTable && col.referencedColumn) {\n\t\tcolumn.foreignKey = `${col.referencedTable}.${col.referencedColumn}`;\n\t}\n\n\tif (col.enumValues && col.enumValues.length > 0) {\n\t\tcolumn.enumValues = col.enumValues;\n\t\tcolumn.description = `Enum values: ${col.enumValues.join(\", \")}`;\n\t}\n\n\treturn column;\n}\n\n/**\n * Extract all relationships from table columns\n */\nfunction extractRelationships(tables: Table[]): Relationship[] {\n\tconst relationships: Relationship[] = [];\n\n\tfor (const table of tables) {\n\t\tfor (const column of table.columns) {\n\t\t\tif (column.foreignKey) {\n\t\t\t\tconst [toTable, toColumn] = column.foreignKey.split(\".\");\n\t\t\t\trelationships.push({\n\t\t\t\t\tfromTable: table.name,\n\t\t\t\t\tfromColumn: column.name,\n\t\t\t\t\ttoTable,\n\t\t\t\t\ttoColumn,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\n/**\n * Get complete database schema with all tables, columns, and relationships\n */\nasync function getDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tincludeDescriptions?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tif (getDbType() === \"mongodb\") {\n\t\treturn getMongoDatabaseSchema(db, {\n\t\t\tincludeSampleData: options.includeSampleData,\n\t\t});\n\t}\n\n\tconst {\n\t\tincludeSampleData = false,\n\t\tincludeDescriptions = true,\n\t\t// maxTables = 50, // Prevent overwhelming the context\n\t} = options;\n\n\ttry {\n\t\tconst tableNames = await getTableNames(db);\n\n\t\t// Fetch schema info for each table in parallel\n\t\tconst tablePromises = tableNames.map(async (tableName) => {\n\t\t\tconst [columns, description, sampleData] = await Promise.all([\n\t\t\t\tgetTableColumns({ tableName, db }),\n\t\t\t\tincludeDescriptions ? getTableDescription(tableName) : Promise.resolve(undefined),\n\t\t\t\tincludeSampleData ? getSampleData(tableName) : Promise.resolve([]),\n\t\t\t]);\n\n\t\t\tconst table: Table = {\n\t\t\t\tname: tableName,\n\t\t\t\tcolumns: columns.map(convertColumnInfo),\n\t\t\t};\n\n\t\t\tif (description) {\n\t\t\t\ttable.description = description;\n\t\t\t}\n\n\t\t\tif (sampleData.length > 0) {\n\t\t\t\ttable.sampleData = sampleData.map((row) =>\n\t\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn table;\n\t\t});\n\n\t\tconst tables = await Promise.all(tablePromises);\n\n\t\t// Extract relationships from foreign keys\n\t\tconst relationships = extractRelationships(tables);\n\n\t\treturn {\n\t\t\tdbType: \"pg\",\n\t\t\ttables,\n\t\t\trelationships,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Error fetching database schema:\", error);\n\t\tthrow new Error(\n\t\t\t`Failed to fetch database schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Get detailed schema with sample data (for initial conversation context)\n */\nexport async function getDetailedSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<DatabaseSchema> {\n\treturn getDatabaseSchema(db, {\n\t\tincludeSampleData: true,\n\t\tincludeDescriptions: true,\n\t\t// maxTables: 30, // todo: DELETE THIS AFTER TESTING\n\t});\n}\n","import type { DatabaseSchema } from \"shared/types\";\n\n/**\n * Generate system prompt with database context\n */\nexport function generateSystemPrompt(schema: DatabaseSchema): string {\n\tconst dbTypeLower = schema.dbType.toLowerCase();\n\tconst dbTypeLabel = schema.dbType === \"pg\" ? \"PostgreSQL\" : schema.dbType;\n\tif (dbTypeLower.includes(\"mongo\")) {\n\t\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating a query\n2. When generating MongoDB queries:\n - Provide 1 sentence explanation\n - The MongoDB query in a JSON code block\n - 1 sentence about expected results\n3. Use exact collection/field names from the schema\n4. If query is unclear, ask ONE specific clarifying question\n5. No preamble, no apologies, get straight to the answer\n6. IMPORTANT: When the user asks about collections, fields, or any schema information, answer DIRECTLY from the \"Database Context\" above — do NOT generate a query to retrieve schema info you already have\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct MongoDB queries\n2. Use proper collection/field names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`json code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. Warn about potentially expensive operations (collection scans, large aggregations)\n8. Consider data privacy - remind users not to share sensitive data externally\n\n**Query Format:**\nReturn a JSON object with the following shape:\n{\n \"collection\": \"collectionName\",\n \"operation\": \"find|aggregate|insertOne|insertMany|updateOne|updateMany|deleteOne|deleteMany|count\",\n \"filter\": { ... },\n \"pipeline\": [ ... ],\n \"document\": { ... } | [ ... ],\n \"update\": { ... },\n \"options\": { ... },\n \"sort\": { \"field\": 1 },\n \"limit\": 100,\n \"skip\": 0\n}\n\nOnly include the fields needed for the chosen operation.\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll aggregate orders to calculate total revenue per customer.\n\n\\`\\`\\`json\n{\n \"collection\": \"orders\",\n \"operation\": \"aggregate\",\n \"pipeline\": [\n { \"$group\": { \"_id\": \"$customer_id\", \"total\": { \"$sum\": \"$total_amount\" } } },\n { \"$sort\": { \"total\": -1 } },\n { \"$limit\": 5 }\n ]\n}\n\\`\\`\\`\n\nThis will return the top 5 customers by revenue.\"`;\n\t}\n\n\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating SQL\n2. When generating SQL:\n - Provide 1 sentence explanation\n - The SQL query in a code block\n - 1 sentence about expected results\n - NO verbose explanations\n3. Use exact table/column names from the schema\n4. Generate valid ${dbTypeLabel} syntax\n5. If query is unclear, ask ONE specific clarifying question\n6. No preamble, no apologies, get straight to the answer\n7. IMPORTANT: When the user asks about tables, columns, relationships, or any schema information, answer DIRECTLY from the \"Database Context\" above — do NOT generate a SQL query to retrieve schema info you already have\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct SQL for the database type (${dbTypeLabel})\n2. Use proper table/column names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`sql code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. For complex queries, break down the logic step-by-step\n8. Warn about potentially expensive operations (full table scans, etc.)\n9. Consider data privacy - remind users not to share sensitive data externally\n\n**Response Format:**\nWhen generating queries, use this structure:\n- Brief explanation of what you'll do\n- The SQL query in a code block\n- Expected results description\n- Optional: suggestions for related queries\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll query the orders and customers tables to find your highest-value customers.\n\n\\`\\`\\`sql\nSELECT \n c.customer_name,\n SUM(o.total_amount) as total_revenue\nFROM customers c\nJOIN orders o ON c.id = o.customer_id\nGROUP BY c.id, c.customer_name\nORDER BY total_revenue DESC\nLIMIT 5;\n\\`\\`\\`\n\nThis will return the 5 customers with the highest total order value. You might also want to see:\n- Revenue trends over time for these customers\n- Their most frequently ordered products\"`;\n}\n\n/**\n * Format schema information for the prompt\n */\nfunction formatSchemaForPrompt(schema: DatabaseSchema): string {\n\tconst dbTypeLabel = schema.dbType === \"pg\" ? \"PostgreSQL\" : schema.dbType;\n\tlet output = `Database Type: ${dbTypeLabel}\\n\\n`;\n\n\toutput += \"**Tables and Columns:**\\n\";\n\tfor (const table of schema.tables) {\n\t\toutput += `\\n### ${table.name}\\n`;\n\t\tif (table.description) {\n\t\t\toutput += `Description: ${table.description}\\n`;\n\t\t}\n\t\toutput += \"Columns:\\n\";\n\n\t\tfor (const col of table.columns) {\n\t\t\tconst pkIndicator = col.isPrimaryKey ? \" [PRIMARY KEY]\" : \"\";\n\t\t\tconst fkIndicator = col.foreignKey ? ` [FK -> ${col.foreignKey}]` : \"\";\n\t\t\tconst nullable = col.nullable ? \"NULL\" : \"NOT NULL\";\n\n\t\t\toutput += ` - ${col.name}: ${col.type} ${nullable}${pkIndicator}${fkIndicator}\\n`;\n\t\t\tif (col.description) {\n\t\t\t\toutput += ` ${col.description}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add sample data if available\n\t\tif (table.sampleData && table.sampleData.length > 0) {\n\t\t\toutput += `Sample data (${table.sampleData.length} rows):\\n`;\n\t\t\toutput += `${JSON.stringify(table.sampleData.slice(0, 3), null, 2)}\\n`;\n\t\t}\n\t}\n\n\t// Add relationships\n\tif (schema.relationships && schema.relationships.length > 0) {\n\t\toutput += \"\\n**Relationships:**\\n\";\n\t\tfor (const rel of schema.relationships) {\n\t\t\toutput += ` - ${rel.fromTable}.${rel.fromColumn} -> ${rel.toTable}.${rel.toColumn}\\n`;\n\t\t}\n\t}\n\n\treturn output;\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { chatSchema } from \"shared/types\";\nimport { getDetailedSchema } from \"@/dao/table-details-schema.js\";\nimport { generateSystemPrompt } from \"@/utils/system-prompt-generator.js\";\n\nexport const chatRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /:dbType/chat/...\n\t */\n\t.basePath(\"/chat\")\n\n\t/**\n\t * GET /chat/limit - Proxy rate limit check to Cloudflare Worker\n\t */\n\t.get(\"/limit\", async (c) => {\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat/limit`, {\n\t\t\theaders: {\n\t\t\t\t\"cf-connecting-ip\": c.req.header(\"cf-connecting-ip\") ?? \"\",\n\t\t\t\t\"x-real-ip\": c.req.header(\"x-real-ip\") ?? \"\",\n\t\t\t\t\"x-forwarded-for\": c.req.header(\"x-forwarded-for\") ?? \"\",\n\t\t\t\t\"x-api-key\": c.req.header(\"x-api-key\") ?? \"\",\n\t\t\t},\n\t\t});\n\t\tconst data = await proxyResponse.json();\n\t\treturn c.json(data, proxyResponse.status as 200 | 500);\n\t})\n\n\t/**\n\t * POST /chat - Handle AI chat requests with streaming\n\t * Proxies to the Cloudflare Worker which has the Gemini API key\n\t */\n\t.post(\"/\", zValidator(\"json\", chatSchema), async (c) => {\n\t\tconst { messages, data } = c.req.valid(\"json\");\n\t\tconst { db, conversationId } = data;\n\t\tconsole.log(\"POST /chat messages\", messages);\n\n\t\t// Get the database schema and generate system prompt\n\t\tconst schema = await getDetailedSchema(db);\n\t\tconst systemPrompt = generateSystemPrompt(schema);\n\n\t\tconst payload = {\n\t\t\tmessages,\n\t\t\tconversationId,\n\t\t\tsystemPrompt,\n\t\t};\n\n\t\t// Forward request to the proxy with the system prompt.\n\t\t// Pass through IP headers so the proxy rate-limiter keys on the real user IP.\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"cf-connecting-ip\": c.req.header(\"cf-connecting-ip\") ?? \"\",\n\t\t\t\t\"x-real-ip\": c.req.header(\"x-real-ip\") ?? \"\",\n\t\t\t\t\"x-forwarded-for\": c.req.header(\"x-forwarded-for\") ?? \"\",\n\t\t\t\t\"x-api-key\": c.req.header(\"x-api-key\") ?? \"\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\n\t\tif (!proxyResponse.ok) {\n\t\t\tconst errorData = await proxyResponse.json();\n\t\t\treturn c.json(\n\t\t\t\t{ error: errorData.error || \"Proxy request failed\" },\n\t\t\t\tproxyResponse.status as 400 | 500,\n\t\t\t);\n\t\t}\n\n\t\t// Stream the SSE response back to the client\n\t\tconst { readable, writable } = new TransformStream();\n\t\tproxyResponse.body?.pipeTo(writable);\n\n\t\treturn new Response(readable, {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\tConnection: \"keep-alive\",\n\t\t\t},\n\t\t});\n\t});\n\nexport type ChatRoutes = typeof chatRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getDbPool(db);\n\n\t// Extract column names and values\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data);\n\n\t// Build the INSERT query\n\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\tconst query = `\n\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\tVALUES (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\tconst result = await pool.query(query, values);\n\tif (result.rowCount === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getDbPool(db);\n\tconst client = await pool.connect();\n\n\ttry {\n\t\t// Get column names from the first record\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\t\tlet successCount = 0;\n\t\tconst failureCount = 0;\n\t\tconst errors: Array<{ recordIndex: number; error: string }> = [];\n\n\t\t// Execute inserts in a transaction\n\t\tawait client.query(\"BEGIN\");\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => record[col]);\n\n\t\t\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait client.query(insertSQL, values);\n\t\t\t\tsuccessCount++;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\n\t\treturn {\n\t\t\tsuccess: failureCount === 0,\n\t\t\tmessage: `Bulk insert completed: ${successCount} records inserted${failureCount > 0 ? `, ${failureCount} failed` : \"\"}`,\n\t\t\tsuccessCount,\n\t\t\tfailureCount,\n\t\t\terrors: errors.length > 0 ? errors : undefined,\n\t\t};\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tclient.release();\n\t}\n};\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getDbPool(db);\n\n\t// Build column definitions\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tlet columnDef = `\"${field.columnName}\" ${field.columnType}`;\n\n\t\t// Add array suffix if needed\n\t\tif (field.isArray) {\n\t\t\tcolumnDef += \"[]\";\n\t\t}\n\n\t\t// Add PRIMARY KEY constraint\n\t\tif (field.isPrimaryKey) {\n\t\t\tcolumnDef += \" PRIMARY KEY\";\n\t\t}\n\n\t\t// Add UNIQUE constraint\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" UNIQUE\";\n\t\t}\n\n\t\t// Add NOT NULL constraint (if not nullable)\n\t\tif (!field.isNullable) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Add GENERATED ALWAYS AS IDENTITY for identity columns\n\t\tif (field.isIdentity) {\n\t\t\tcolumnDef += \" GENERATED ALWAYS AS IDENTITY\";\n\t\t}\n\n\t\t// Add default value\n\t\tif (field.defaultValue && !field.isIdentity) {\n\t\t\tcolumnDef += ` DEFAULT ${field.defaultValue}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Build foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \"${constraintName}\" FOREIGN KEY (\"${fk.columnName}\") REFERENCES \"${fk.referencedTable}\" (\"${fk.referencedColumn}\") ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\t// Combine column definitions and foreign key constraints\n\tconst allDefinitions = [...columnDefinitions, ...foreignKeyConstraints];\n\n\t// Create the table\n\tconst createTableSQL = `\n\t\t\tCREATE TABLE \"${tableName}\" (\n\t\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\\t\")}\n\t\t\t);\n\t\t`;\n\n\tawait pool.query(createTableSQL);\n}\n","/**\n * Parse DATABASE_URL to extract host and port\n */\nexport function parseDatabaseUrl(): { host: string; port: number } {\n\tconst databaseUrl = process.env.DATABASE_URL;\n\n\tif (!databaseUrl) {\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n\n\ttry {\n\t\tconst url = new URL(databaseUrl);\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tconst defaultPort = protocol === \"mongodb\" || protocol === \"mongodb+srv\" ? 27017 : 5432;\n\t\treturn {\n\t\t\thost: url.hostname || \"localhost\",\n\t\t\tport: Number.parseInt(url.port, 10) || defaultPort,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Failed to parse DATABASE_URL:\", error);\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ConnectionInfoSchemaType,\n\tconnectionInfoSchema,\n\ttype DatabaseInfoSchemaType,\n\ttype DatabaseSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all normal databases on the PostgreSQL server.\n * Returns name, size (human readable), owner, and encoding.\n *\n * @returns List of database information objects\n * @throws Error if query fails or no databases are found\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n d.datname as name,\n pg_size_pretty(pg_database_size(d.datname)) as size,\n pg_catalog.pg_get_userbyid(d.datdba) as owner,\n pg_encoding_to_char(d.encoding) as encoding\n FROM pg_catalog.pg_database d\n WHERE d.datistemplate = false\n ORDER BY d.datname;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from database\",\n\t\t});\n\t}\n\n\treturn rows;\n}\n\n/**\n * Gets the name of the database we are currently using.\n *\n * @returns Object with current database name\n * @throws Error if query fails or no name is returned\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = \"SELECT current_database() as database;\";\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from database\",\n\t\t});\n\t}\n\n\treturn rows[0];\n}\n\n/**\n * Gets useful information about the connection and PostgreSQL server.\n * Includes version, host, port, user, database name, active connections, etc.\n *\n * Uses fallback values from DATABASE_URL if some fields are missing.\n *\n * @returns Connection and server information object\n * @throws Error if query fails or result is invalid\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n version() as version,\n current_database() as database,\n current_user as user,\n inet_server_addr() as host,\n inet_server_port() as port,\n (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,\n (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from database\",\n\t\t});\n\t}\n\n\t// Validate main result\n\tconst result = connectionInfoSchema.parse(rows[0]);\n\n\t// Use DATABASE_URL as backup for host/port if needed\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: result.host || urlDefaults.host,\n\t\tport: result.port || urlDefaults.port,\n\t\tuser: result.user,\n\t\tdatabase: result.database,\n\t\tversion: result.version.toString(),\n\t\tactive_connections: result.active_connections,\n\t\tmax_connections: result.max_connections,\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a table using ALTER TABLE DROP COLUMN.\n * Uses CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies.\n *\n * @param params.tableName - Name of the table containing the column\n * @param params.columnName - Name of the column to delete\n * @param params.cascade - If true, uses CASCADE; if false, uses RESTRICT\n * @param params.db - Optional database name to connect to\n * @returns {Object} Object with deleted count\n * @throws HTTPException if table or column does not exist\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, cascade, db } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check if column exists\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns \n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Use CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies\n\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\tconst dropColumnSQL = `ALTER TABLE \"${tableName}\" DROP COLUMN \"${columnName}\" ${dropMode}`;\n\n\tconst { rowCount } = await pool.query(dropColumnSQL);\n\n\treturn { deletedCount: rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Finds all records in other tables that reference the given primary key values\n */\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\t// Group constraints by referencing table and column for efficiency\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) {\n\t\t\tconstraintsByTable.set(key, []);\n\t\t}\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\t// Get the primary key values that we're looking for\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\t// Find which primary key column matches this FK's referenced column\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\t// Build query to find related records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tWHERE \"${constraint.referencingColumn}\" IN (${placeholders})\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery, pkValues);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Attempts to delete records. If FK violation occurs, returns related records.\n */\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\n\tconst query = `\n\t\tDELETE FROM \"${tableName}\"\n\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\tRETURNING *\n\t`;\n\n\ttry {\n\t\tawait pool.query(\"BEGIN\");\n\t\tconst result = await pool.query(query, pkValues);\n\t\tawait pool.query(\"COMMIT\");\n\t\treturn { deletedCount: result.rowCount ?? 0, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\t// Check if this is a foreign key violation\n\t\tconst pgError = error as {\n\t\t\tcode?: string;\n\t\t\tdetail?: string;\n\t\t\tconstraint?: string;\n\t\t};\n\n\t\tif (pgError.code === \"23503\") {\n\t\t\t// Fetch related records to show the user\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\n/**\n * Force deletes records by first deleting all related records in referencing tables (cascade)\n */\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\t// Get all FK constraints that reference this table\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\t\tlet totalRelatedDeleted = 0;\n\n\t\t// Delete related records in reverse dependency order\n\t\t// We need to handle nested FKs recursively\n\t\tconst deletedTables = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t) => {\n\t\t\t// First, find if there are tables referencing the target table\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\t// Get the values that will be deleted from the target table\n\t\t\t\tconst nestedPlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\t\tconst selectQuery = `\n\t\t\t\t\tSELECT \"${nestedFk.referencedColumn}\" FROM \"${targetTable}\"\n\t\t\t\t\tWHERE \"${targetColumn}\" IN (${nestedPlaceholders})\n\t\t\t\t`;\n\n\t\t\t\tconst selectResult = await pool.query(selectQuery, values);\n\t\t\t\tconst nestedValues = selectResult.rows.map(\n\t\t\t\t\t({ row }: { row: { [nestedFk.referencedColumn]: unknown } }) =>\n\t\t\t\t\t\trow[nestedFk.referencedColumn],\n\t\t\t\t);\n\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Now delete from the target table\n\t\t\tconst deletePlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\tconst deleteQuery = `\n\t\t\t\tDELETE FROM \"${targetTable}\"\n\t\t\t\tWHERE \"${targetColumn}\" IN (${deletePlaceholders})\n\t\t\t`;\n\n\t\t\tconst deleteResult = await pool.query(deleteQuery, values);\n\t\t\ttotalRelatedDeleted += deleteResult.rowCount ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\t// Delete from all referencing tables first\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t);\n\t\t}\n\n\t\t// Finally delete the main records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst query = `\n\t\t\tDELETE FROM \"${tableName}\"\n\t\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\t\tconst result = await pool.query(query, pkValues);\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\tconst mainDeleted = result.rowCount ?? 0;\n\n\t\treturn { deletedCount: mainDeleted + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Gets related records from tables that reference this table\n */\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Gets the total row count for a table\n */\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(`SELECT COUNT(*) as count FROM \"${tableName}\"`);\n\treturn Number.parseInt(result.rows[0]?.count ?? \"0\", 10);\n}\n\n/**\n * Deletes a table from the database.\n * If there are FK constraints referencing this table, returns the related records.\n *\n * @param params.tableName - Name of the table to delete\n * @param params.db - Database name\n * @param params.cascade - If true, uses CASCADE to drop dependent objects\n * @returns DeleteTableResult with deletedCount, fkViolation flag, and relatedRecords\n */\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get row count before deletion\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\t// If not cascade, check for FK constraints first\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\t}\n\n\ttry {\n\t\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\t\tconst dropTableSQL = `DROP TABLE \"${tableName}\" ${dropMode}`;\n\n\t\tawait pool.query(dropTableSQL);\n\n\t\treturn {\n\t\t\tdeletedCount: rowCount,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error) {\n\t\tconst pgError = error as { code?: string; detail?: string };\n\n\t\t// Check if this is a dependency error (foreign key constraint)\n\t\tif (pgError.code === \"2BP01\") {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getDbPool(db);\n\tconst { rows } = await pool.query(`SELECT * FROM \"${tableName}\"`);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { normalizeMongoDocument } from \"./tables.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, { message: \"At least one record is required\" });\n\t}\n\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tconst docs = records.map((record) => {\n\t\tconst normalized = normalizeMongoDocument(record) as Record<string, unknown>;\n\t\tif (normalized._id === \"\" || normalized._id === null) delete normalized._id;\n\t\treturn normalized;\n\t});\n\n\ttry {\n\t\tconst result = await collection.insertMany(docs, { ordered: false });\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${result.insertedCount} record${result.insertedCount !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: result.insertedCount,\n\t\t\tfailureCount: records.length - result.insertedCount,\n\t\t};\n\t} catch (error) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Bulk insert failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t});\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMongoClient, getMongoDbName } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\nconst formatBytes = (bytes: number): string => {\n\tif (!Number.isFinite(bytes)) return \"n/a\";\n\tconst units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\tlet value = bytes;\n\tlet unitIndex = 0;\n\twhile (value >= 1024 && unitIndex < units.length - 1) {\n\t\tvalue /= 1024;\n\t\tunitIndex += 1;\n\t}\n\treturn `${value.toFixed(1)} ${units[unitIndex]}`;\n};\n\nexport async function getMongoDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst client = await getMongoClient();\n\tconst admin = client.db().admin();\n\tconst result = await admin.listDatabases();\n\tconst databases = result.databases ?? [];\n\n\tif (!databases[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from MongoDB\",\n\t\t});\n\t}\n\n\treturn databases.map((db) => ({\n\t\tname: db.name,\n\t\tsize: formatBytes(db.sizeOnDisk ?? 0),\n\t\towner: \"n/a\",\n\t\tencoding: \"n/a\",\n\t}));\n}\n\nexport async function getMongoCurrentDatabase(): Promise<DatabaseSchemaType> {\n\treturn { db: getMongoDbName() };\n}\n\nexport async function getMongoConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst client = await getMongoClient();\n\tconst admin = client.db().admin();\n\tconst urlDefaults = parseDatabaseUrl();\n\tlet serverStatus: {\n\t\tversion?: string;\n\t\tconnections?: { current?: number; available?: number };\n\t} = {};\n\ttry {\n\t\tserverStatus = await admin.serverStatus();\n\t} catch (error) {\n\t\tconsole.warn(\"Failed to read MongoDB serverStatus:\", error);\n\t}\n\n\treturn {\n\t\thost: urlDefaults.host,\n\t\tport: urlDefaults.port,\n\t\tuser: \"n/a\",\n\t\tdatabase: getMongoDbName(),\n\t\tversion: serverStatus.version ?? \"unknown\",\n\t\tactive_connections: serverStatus.connections?.current ?? 0,\n\t\tmax_connections:\n\t\t\t(serverStatus.connections?.current ?? 0) + (serverStatus.connections?.available ?? 0),\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { buildMongoSortForQuery, normalizeMongoDocument, toMongoId } from \"./tables.dao.js\";\n\ntype MongoQueryPayload = {\n\tcollection: string;\n\toperation:\n\t\t| \"find\"\n\t\t| \"aggregate\"\n\t\t| \"insertOne\"\n\t\t| \"insertMany\"\n\t\t| \"updateOne\"\n\t\t| \"updateMany\"\n\t\t| \"deleteOne\"\n\t\t| \"deleteMany\"\n\t\t| \"count\";\n\tfilter?: Record<string, unknown>;\n\tpipeline?: Record<string, unknown>[];\n\tdocument?: Record<string, unknown> | Record<string, unknown>[];\n\tupdate?: Record<string, unknown>;\n\toptions?: Record<string, unknown>;\n\tsort?: Record<string, 1 | -1>;\n\tlimit?: number;\n\tskip?: number;\n};\n\nconst normalizeIdFilter = (filter: Record<string, unknown>) => {\n\tif (filter._id && typeof filter._id === \"string\") {\n\t\treturn { ...filter, _id: toMongoId(filter._id) };\n\t}\n\tif (filter._id && typeof filter._id === \"object\") {\n\t\tconst obj = filter._id as Record<string, unknown>;\n\t\tif (Array.isArray(obj.$in)) {\n\t\t\treturn {\n\t\t\t\t...filter,\n\t\t\t\t_id: {\n\t\t\t\t\t...obj,\n\t\t\t\t\t$in: obj.$in.map((val) => (typeof val === \"string\" ? toMongoId(val) : val)),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (Array.isArray(obj.$nin)) {\n\t\t\treturn {\n\t\t\t\t...filter,\n\t\t\t\t_id: {\n\t\t\t\t\t...obj,\n\t\t\t\t\t$nin: obj.$nin.map((val) => (typeof val === \"string\" ? toMongoId(val) : val)),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\treturn filter;\n};\n\nexport const executeMongoQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tlet payload: MongoQueryPayload;\n\ttry {\n\t\tpayload = JSON.parse(query) as MongoQueryPayload;\n\t} catch (_error) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Mongo query must be valid JSON\",\n\t\t});\n\t}\n\n\tif (!payload.collection || !payload.operation) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Mongo query must include collection and operation\",\n\t\t});\n\t}\n\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(payload.collection);\n\n\tconst startTime = performance.now();\n\tlet rows: Record<string, unknown>[] = [];\n\tlet rowCount = 0;\n\tlet message: string | undefined;\n\n\tswitch (payload.operation) {\n\t\tcase \"find\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst cursor = collection.find(filter, payload.options ?? {});\n\t\t\tconst sort = payload.sort ?? buildMongoSortForQuery(\"\", undefined);\n\t\t\tcursor.sort(sort);\n\t\t\tif (payload.skip) cursor.skip(payload.skip);\n\t\t\tif (payload.limit) cursor.limit(payload.limit);\n\t\t\trows = await cursor.toArray();\n\t\t\trowCount = rows.length;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"aggregate\": {\n\t\t\tconst pipeline = payload.pipeline ?? [];\n\t\t\trows = await collection.aggregate(pipeline, payload.options ?? {}).toArray();\n\t\t\trowCount = rows.length;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"insertOne\": {\n\t\t\tconst doc = payload.document as Record<string, unknown> | undefined;\n\t\t\tif (!doc) throw new HTTPException(400, { message: \"document is required\" });\n\t\t\tconst result = await collection.insertOne(doc);\n\t\t\trowCount = result.insertedId ? 1 : 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"insertMany\": {\n\t\t\tconst docs = payload.document as Record<string, unknown>[] | undefined;\n\t\t\tif (!Array.isArray(docs))\n\t\t\t\tthrow new HTTPException(400, { message: \"document array is required\" });\n\t\t\tconst result = await collection.insertMany(docs);\n\t\t\trowCount = result.insertedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"updateOne\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tif (!payload.update) throw new HTTPException(400, { message: \"update is required\" });\n\t\t\tconst result = await collection.updateOne(filter, payload.update, payload.options ?? {});\n\t\t\trowCount = result.matchedCount ?? 0;\n\t\t\tmessage = `OK (${result.modifiedCount ?? 0} modified)`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"updateMany\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tif (!payload.update) throw new HTTPException(400, { message: \"update is required\" });\n\t\t\tconst result = await collection.updateMany(\n\t\t\t\tfilter,\n\t\t\t\tpayload.update,\n\t\t\t\tpayload.options ?? {},\n\t\t\t);\n\t\t\trowCount = result.matchedCount ?? 0;\n\t\t\tmessage = `OK (${result.modifiedCount ?? 0} modified)`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"deleteOne\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst result = await collection.deleteOne(filter, payload.options ?? {});\n\t\t\trowCount = result.deletedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"deleteMany\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst result = await collection.deleteMany(filter, payload.options ?? {});\n\t\t\trowCount = result.deletedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"count\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\trowCount = await collection.countDocuments(filter);\n\t\t\trows = [{ count: rowCount }];\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tthrow new HTTPException(400, { message: \"Unsupported Mongo operation\" });\n\t}\n\n\tconst duration = performance.now() - startTime;\n\n\tconst normalizedRows = rows.map(\n\t\t(row) => normalizeMongoDocument(row) as Record<string, unknown>,\n\t);\n\n\tconst columns = normalizedRows[0] ? Object.keys(normalizedRows[0]) : [];\n\treturn {\n\t\tcolumns,\n\t\trows: normalizedRows,\n\t\trowCount,\n\t\tduration,\n\t\tmessage,\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tAddRecordSchemaType,\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteResult,\n\tUpdateRecordsSchemaType,\n} from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { canCoerceObjectId, normalizeMongoDocument, toMongoId } from \"./tables.dao.js\";\n\nexport async function addMongoRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst payload = normalizeMongoDocument(data) as Record<string, unknown>;\n\tif (payload._id === \"\" || payload._id === null) {\n\t\tdelete payload._id;\n\t}\n\tconst result = await collection.insertOne(payload);\n\tif (!result.insertedId) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\treturn { insertedCount: 1 };\n}\n\nexport async function updateMongoRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tlet totalUpdated = 0;\n\tconst pkField = primaryKey || \"_id\";\n\tconst updatesByRow = new Map<unknown, Record<string, unknown>>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[pkField];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${pkField}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, {});\n\t\t}\n\t\tupdatesByRow.get(pkValue)![update.columnName] = update.value;\n\t}\n\n\tfor (const [pkValue, updateSet] of updatesByRow.entries()) {\n\t\tconst queryValue =\n\t\t\tpkField === \"_id\" && canCoerceObjectId(pkValue) ? toMongoId(pkValue) : pkValue;\n\n\t\tconst result = await collection.updateOne({ [pkField]: queryValue }, { $set: updateSet });\n\n\t\tif (result.matchedCount === 0) {\n\t\t\tthrow new HTTPException(404, {\n\t\t\t\tmessage: `Record with ${pkField} = ${String(pkValue)} not found in \"${tableName}\"`,\n\t\t\t});\n\t\t}\n\n\t\ttotalUpdated += result.modifiedCount;\n\t}\n\n\treturn { updatedCount: totalUpdated };\n}\n\nexport async function deleteMongoRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteResult> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tconst pkColumn = primaryKeys[0]?.columnName ?? \"_id\";\n\tconst pkValues = primaryKeys.map((pk) =>\n\t\tpkColumn === \"_id\" && canCoerceObjectId(pk.value) ? toMongoId(pk.value) : pk.value,\n\t);\n\n\tconst result = await collection.deleteMany({ [pkColumn]: { $in: pkValues } });\n\treturn { deletedCount: result.deletedCount ?? 0 };\n}\n\nexport async function forceDeleteMongoRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst result = await deleteMongoRecords({ tableName, primaryKeys, db });\n\treturn { deletedCount: result.deletedCount };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nconst SAMPLE_LIMIT = 200;\n\nconst inferBsonType = (value: unknown): string => {\n\tif (value === null || value === undefined) return \"null\";\n\tif (value instanceof Date) return \"date\";\n\tif (typeof value === \"boolean\") return \"bool\";\n\tif (typeof value === \"number\") return Number.isInteger(value) ? \"int\" : \"double\";\n\tif (typeof value === \"bigint\") return \"long\";\n\tif (Array.isArray(value)) return \"array\";\n\tif (typeof value === \"object\") {\n\t\tif (\"_bsontype\" in (value as object)) {\n\t\t\tconst bson = (value as { _bsontype: string })._bsontype;\n\t\t\tif (bson === \"ObjectId\") return \"objectId\";\n\t\t\tif (bson === \"Decimal128\") return \"decimal\";\n\t\t\tif (bson === \"Binary\") return \"binData\";\n\t\t\tif (bson === \"Timestamp\") return \"timestamp\";\n\t\t\treturn bson.toLowerCase();\n\t\t}\n\t\treturn \"object\";\n\t}\n\treturn \"string\";\n};\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tconst collection = mongoDb.collection(tableName);\n\tconst docs = await collection.find({}).limit(SAMPLE_LIMIT).toArray();\n\tconst totalDocs = await collection.estimatedDocumentCount();\n\n\t// Build field → bson types map\n\tconst fieldTypes = new Map<string, Set<string>>();\n\tconst fieldPresence = new Map<string, number>();\n\n\tfor (const doc of docs) {\n\t\tfor (const [key, value] of Object.entries(doc)) {\n\t\t\tconst bsonType = inferBsonType(value);\n\t\t\tif (!fieldTypes.has(key)) {\n\t\t\t\tfieldTypes.set(key, new Set());\n\t\t\t\tfieldPresence.set(key, 0);\n\t\t\t}\n\t\t\tfieldTypes.get(key)?.add(bsonType);\n\t\t\tfieldPresence.set(key, (fieldPresence.get(key) ?? 0) + 1);\n\t\t}\n\t}\n\n\tconst properties: Record<string, unknown> = {};\n\tconst required: string[] = [];\n\n\tfor (const [field, types] of fieldTypes.entries()) {\n\t\tconst presence = fieldPresence.get(field) ?? 0;\n\t\tconst isRequired = presence === docs.length && docs.length > 0;\n\t\tconst typeList = Array.from(types).filter((t) => t !== \"null\");\n\t\tconst isNullable = types.has(\"null\") || presence < docs.length;\n\n\t\tif (isRequired && !isNullable) required.push(field);\n\n\t\tproperties[field] =\n\t\t\ttypeList.length === 1\n\t\t\t\t? { bsonType: isNullable ? [typeList[0], \"null\"] : typeList[0] }\n\t\t\t\t: { bsonType: isNullable ? [...typeList, \"null\"] : typeList };\n\t}\n\n\tconst schema = {\n\t\tcollection: tableName,\n\t\testimatedDocumentCount: totalDocs,\n\t\tsampledDocuments: docs.length,\n\t\tjsonSchema: {\n\t\t\tbsonType: \"object\",\n\t\t\trequired: required.length > 0 ? required : undefined,\n\t\t\tproperties,\n\t\t},\n\t};\n\n\treturn JSON.stringify(schema, null, 2);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMssqlToDataType,\n\tstandardizeMssqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow {\n\tcolumnName: string;\n\tdataType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\nfunction parseCheckConstraintValues(checkClause: string): string[] | null {\n\t// Match all single-quoted string literals in the CHECK clause\n\t// e.g. ([status]='active' OR [status]='inactive') → ['active', 'inactive']\n\tconst matches = checkClause.match(/'([^']+)'/g);\n\tif (!matches || matches.length === 0) return null;\n\treturn matches.map((m) => m.slice(1, -1));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t CASE WHEN c.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t CASE \n\t\t WHEN pk.COLUMN_NAME IS NOT NULL THEN 1 \n\t\t ELSE 0 \n\t\t END AS isPrimaryKey,\n\t\t CASE \n\t\t WHEN fk.COLUMN_NAME IS NOT NULL THEN 1 \n\t\t ELSE 0 \n\t\t END AS isForeignKey,\n\t\t fk.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t fk.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM INFORMATION_SCHEMA.COLUMNS c\n\t\tLEFT JOIN (\n\t\t SELECT \n\t\t ku.TABLE_SCHEMA,\n\t\t ku.TABLE_NAME,\n\t\t ku.COLUMN_NAME\n\t\t FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t AND tc.TABLE_SCHEMA = ku.TABLE_SCHEMA\n\t\t AND tc.TABLE_NAME = ku.TABLE_NAME\n\t\t WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'\n\t\t) pk ON c.TABLE_SCHEMA = pk.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = pk.TABLE_NAME\n\t\t AND c.COLUMN_NAME = pk.COLUMN_NAME\n\t\tLEFT JOIN (\n\t\t SELECT \n\t\t ku.TABLE_SCHEMA,\n\t\t ku.TABLE_NAME,\n\t\t ku.COLUMN_NAME,\n\t\t ku2.TABLE_NAME AS REFERENCED_TABLE_NAME,\n\t\t ku2.COLUMN_NAME AS REFERENCED_COLUMN_NAME\n\t\t FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t ON rc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t AND rc.CONSTRAINT_SCHEMA = ku.TABLE_SCHEMA\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku2\n\t\t ON rc.UNIQUE_CONSTRAINT_NAME = ku2.CONSTRAINT_NAME\n\t\t AND rc.UNIQUE_CONSTRAINT_SCHEMA = ku2.TABLE_SCHEMA\n\t\t) fk ON c.TABLE_SCHEMA = fk.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = fk.TABLE_NAME\n\t\t AND c.COLUMN_NAME = fk.COLUMN_NAME\n\t\tWHERE c.TABLE_CATALOG = DB_NAME()\n\t\t AND c.TABLE_NAME = @tableName\n\t\t AND c.TABLE_SCHEMA = 'dbo'\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst result = await pool.request().input(\"tableName\", tableName).query(query);\n\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Fetch CHECK constraints to simulate enum values\n\tconst checkResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\tSELECT\n\t\t cc.COLUMN_NAME AS columnName,\n\t\t chk.CHECK_CLAUSE AS checkClause\n\t\tFROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS chk\n\t\tJOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc\n\t\t ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME\n\t\t AND cc.TABLE_SCHEMA = 'dbo'\n\t\tWHERE cc.TABLE_NAME = @tableName\n\t\t AND cc.TABLE_CATALOG = DB_NAME()\n\t`);\n\n\tconst checkEnumMap = new Map<string, string[]>();\n\tfor (const row of checkResult.recordset as { columnName: string; checkClause: string }[]) {\n\t\tconst values = parseCheckConstraintValues(row.checkClause);\n\t\tif (values) {\n\t\t\tcheckEnumMap.set(row.columnName, values);\n\t\t}\n\t}\n\n\treturn (result.recordset as ColumnRow[]).map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst enumValues = checkEnumMap.get(r.columnName) ?? null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: enumValues ? \"enum\" : mapMssqlToDataType(dataType),\n\t\t\tdataTypeLabel: enumValues ? \"enum\" : standardizeMssqlDataTypeLabel(dataType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = await getMssqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\t// Fetch identity columns and exclude them from the insert\n\tconst identityResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(\n\t\t\t`SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1`,\n\t\t);\n\tconst identityColumns = new Set(\n\t\t(identityResult.recordset as { name: string }[]).map((r) => r.name),\n\t);\n\n\tconst columns = Object.keys(data).filter((col) => !identityColumns.has(col));\n\tconst values = columns.map((col) => {\n\t\tconst value = data[col];\n\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst columnNames = columns.map((col) => `[${col}]`).join(\", \");\n\tconst paramNames = columns.map((_col, idx) => `@param${idx}`).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO [${tableName}] (${columnNames})\n\t\tVALUES (${paramNames})\n\t`;\n\n\tconst request = pool.request();\n\tcolumns.forEach((_col, idx) => {\n\t\trequest.input(`param${idx}`, values[idx]);\n\t});\n\n\tconst result = await request.query(query);\n\n\tif (result.rowsAffected[0] === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowsAffected[0] ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = await getMssqlPool(db);\n\tconst transaction = pool.transaction();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `[${col}]`).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait transaction.begin();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst request = transaction.request();\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\n\t\t\tconst paramNames = columns.map((_, idx) => `@p${i}_${idx}`).join(\", \");\n\t\t\tcolumns.forEach((_col, idx) => {\n\t\t\t\trequest.input(`p${i}_${idx}`, values[idx]);\n\t\t\t});\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO [${tableName}] (${columnNames})\n\t\t\t\tVALUES (${paramNames})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait request.query(insertSQL);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait transaction.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t}\n};\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n/**\n * Formats default values for SQL Server compatibility\n */\nfunction formatMssqlDefaultValue(defaultValue: string, columnType: string): string | null {\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Function calls\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\tif (trimmed.includes(\"newid()\")) {\n\t\t\t// NEWID() for uniqueidentifier columns\n\t\t\tif (!columnType.toUpperCase().includes(\"UNIQUEIDENTIFIER\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"NEWID()\";\n\t\t}\n\n\t\tif (trimmed.includes(\"getdate\") || trimmed.includes(\"current_timestamp\")) {\n\t\t\treturn \"GETDATE()\";\n\t\t}\n\n\t\treturn defaultValue.trim();\n\t}\n\n\t// Keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PostgreSQL-style column types to SQL Server types\n */\nfunction mapColumnTypeToMssql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// SQL Server doesn't support native array types — use NVARCHAR(MAX) for JSON\n\t\treturn \"NVARCHAR(MAX)\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT IDENTITY(1,1)\",\n\t\tserial4: \"INT IDENTITY(1,1)\",\n\t\tbigserial: \"BIGINT IDENTITY(1,1)\",\n\t\tserial8: \"BIGINT IDENTITY(1,1)\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\ttinyint: \"TINYINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"NUMERIC\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"REAL\",\n\t\tfloat4: \"REAL\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"FLOAT\",\n\t\tfloat8: \"FLOAT\",\n\t\tmoney: \"MONEY\",\n\t\t// Boolean\n\t\tboolean: \"BIT\",\n\t\tbool: \"BIT\",\n\t\t// Text\n\t\ttext: \"NVARCHAR(MAX)\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"UNIQUEIDENTIFIER\",\n\t\t// JSON\n\t\tjson: \"NVARCHAR(MAX)\",\n\t\tjsonb: \"NVARCHAR(MAX)\",\n\t\txml: \"XML\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME2\",\n\t\t\"timestamp without time zone\": \"DATETIME2\",\n\t\t\"timestamp with time zone\": \"DATETIMEOFFSET\",\n\t\ttimestamptz: \"DATETIMEOFFSET\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"VARBINARY(MAX)\",\n\t\t// Network / geometric — store as text in SQL Server\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = await getMssqlPool(db);\n\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tconst mappedType = mapColumnTypeToMssql(field.columnType, field.isArray ?? false);\n\t\tlet columnDef = `[${field.columnName}] ${mappedType}`;\n\n\t\t// NOT NULL\n\t\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Default value (skip for IDENTITY columns)\n\t\tif (field.defaultValue && !mappedType.includes(\"IDENTITY\")) {\n\t\t\tconst defaultValue = formatMssqlDefaultValue(field.defaultValue, mappedType);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t\t}\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `[${f.columnName}]`).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(`UNIQUE ([${field.columnName}])`);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `FK_${tableName}_${fk.columnName}`;\n\t\t\treturn `CONSTRAINT [${constraintName}] FOREIGN KEY ([${fk.columnName}]) REFERENCES [${fk.referencedTable}] ([${fk.referencedColumn}]) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE [${tableName}] (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t)\n\t`;\n\n\tawait pool.request().query(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases on the SQL Server instance.\n * Returns name, size (human-readable), owner (connected user), and encoding (collation).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = await getMssqlPool();\n\n\tconst result = await pool.request().query(`\n\t\tSELECT\n\t\t d.name AS name,\n\t\t CAST(\n\t\t ROUND(\n\t\t CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)),\n\t\t 2\n\t\t ) AS VARCHAR(20)\n\t\t ) + ' MB' AS size,\n\t\t SUSER_SNAME(d.owner_sid) AS owner,\n\t\t d.collation_name AS encoding\n\t\tFROM sys.databases d\n\t\tJOIN sys.master_files mf ON d.database_id = mf.database_id\n\t\tWHERE d.database_id > 4 -- Exclude system databases\n\t\tGROUP BY d.name, d.owner_sid, d.collation_name\n\t\tORDER BY d.name\n\t`);\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn result.recordset as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = await getMssqlPool();\n\tconst result = await pool.request().query(\"SELECT DB_NAME() AS db\");\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn result.recordset[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for SQL Server.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = await getMssqlPool();\n\n\tconst result = await pool.request().query(`\n\t\tSELECT\n\t\t @@VERSION AS version,\n\t\t DB_NAME() AS database_name,\n\t\t SUSER_NAME() AS [user],\n\t\t @@SERVERNAME AS host,\n\t\t (SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID) AS port,\n\t\t @@MAX_CONNECTIONS AS max_connections,\n\t\t (SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections\n\t`);\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = result.recordset[0] as Record<string, string | number>;\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: Number(info.active_connections ?? 0),\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a SQL Server table using ALTER TABLE DROP COLUMN\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = await getMssqlPool(db);\n\n\t// Check table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst columnCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.input(\"columnName\", columnName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.COLUMNS\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND COLUMN_NAME = @columnName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst columnExists = Number(columnCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst result = await pool\n\t\t.request()\n\t\t.query(`ALTER TABLE [${tableName}] DROP COLUMN [${columnName}]`);\n\n\treturn { deletedCount: result.rowsAffected[0] ?? 1 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n// SQL Server FK violation error number\nconst MSSQL_FK_VIOLATION = 547;\n\ninterface FkConstraintRow {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n}\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT\n\t\t\t\tfk.name AS constraint_name,\n\t\t\t\tOBJECT_NAME(fk.parent_object_id) AS referencing_table,\n\t\t\t\tCOL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS referencing_column,\n\t\t\t\tOBJECT_NAME(fk.referenced_object_id) AS referenced_table,\n\t\t\t\tCOL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n\t\t\tFROM sys.foreign_keys fk\n\t\t\tINNER JOIN sys.foreign_key_columns fkc\n\t\t\t\tON fk.object_id = fkc.constraint_object_id\n\t\t\tWHERE OBJECT_NAME(fk.referenced_object_id) = @tableName\n\t\t`);\n\n\treturn (result.recordset as FkConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = await getMssqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst request = pool.request();\n\t\tpkValues.forEach((value, idx) => {\n\t\t\trequest.input(`pk${idx}`, value);\n\t\t});\n\t\tconst paramList = pkValues.map((_, idx) => `@pk${idx}`).join(\", \");\n\n\t\tconst relatedResult = await request.query(`\n\t\t\tSELECT TOP 100 * FROM [${constraint.referencingTable}]\n\t\t\tWHERE [${constraint.referencingColumn}] IN (${paramList})\n\t\t`);\n\n\t\tif (relatedResult.recordset.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.recordset as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tconst request = transaction.request();\n\t\tpkValues.forEach((value, idx) => {\n\t\t\trequest.input(`pk${idx}`, value);\n\t\t});\n\t\tconst paramList = pkValues.map((_, idx) => `@pk${idx}`).join(\", \");\n\n\t\tconst result = await request.query(\n\t\t\t`DELETE FROM [${tableName}] WHERE [${pkColumn}] IN (${paramList})`,\n\t\t);\n\n\t\tawait transaction.commit();\n\t\treturn {\n\t\t\tdeletedCount: result.rowsAffected[0] ?? 0,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error: any) {\n\t\tawait transaction.rollback();\n\n\t\tif (error.number === MSSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst selectRequest = transaction.request();\n\t\t\t\tvalues.forEach((val, idx) => {\n\t\t\t\t\tselectRequest.input(`val${idx}`, val);\n\t\t\t\t});\n\t\t\t\tconst selectParamList = values.map((_, idx) => `@val${idx}`).join(\", \");\n\n\t\t\t\tconst selectResult = await selectRequest.query(`\n\t\t\t\t\tSELECT [${nestedFk.referencedColumn}] FROM [${targetTable}]\n\t\t\t\t\tWHERE [${targetColumn}] IN (${selectParamList})\n\t\t\t\t`);\n\n\t\t\t\tconst nestedValues = (selectResult.recordset as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deleteRequest = transaction.request();\n\t\t\tvalues.forEach((val, idx) => {\n\t\t\t\tdeleteRequest.input(`delVal${idx}`, val);\n\t\t\t});\n\t\t\tconst deleteParamList = values.map((_, idx) => `@delVal${idx}`).join(\", \");\n\n\t\t\tconst deleteResult = await deleteRequest.query(\n\t\t\t\t`DELETE FROM [${targetTable}] WHERE [${targetColumn}] IN (${deleteParamList})`,\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.rowsAffected[0] ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainRequest = transaction.request();\n\t\tpkValues.forEach((val, idx) => {\n\t\t\tmainRequest.input(`mainPk${idx}`, val);\n\t\t});\n\t\tconst mainParamList = pkValues.map((_, idx) => `@mainPk${idx}`).join(\", \");\n\n\t\tconst result = await mainRequest.query(\n\t\t\t`DELETE FROM [${tableName}] WHERE [${pkColumn}] IN (${mainParamList})`,\n\t\t);\n\n\t\tawait transaction.commit();\n\n\t\treturn { deletedCount: (result.rowsAffected[0] ?? 0) + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n// SQL Server error number for FK dependency\nconst MSSQL_FK_DEPENDENCY = 3726;\n\ninterface FkConstraintRow {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n}\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT\n\t\t\t\tfk.name AS constraint_name,\n\t\t\t\tOBJECT_NAME(fk.parent_object_id) AS referencing_table,\n\t\t\t\tCOL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS referencing_column,\n\t\t\t\tOBJECT_NAME(fk.referenced_object_id) AS referenced_table,\n\t\t\t\tCOL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n\t\t\tFROM sys.foreign_keys fk\n\t\t\tINNER JOIN sys.foreign_key_columns fkc\n\t\t\t\tON fk.object_id = fkc.constraint_object_id\n\t\t\tWHERE OBJECT_NAME(fk.referenced_object_id) = @tableName\n\t\t`);\n\n\treturn (result.recordset as FkConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = await getMssqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedResult = await pool\n\t\t\t.request()\n\t\t\t.query(`SELECT TOP 100 * FROM [${constraint.referencingTable}]`);\n\n\t\tif (relatedResult.recordset.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.recordset as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool.request().query(`SELECT COUNT(*) as count FROM [${tableName}]`);\n\treturn Number(result.recordset[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = await getMssqlPool(db);\n\n\t// Check if table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// Drop all FK constraints referencing this table first\n\t\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\t\tfor (const fk of fkConstraints) {\n\t\t\t\tawait pool\n\t\t\t\t\t.request()\n\t\t\t\t\t.query(\n\t\t\t\t\t\t`ALTER TABLE [${fk.referencingTable}] DROP CONSTRAINT [${fk.constraintName}]`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait pool.request().query(`DROP TABLE [${tableName}]`);\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error: any) {\n\t\tif (error.number === MSSQL_FK_DEPENDENCY) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool.request().query(`SELECT * FROM [${tableName}]`);\n\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(result.recordset[0]);\n\n\treturn { cols, rows: result.recordset as Record<string, CellValue>[] };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = await getMssqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.request().query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\t// Check if query returned data (SELECT-like)\n\tif (result.recordset) {\n\t\tconst rows = result.recordset as Record<string, unknown>[];\n\t\tconst columns = result.recordset.columns\n\t\t\t? Object.keys(result.recordset.columns)\n\t\t\t: Object.keys(rows[0] ?? {});\n\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows,\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: result.rowsAffected[0] ?? 0,\n\t\tduration,\n\t\tmessage: `OK — ${result.rowsAffected[0] ?? 0} row(s) affected`,\n\t};\n};\n","import type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name AS tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_catalog = DB_NAME()\n\t\t AND table_type = 'BASE TABLE'\n\t\t AND table_schema = 'dbo'\n\t\tORDER BY table_name\n\t`;\n\n\tconst result = await pool.request().query(tablesQuery);\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst tablesList: TableInfoSchemaType[] = await Promise.all(\n\t\t(result.recordset as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst countResult = await pool\n\t\t\t\t.request()\n\t\t\t\t.query(`SELECT COUNT(*) as count FROM [${table.tableName}]`);\n\t\t\tconst countRow = countResult.recordset[0] as { count: number };\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn tablesList;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = await getMssqlPool(db);\n\n\t// Check if table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get table schema using sp_help which provides comprehensive table information\n\t// Note: We could also use INFORMATION_SCHEMA or sys.columns for more structured output\n\tconst schemaResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT \n\t\t\t c.COLUMN_NAME,\n\t\t\t c.DATA_TYPE,\n\t\t\t c.CHARACTER_MAXIMUM_LENGTH,\n\t\t\t c.NUMERIC_PRECISION,\n\t\t\t c.NUMERIC_SCALE,\n\t\t\t c.IS_NULLABLE,\n\t\t\t c.COLUMN_DEFAULT,\n\t\t\t CASE \n\t\t\t WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY'\n\t\t\t WHEN fk.COLUMN_NAME IS NOT NULL THEN 'FOREIGN KEY'\n\t\t\t ELSE ''\n\t\t\t END AS KEY_TYPE,\n\t\t\t fk.REFERENCED_TABLE_NAME,\n\t\t\t fk.REFERENCED_COLUMN_NAME\n\t\t\tFROM INFORMATION_SCHEMA.COLUMNS c\n\t\t\tLEFT JOIN (\n\t\t\t SELECT ku.TABLE_SCHEMA, ku.TABLE_NAME, ku.COLUMN_NAME\n\t\t\t FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t\t ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t\t WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'\n\t\t\t) pk ON c.TABLE_SCHEMA = pk.TABLE_SCHEMA\n\t\t\t AND c.TABLE_NAME = pk.TABLE_NAME\n\t\t\t AND c.COLUMN_NAME = pk.COLUMN_NAME\n\t\t\tLEFT JOIN (\n\t\t\t SELECT \n\t\t\t ku.TABLE_SCHEMA,\n\t\t\t ku.TABLE_NAME,\n\t\t\t ku.COLUMN_NAME,\n\t\t\t ku2.TABLE_NAME AS REFERENCED_TABLE_NAME,\n\t\t\t ku2.COLUMN_NAME AS REFERENCED_COLUMN_NAME\n\t\t\t FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t\t ON rc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku2\n\t\t\t ON rc.UNIQUE_CONSTRAINT_NAME = ku2.CONSTRAINT_NAME\n\t\t\t) fk ON c.TABLE_SCHEMA = fk.TABLE_SCHEMA\n\t\t\t AND c.TABLE_NAME = fk.TABLE_NAME\n\t\t\t AND c.COLUMN_NAME = fk.COLUMN_NAME\n\t\t\tWHERE c.TABLE_CATALOG = DB_NAME()\n\t\t\t AND c.TABLE_NAME = @tableName\n\t\t\t AND c.TABLE_SCHEMA = 'dbo'\n\t\t\tORDER BY c.ORDINAL_POSITION\n\t\t`);\n\n\tif (!schemaResult.recordset || schemaResult.recordset.length === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Build a CREATE TABLE statement from the schema information\n\tconst columns = schemaResult.recordset.map((col: any) => {\n\t\tlet columnDef = ` [${col.COLUMN_NAME}] ${col.DATA_TYPE}`;\n\n\t\t// Add length/precision\n\t\tif (col.CHARACTER_MAXIMUM_LENGTH) {\n\t\t\tcolumnDef +=\n\t\t\t\tcol.CHARACTER_MAXIMUM_LENGTH === -1 ? \"(MAX)\" : `(${col.CHARACTER_MAXIMUM_LENGTH})`;\n\t\t} else if (col.NUMERIC_PRECISION) {\n\t\t\tif (col.NUMERIC_SCALE) {\n\t\t\t\tcolumnDef += `(${col.NUMERIC_PRECISION},${col.NUMERIC_SCALE})`;\n\t\t\t} else {\n\t\t\t\tcolumnDef += `(${col.NUMERIC_PRECISION})`;\n\t\t\t}\n\t\t}\n\n\t\t// Add NULL/NOT NULL\n\t\tcolumnDef += col.IS_NULLABLE === \"YES\" ? \" NULL\" : \" NOT NULL\";\n\n\t\t// Add default\n\t\tif (col.COLUMN_DEFAULT) {\n\t\t\tcolumnDef += ` DEFAULT ${col.COLUMN_DEFAULT}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\tconst createTableSql = `CREATE TABLE [${tableName}] (\\n${columns.join(\",\\n\")}\\n)`;\n\n\treturn createTableSql;\n}\n","import type {\n\tDatabaseSchemaType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: any[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\n/**\n * Simplified implementation of getTableData for SQL Server\n * This version supports basic pagination with OFFSET/FETCH and simple sorting\n *\n * Note: A full implementation would include:\n * - Cursor-based pagination\n * - Complex filtering\n * - Multiple sort columns\n * - Foreign key relationships\n */\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = await getMssqlPool(db);\n\n\t// Basic implementation: Use OFFSET/FETCH for pagination\n\t// Parse cursor as page number (simplified)\n\tconst page = cursor ? Number.parseInt(cursor, 10) : 0;\n\tconst offset = page * limit;\n\n\t// Build sort clause\n\tlet sortClause = \"\";\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tconst sortParts = sort.map((s) => `[${s.columnName}] ${s.direction.toUpperCase()}`);\n\t\tsortClause = `ORDER BY ${sortParts.join(\", \")}`;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortClause = `ORDER BY [${sort}] ${order.toUpperCase()}`;\n\t} else {\n\t\t// Default sort - use first column or (SELECT NULL)\n\t\tsortClause = \"ORDER BY (SELECT NULL)\";\n\t}\n\n\t// Get total count\n\tconst countResult = await pool\n\t\t.request()\n\t\t.query(`SELECT COUNT(*) as total FROM [${tableName}]`);\n\tconst totalRows = Number(countResult.recordset[0]?.total ?? 0);\n\n\t// Get paginated data\n\tconst dataResult = await pool.request().query(`\n\t\tSELECT *\n\t\tFROM [${tableName}]\n\t\t${sortClause}\n\t\tOFFSET ${offset} ROWS\n\t\tFETCH NEXT ${limit + 1} ROWS ONLY\n\t`);\n\n\tlet rows = dataResult.recordset as Record<string, unknown>[];\n\tconst hasMore = rows.length > limit;\n\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tconst nextCursor = hasMore ? String(page + 1) : null;\n\tconst prevCursor = page > 0 ? String(page - 1) : null;\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: hasMore,\n\t\t\thasPreviousPage: page > 0,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = await getMssqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, idx) => `[${u.columnName}] = @value${idx}`);\n\t\t\tconst request = transaction.request();\n\n\t\t\trowUpdates.forEach((u, idx) => {\n\t\t\t\tlet value = u.value;\n\t\t\t\tif (value !== null && typeof value === \"object\") {\n\t\t\t\t\tvalue = JSON.stringify(value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof value === \"string\") {\n\t\t\t\t\tvalue = value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\trequest.input(`value${idx}`, value);\n\t\t\t});\n\n\t\t\trequest.input(\"pkValue\", pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE [${tableName}]\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE [${primaryKey}] = @pkValue\n\t\t\t`;\n\n\t\t\tconst result = await request.query(query);\n\n\t\t\tif (result.rowsAffected[0] === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowsAffected[0] ?? 0;\n\t\t}\n\n\t\tawait transaction.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMysqlToDataType,\n\tstandardizeMysqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow extends RowDataPacket {\n\tcolumnName: string;\n\tdataType: string;\n\tcolumnType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\n/**\n * Parse MySQL enum/set values from COLUMN_TYPE, e.g. \"enum('a','b','c')\" → [\"a\",\"b\",\"c\"]\n */\nfunction parseMysqlEnumValues(columnType: string): string[] | null {\n\tconst match = columnType.match(/^(?:enum|set)\\((.+)\\)$/i);\n\tif (!match?.[1]) return null;\n\treturn match[1].split(\",\").map((v) => v.trim().replace(/^'|'$/g, \"\"));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t c.COLUMN_TYPE AS columnType,\n\t\t (c.IS_NULLABLE = 'YES') AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t (c.COLUMN_KEY = 'PRI') AS isPrimaryKey,\n\t\t (kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,\n\t\t kcu.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t kcu.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM information_schema.COLUMNS c\n\t\tLEFT JOIN information_schema.KEY_COLUMN_USAGE kcu\n\t\t ON c.TABLE_SCHEMA = kcu.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = kcu.TABLE_NAME\n\t\t AND c.COLUMN_NAME = kcu.COLUMN_NAME\n\t\t AND kcu.REFERENCED_TABLE_NAME IS NOT NULL\n\t\tWHERE c.TABLE_SCHEMA = DATABASE()\n\t\t AND c.TABLE_NAME = ?\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst [rows] = await pool.execute<ColumnRow[]>(query, [tableName]);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst columnType = r.columnType as string;\n\t\tconst isEnum = dataType === \"enum\" || dataType === \"set\";\n\t\tconst enumValues = isEnum ? parseMysqlEnumValues(columnType) : null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapMysqlToDataType(dataType, columnType),\n\t\t\tdataTypeLabel: standardizeMysqlDataTypeLabel(dataType, columnType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data).map((value, index) => {\n\t\tconst columnName = columns[index];\n\t\tif (booleanColumns.has(columnName) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\tVALUES (${placeholders})\n\t`;\n\n\tconst [result] = await pool.execute<ResultSetHeader>(query, values);\n\n\tif (result.affectedRows === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getMysqlPool(db);\n\tconst connection = await pool.getConnection();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait connection.beginTransaction();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\t\tawait connection.execute<ResultSetHeader>(insertSQL, values as any);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait connection.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait connection.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n};\n","type MysqlColumnDefinitionInput = {\n\tcolumnName: string;\n\tcolumnType: string;\n\tdefaultValue?: string | null;\n\tisPrimaryKey?: boolean;\n\tisNullable?: boolean;\n\tisUnique?: boolean;\n\tisIdentity?: boolean;\n\tisArray?: boolean;\n};\n\ntype BuildMysqlColumnDefinitionOptions = {\n\tincludePrimaryKey?: boolean;\n\tincludeUnique?: boolean;\n\tpreserveAutoIncrement?: boolean;\n};\n\n/**\n * Formats default values for MySQL compatibility.\n * MySQL requires function calls in DEFAULT clauses to be wrapped in parentheses.\n */\nexport function formatMysqlDefaultValue(\n\tdefaultValue: string | null | undefined,\n\tcolumnType: string,\n): string | null {\n\tif (!defaultValue?.trim()) {\n\t\treturn null;\n\t}\n\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Check if it's a function call (contains parentheses)\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\t// MySQL 8.0+ requires function calls to be wrapped in parentheses for DEFAULT\n\t\t// But UUID() returns a string, not compatible with INT columns\n\t\tif (trimmed.includes(\"uuid()\")) {\n\t\t\t// UUID() only makes sense for CHAR(36) or VARCHAR columns\n\t\t\tif (\n\t\t\t\t!columnType.toUpperCase().includes(\"CHAR\") &&\n\t\t\t\t!columnType.toUpperCase().includes(\"TEXT\")\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"(UUID())\";\n\t\t}\n\n\t\t// Other function calls like CURRENT_TIMESTAMP, NOW(), etc.\n\t\tif (trimmed.includes(\"current_timestamp\") || trimmed.includes(\"now()\")) {\n\t\t\treturn \"(CURRENT_TIMESTAMP)\";\n\t\t}\n\n\t\tif (trimmed.includes(\"current_date\")) {\n\t\t\treturn \"(CURRENT_DATE)\";\n\t\t}\n\n\t\t// Wrap other function calls in parentheses\n\t\treturn `(${defaultValue.trim()})`;\n\t}\n\n\t// For non-function defaults (literals), return as-is\n\t// Handle special keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\t// Return the value as-is (could be a number, quoted string, etc.)\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PG-style column types from the UI schema to MySQL-compatible types.\n * The UI uses PostgreSQL-style type names, so we translate them for MySQL.\n */\nexport function mapColumnTypeToMysql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// MySQL does not support native array types - use JSON as fallback\n\t\treturn \"JSON\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT AUTO_INCREMENT\",\n\t\tserial4: \"INT AUTO_INCREMENT\",\n\t\tbigserial: \"BIGINT AUTO_INCREMENT\",\n\t\tserial8: \"BIGINT AUTO_INCREMENT\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"DECIMAL\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"FLOAT\",\n\t\tfloat4: \"FLOAT\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"DOUBLE\",\n\t\tfloat8: \"DOUBLE\",\n\t\tmoney: \"DECIMAL(19, 4)\",\n\t\t// Boolean\n\t\tboolean: \"TINYINT(1)\",\n\t\tbool: \"TINYINT(1)\",\n\t\t// Text\n\t\ttext: \"LONGTEXT\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"CHAR(36)\",\n\t\t// JSON\n\t\tjson: \"JSON\",\n\t\tjsonb: \"JSON\",\n\t\txml: \"LONGTEXT\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME\",\n\t\t\"timestamp without time zone\": \"DATETIME\",\n\t\t\"timestamp with time zone\": \"DATETIME\",\n\t\ttimestamptz: \"DATETIME\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"LONGBLOB\",\n\t\t// Network / geometric - store as text in MySQL\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t\tpoint: \"POINT\",\n\t\tline: \"LINESTRING\",\n\t\tpolygon: \"POLYGON\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport function buildMysqlColumnDefinition(\n\tfield: MysqlColumnDefinitionInput,\n\toptions: BuildMysqlColumnDefinitionOptions = {},\n): string {\n\tconst mappedType = mapColumnTypeToMysql(field.columnType, field.isArray ?? false);\n\tlet columnDef = `\\`${field.columnName}\\` ${mappedType}`;\n\n\t// NOT NULL\n\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\tcolumnDef += \" NOT NULL\";\n\t}\n\n\t// Default value (skip for AUTO_INCREMENT columns)\n\tif (field.defaultValue && !mappedType.includes(\"AUTO_INCREMENT\")) {\n\t\tconst defaultValue = formatMysqlDefaultValue(field.defaultValue, mappedType);\n\t\tif (defaultValue !== null) {\n\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t}\n\t}\n\n\t// isIdentity -> AUTO_INCREMENT (already embedded in type map via SERIAL mapping)\n\tif (\n\t\t(field.isIdentity || options.preserveAutoIncrement) &&\n\t\t!mappedType.includes(\"AUTO_INCREMENT\")\n\t) {\n\t\tcolumnDef += \" AUTO_INCREMENT\";\n\t}\n\n\tif (options.includeUnique && field.isUnique && !field.isPrimaryKey) {\n\t\tcolumnDef += \" UNIQUE\";\n\t}\n\n\tif (options.includePrimaryKey && field.isPrimaryKey) {\n\t\tcolumnDef += \" PRIMARY KEY\";\n\t}\n\n\treturn columnDef;\n}\n","import type { ResultSetHeader } from \"mysql2\";\nimport type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getMysqlPool(db);\n\n\tconst columnDefinitions = fields.map((field) => buildMysqlColumnDefinition(field));\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `\\`${f.columnName}\\``).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(\n\t\t\t\t`UNIQUE KEY \\`uq_${tableName}_${field.columnName}\\` (\\`${field.columnName}\\`)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \\`${constraintName}\\` FOREIGN KEY (\\`${fk.columnName}\\`) REFERENCES \\`${fk.referencedTable}\\` (\\`${fk.referencedColumn}\\`) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE \\`${tableName}\\` (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci\n\t`;\n\n\tawait pool.execute<ResultSetHeader>(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases (schemas) on the MySQL server.\n * Returns name, size (human-readable), owner (connected user), and encoding (charset).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getMysqlPool();\n\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t s.SCHEMA_NAME AS name,\n\t\t CONCAT(\n\t\t ROUND(\n\t\t COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024,\n\t\t 2\n\t\t ),\n\t\t ' MB'\n\t\t ) AS size,\n\t\t CURRENT_USER() AS owner,\n\t\t s.DEFAULT_CHARACTER_SET_NAME AS encoding\n\t\tFROM information_schema.SCHEMATA s\n\t\tLEFT JOIN information_schema.TABLES t\n\t\t ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n\t\tGROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME\n\t\tORDER BY s.SCHEMA_NAME\n\t`);\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn rows as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getMysqlPool();\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\"SELECT DATABASE() AS db\");\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn (rows as Array<{ db: string }>)[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for MySQL.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getMysqlPool();\n\n\tconst [infoRows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t VERSION() AS version,\n\t\t DATABASE() AS database_name,\n\t\t CURRENT_USER() AS user,\n\t\t @@hostname AS host,\n\t\t @@port AS port,\n\t\t @@max_connections AS max_connections\n\t`);\n\n\tconst [connRows] = await pool.execute<RowDataPacket[]>(\n\t\t\"SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST\",\n\t);\n\n\tif (!infoRows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = (infoRows as Array<Record<string, string | number>>)[0];\n\tconst activeConnections = Number((connRows as Array<{ cnt: number }>)[0]?.cnt ?? 0);\n\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: activeConnections,\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a MySQL table using ALTER TABLE DROP COLUMN.\n * Note: MySQL does not support CASCADE/RESTRICT on DROP COLUMN — the cascade param is accepted\n * for API compatibility but does not change behavior.\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [result] = await pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` DROP COLUMN \\`${columnName}\\``,\n\t);\n\n\treturn { deletedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL FK violation error number\nconst MYSQL_FK_VIOLATION = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\`\n\t\t\t WHERE \\`${constraint.referencingColumn}\\` IN (${placeholders})\n\t\t\t LIMIT 100`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${placeholders})`,\n\t\t\tpkValues,\n\t\t);\n\t\tawait connection.commit();\n\t\treturn { deletedCount: result.affectedRows, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (mysqlError.errno === MYSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\t// Disable FK checks temporarily for cascade delete\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst nestedPlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\t\tconst [selectRows] = await connection.execute<RowDataPacket[]>(\n\t\t\t\t\t`SELECT \\`${nestedFk.referencedColumn}\\` FROM \\`${targetTable}\\`\n\t\t\t\t\t WHERE \\`${targetColumn}\\` IN (${nestedPlaceholders})`,\n\t\t\t\t\tvalues as any[],\n\t\t\t\t);\n\t\t\t\tconst nestedValues = (selectRows as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deletePlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\tconst [deleteResult] = await connection.execute<ResultSetHeader>(\n\t\t\t\t`DELETE FROM \\`${targetTable}\\` WHERE \\`${targetColumn}\\` IN (${deletePlaceholders})`,\n\t\t\t\tvalues as any[],\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.affectedRows;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainPlaceholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${mainPlaceholders})`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\tawait connection.commit();\n\n\t\treturn { deletedCount: result.affectedRows + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL error number for FK dependency preventing DROP TABLE\nconst MYSQL_FK_DEPENDENCY = 1217;\nconst MYSQL_FK_ROW_REFERENCED = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\` LIMIT 100`,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as count FROM \\`${tableName}\\``,\n\t);\n\treturn Number((rows as Array<{ count: number }>)[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// MySQL doesn't support CASCADE on DROP TABLE natively the same way PG does.\n\t\t\t// We disable FK checks, drop the table, then re-enable.\n\t\t\tconst connection = await pool.getConnection();\n\t\t\ttry {\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\t\t\t\tawait connection.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\t\t} finally {\n\t\t\t\tconnection.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait pool.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t}\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\t// Re-enable FK checks in case we disabled them\n\t\tawait pool.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (\n\t\t\tmysqlError.errno === MYSQL_FK_DEPENDENCY ||\n\t\t\tmysqlError.errno === MYSQL_FK_ROW_REFERENCED\n\t\t) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SELECT * FROM \\`${tableName}\\``);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows: rows as Record<string, CellValue>[] };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { FieldPacket, ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getMysqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\t// mysql2 returns [rows, fields] for SELECT and [ResultSetHeader, fields] for DML\n\tconst [result, fields] = (await pool.execute(cleanedQuery)) as [\n\t\tRowDataPacket[] | ResultSetHeader,\n\t\tFieldPacket[],\n\t];\n\tconst duration = performance.now() - startTime;\n\n\t// SELECT-like results have an array of rows\n\tif (Array.isArray(result)) {\n\t\tconst rows = result as RowDataPacket[];\n\t\tconst columns = fields ? fields.map((f) => f.name) : Object.keys(rows[0] ?? {});\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows: rows as Record<string, unknown>[],\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\tconst dmlResult = result as ResultSetHeader;\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: dmlResult.affectedRows,\n\t\tduration,\n\t\tmessage: `OK — ${dmlResult.affectedRows} row(s) affected`,\n\t};\n};\n","import type { RowDataPacket } from \"mysql2\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name as tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = DATABASE()\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name\n\t`;\n\n\tconst [tables] = await pool.execute<RowDataPacket[]>(tablesQuery);\n\tif (!tables || tables.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\t(tables as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t\t`SELECT COUNT(*) as count FROM \\`${table.tableName}\\``,\n\t\t\t);\n\t\t\tconst countRow = (countRows as Array<{ count: number }>)[0];\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// SHOW CREATE TABLE returns the full DDL including column types, indexes, FK constraints\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SHOW CREATE TABLE \\`${tableName}\\``);\n\tconst row = (rows as Array<Record<string, string>>)[0];\n\n\t// The result row has \"Create Table\" key\n\tconst createTableSql = row?.[\"Create Table\"] ?? row?.create_table ?? \"\";\n\tif (!createTableSql) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn createTableSql;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\n/**\n * MySQL-specific WHERE clause builder.\n * Uses ? placeholders and backtick identifiers.\n * ILIKE/NOT ILIKE map to LIKE/NOT LIKE (MySQL is case-insensitive by default on most collations).\n */\nexport function buildWhereClauseMysql(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst columnName = `\\`${filter.columnName}\\``;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\tcase \"ilike\":\n\t\t\t\t// MySQL LIKE is case-insensitive by default on most collations\n\t\t\t\tconditions.push(`${columnName} LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName} NOT LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\n/**\n * MySQL-specific ORDER BY clause builder.\n * Uses backtick identifiers.\n */\nexport function buildSortClauseMysql(\n\tsorts: SortType[] | string,\n\torder: SortDirection,\n): string {\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\\`${sort.columnName}\\` ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \\`${sorts}\\` ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * MySQL-specific cursor WHERE clause builder.\n * Uses ? placeholders (no index tracking needed since all placeholders are ?).\n */\nexport function buildCursorWhereClauseMysql(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\\`${col}\\``).join(\", \");\n\t\tconst placeholders = sortColumns.map(() => \"?\").join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClauseMysql,\n\tbuildSortClauseMysql,\n\tbuildWhereClauseMysql,\n} from \"@/utils/build-clauses-mysql.js\";\n\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getMysqlPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COLUMN_NAME as column_name\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE()\n\t\t AND TABLE_NAME = ?\n\t\t AND COLUMN_KEY = 'PRI'\n\t\t ORDER BY ORDINAL_POSITION`,\n\t\t[tableName],\n\t);\n\treturn (rows as Array<{ column_name: string }>).map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getMysqlPool(db);\n\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// MySQL has no ctid equivalent — if no cursor columns, use empty (rely on natural order)\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClauseMysql(filters);\n\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClauseMysql(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\tconst sortClause = buildSortClauseMysql(Array.isArray(sort) ? sort : sort, order);\n\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else if (cursorColumns.length > 0) {\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as total FROM \\`${tableName}\\` ${filterWhereClause}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\tfilterValues as any,\n\t);\n\tconst totalRows = Number((countRows as Array<{ total: number }>)[0]?.total ?? 0);\n\n\tconst fetchLimit = Math.floor(limit) + 1;\n\tconst [dataRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT * FROM \\`${tableName}\\` ${combinedWhereClause} ${effectiveSortClause} LIMIT ${fetchLimit}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t[...filterValues, ...cursorValues] as any,\n\t);\n\n\tlet rows = dataRows as Record<string, unknown>[];\n\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\n\tif (rows.length > 0 && cursorColumns.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\n\t\tif (direction === \"asc\") {\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u) => `\\`${u.columnName}\\` = ?`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof u.value === \"string\") {\n\t\t\t\t\treturn u.value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \\`${tableName}\\`\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \\`${primaryKey}\\` = ?\n\t\t\t`;\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\tconst [result] = await connection.execute<ResultSetHeader>(query, values as any);\n\n\t\t\tif (result.affectedRows === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.affectedRows;\n\t\t}\n\n\t\tawait connection.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getDbPool(db);\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\t// Clean the query - remove trailing semicolons and whitespace\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\tconst columns = result.fields.map((field) => field.name);\n\n\treturn {\n\t\tcolumns,\n\t\trows: result.rows,\n\t\trowCount: result.rows.length,\n\t\tduration,\n\t\tmessage: result.rows.length === 0 ? \"OK\" : undefined,\n\t};\n};\n","import type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nconst quoteIdentifier = (identifier: string): string => identifier.replaceAll('\"', '\"\"');\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\n\t// First, get all table names\n\tconst tablesQuery = `\n\t\tSELECT table_schema as \"schemaName\", table_name as \"tableName\"\n\t\tFROM information_schema.tables\n\t\tWHERE table_type = 'BASE TABLE'\n\t\t AND table_schema NOT IN ('pg_catalog', 'information_schema')\n\t\t AND table_schema NOT LIKE 'pg_toast%'\n\t\tORDER BY table_schema, table_name;\n\t`;\n\n\tconst { rows: tables } = await pool.query(tablesQuery);\n\tif (!tables[0]) {\n\t\treturn [];\n\t}\n\n\t// Get accurate row count for each table\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\ttables.map(async (table: { schemaName: string; tableName: string }) => {\n\t\t\tconst safeSchemaName = quoteIdentifier(table.schemaName);\n\t\t\tconst safeTableName = quoteIdentifier(table.tableName);\n\t\t\tconst countQuery = `SELECT COUNT(*)::integer as count FROM \"${safeSchemaName}\".\"${safeTableName}\"`;\n\t\t\tconst { rows } = await pool.query(countQuery);\n\t\t\treturn {\n\t\t\t\tschemaName: table.schemaName,\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: rows[0]?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\ninterface ColumnInfo {\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string;\n\tis_nullable: string;\n\tcolumn_default: string | null;\n\tcharacter_maximum_length: number | null;\n\tnumeric_precision: number | null;\n\tnumeric_scale: number | null;\n}\n\ninterface ConstraintInfo {\n\tconstraint_name: string;\n\tconstraint_type: string;\n\tcolumn_name: string;\n\tforeign_table_name: string | null;\n\tforeign_column_name: string | null;\n}\n\ninterface IndexInfo {\n\tindexname: string;\n\tindexdef: string;\n}\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\t) as exists\n\t`;\n\tconst { rows: tableExistsRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableExistsRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get column information\n\tconst columnsQuery = `\n\t\tSELECT \n\t\t\tcolumn_name,\n\t\t\tdata_type,\n\t\t\tudt_name,\n\t\t\tis_nullable,\n\t\t\tcolumn_default,\n\t\t\tcharacter_maximum_length,\n\t\t\tnumeric_precision,\n\t\t\tnumeric_scale\n\t\tFROM information_schema.columns\n\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\tORDER BY ordinal_position\n\t`;\n\tconst { rows: columns } = await pool.query<ColumnInfo>(columnsQuery, [tableName]);\n\n\t// Get constraints (primary keys, foreign keys, unique)\n\tconst constraintsQuery = `\n\t\tSELECT \n\t\t\ttc.constraint_name,\n\t\t\ttc.constraint_type,\n\t\t\tkcu.column_name,\n\t\t\tccu.table_name AS foreign_table_name,\n\t\t\tccu.column_name AS foreign_column_name\n\t\tFROM information_schema.table_constraints tc\n\t\tJOIN information_schema.key_column_usage kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tLEFT JOIN information_schema.constraint_column_usage ccu\n\t\t\tON tc.constraint_name = ccu.constraint_name\n\t\t\tAND tc.table_schema = ccu.table_schema\n\t\t\tAND tc.constraint_type = 'FOREIGN KEY'\n\t\tWHERE tc.table_schema = 'public' AND tc.table_name = $1\n\t\tORDER BY tc.constraint_type, tc.constraint_name\n\t`;\n\tconst { rows: constraints } = await pool.query<ConstraintInfo>(constraintsQuery, [\n\t\ttableName,\n\t]);\n\n\t// Get indexes (excluding primary key indexes which are auto-created)\n\tconst indexesQuery = `\n\t\tSELECT indexname, indexdef\n\t\tFROM pg_indexes\n\t\tWHERE schemaname = 'public' AND tablename = $1\n\t\tAND indexname NOT IN (\n\t\t\tSELECT constraint_name \n\t\t\tFROM information_schema.table_constraints \n\t\t\tWHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY'\n\t\t)\n\t`;\n\tconst { rows: indexes } = await pool.query<IndexInfo>(indexesQuery, [tableName]);\n\n\t// Build the CREATE TABLE statement\n\tconst schemaLines: string[] = [];\n\tschemaLines.push(`create table public.${tableName} (`);\n\n\t// Add columns\n\tconst columnDefs: string[] = [];\n\tfor (const col of columns) {\n\t\tlet colDef = ` ${col.column_name} ${formatDataType(col)}`;\n\n\t\tif (col.is_nullable === \"NO\") {\n\t\t\tcolDef += \" not null\";\n\t\t}\n\n\t\tif (col.column_default !== null) {\n\t\t\tcolDef += ` default ${col.column_default}`;\n\t\t}\n\n\t\tcolumnDefs.push(colDef);\n\t}\n\n\t// Group constraints by name to handle composite keys\n\tconst constraintMap = new Map<string, ConstraintInfo[]>();\n\tfor (const constraint of constraints) {\n\t\tconst existing = constraintMap.get(constraint.constraint_name) || [];\n\t\texisting.push(constraint);\n\t\tconstraintMap.set(constraint.constraint_name, existing);\n\t}\n\n\t// Add constraints\n\tconst constraintDefs: string[] = [];\n\tfor (const [constraintName, constraintColumns] of constraintMap) {\n\t\tconst firstConstraint = constraintColumns[0];\n\t\tconst columnNames = constraintColumns.map((c) => c.column_name).join(\", \");\n\n\t\tif (firstConstraint.constraint_type === \"PRIMARY KEY\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} primary key (${columnNames})`);\n\t\t} else if (firstConstraint.constraint_type === \"FOREIGN KEY\") {\n\t\t\tconst foreignTable = firstConstraint.foreign_table_name;\n\t\t\tconst foreignColumn = firstConstraint.foreign_column_name;\n\t\t\tconstraintDefs.push(\n\t\t\t\t` constraint ${constraintName} foreign key (${columnNames}) references ${foreignTable} (${foreignColumn})`,\n\t\t\t);\n\t\t} else if (firstConstraint.constraint_type === \"UNIQUE\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} unique (${columnNames})`);\n\t\t}\n\t}\n\n\t// Combine column and constraint definitions\n\tconst allDefs = [...columnDefs, ...constraintDefs];\n\tschemaLines.push(allDefs.join(\",\\n\"));\n\n\tschemaLines.push(\") tablespace pg_default;\");\n\n\t// Add indexes as separate statements\n\tfor (const index of indexes) {\n\t\t// Skip unique indexes that are already covered by unique constraints\n\t\tconst isUniqueConstraint = Array.from(constraintMap.values()).some(\n\t\t\t(c) => c[0].constraint_type === \"UNIQUE\" && c[0].constraint_name === index.indexname,\n\t\t);\n\t\tif (!isUniqueConstraint) {\n\t\t\tschemaLines.push(\"\");\n\t\t\tschemaLines.push(`${index.indexdef};`);\n\t\t}\n\t}\n\n\treturn schemaLines.join(\"\\n\");\n}\n\nfunction formatDataType(col: ColumnInfo): string {\n\tconst { data_type, udt_name, character_maximum_length, numeric_precision, numeric_scale } =\n\t\tcol;\n\n\t// Handle user-defined types (enums)\n\tif (data_type === \"USER-DEFINED\") {\n\t\treturn udt_name;\n\t}\n\n\t// Handle array types\n\tif (data_type === \"ARRAY\") {\n\t\treturn `${udt_name.replace(/^_/, \"\")}[]`;\n\t}\n\n\t// Handle character types with length\n\tif (\n\t\t(data_type === \"character varying\" || data_type === \"varchar\") &&\n\t\tcharacter_maximum_length\n\t) {\n\t\treturn `varchar(${character_maximum_length})`;\n\t}\n\n\tif (data_type === \"character\" && character_maximum_length) {\n\t\treturn `char(${character_maximum_length})`;\n\t}\n\n\t// Handle numeric with precision and scale\n\tif (data_type === \"numeric\" && numeric_precision !== null) {\n\t\tif (numeric_scale !== null && numeric_scale > 0) {\n\t\t\treturn `numeric(${numeric_precision}, ${numeric_scale})`;\n\t\t}\n\t\treturn `numeric(${numeric_precision})`;\n\t}\n\n\t// Handle timestamp types\n\tif (data_type === \"timestamp with time zone\") {\n\t\treturn \"timestamp with time zone\";\n\t}\n\n\tif (data_type === \"timestamp without time zone\") {\n\t\treturn \"timestamp\";\n\t}\n\n\t// Map common data types\n\tconst typeMap: Record<string, string> = {\n\t\t\"character varying\": \"varchar\",\n\t\tcharacter: \"char\",\n\t\t\"double precision\": \"float8\",\n\t\tinteger: \"integer\",\n\t\tbigint: \"bigint\",\n\t\tsmallint: \"smallint\",\n\t\tboolean: \"boolean\",\n\t\ttext: \"text\",\n\t\tuuid: \"uuid\",\n\t\tjson: \"json\",\n\t\tjsonb: \"jsonb\",\n\t\tdate: \"date\",\n\t\ttime: \"time\",\n\t\tbytea: \"bytea\",\n\t};\n\n\treturn typeMap[data_type] || data_type;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\nexport function buildWhereClause(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst paramIndex = values.length + 1;\n\t\tconst columnName = `\"${filter.columnName}\"`;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\t// Handle NULL values\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tconditions.push(`${columnName}::text LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tconditions.push(`${columnName}::text NOT LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tconditions.push(`${columnName}::text ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName}::text NOT ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Unknown operator, skip\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\nexport function buildSortClause(sorts: SortType[] | string, order: SortDirection): string {\n\t// Handle array of Sort objects (new format for referenced tables)\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\"${sort.columnName}\" ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\t// Handle legacy format (string column name + order)\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \"${sorts}\" ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\nexport function buildCursorWhereClause(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n\tstartParamIndex: number,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\t// Determine comparison operator based on direction and sort order\n\t// Forward + ASC = >, Forward + DESC = <\n\t// Backward + ASC = <, Backward + DESC = >\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\t// Build row comparison for multi-column cursor\n\t// Uses tuple comparison: (col1, col2, ...) > (val1, val2, ...)\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\"${col}\"`).join(\", \");\n\t\tconst placeholders = sortColumns.map((_, i) => `$${startParamIndex + i}`).join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClause,\n\tbuildSortClause,\n\tbuildWhereClause,\n} from \"@/utils/build-clauses.js\";\n\n// Encode cursor data to base64 string\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\n// Decode base64 cursor string to cursor data\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// Get primary key column(s) for a table\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getDbPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\t// Quote the table name to preserve case sensitivity in PostgreSQL\n\tconst quotedTableName = `\"${tableName}\"`;\n\tconst result = await pool.query(\n\t\t`SELECT a.attname as column_name\n\t\t FROM pg_index i\n\t\t JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n\t\t WHERE i.indrelid = $1::regclass AND i.indisprimary\n\t\t ORDER BY array_position(i.indkey, a.attnum)`,\n\t\t[quotedTableName],\n\t);\n\treturn result.rows.map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getDbPool(db);\n\n\t// Get primary key columns for stable cursor pagination\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\t// Determine sort columns - use provided sort or fall back to primary key\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\t// Always include primary key columns for stable pagination\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// If no sort columns and no primary key, fall back to ctid (PostgreSQL internal row id)\n\tif (cursorColumns.length === 0) {\n\t\tcursorColumns.push(\"ctid\");\n\t}\n\t// Build filter WHERE clause\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClause(filters);\n\t// Build cursor WHERE clause if cursor is provided\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClause(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t\tfilterValues.length + 1,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\t// Combine WHERE clauses\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\t// Remove \"WHERE \" prefix from filterWhereClause and combine\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\t// Build sort clause\n\tconst sortClause = buildSortClause(Array.isArray(sort) ? sort : sort, order);\n\n\t// For backward pagination, reverse the sort order\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else {\n\t\t\t// Default sort by cursor columns in reverse\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\"${col}\" ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\t// Default sort by cursor columns\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\"${col}\" ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\t// Get total count (with filters only, not cursor)\n\tconst countRes = await pool.query(\n\t\t`SELECT COUNT(*) as total FROM \"${tableName}\" ${filterWhereClause}`,\n\t\tfilterValues,\n\t);\n\tconst totalRows = Number(countRes.rows[0].total);\n\t// Fetch one extra row to determine if there are more results\n\tconst limitParamIndex = filterValues.length + cursorValues.length + 1;\n\tconst dataRes = await pool.query(\n\t\t`SELECT * FROM \"${tableName}\" ${combinedWhereClause} ${effectiveSortClause} LIMIT $${limitParamIndex}`,\n\t\t[...filterValues, ...cursorValues, limit + 1],\n\t);\n\t// Check if table has columns\n\tconst hasColumns = dataRes.fields && dataRes.fields.length > 0;\n\t// Filter out empty objects\n\tlet rows = hasColumns\n\t\t? dataRes.rows.filter((row) => Object.keys(row).length > 0)\n\t\t: dataRes.rows;\n\t// Determine if there are more results\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\t// For backward pagination, reverse the results to maintain correct order\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\t// Build cursors for next/previous pages\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\tif (rows.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\t\t// Create cursor from row values\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\t\t// For forward pagination\n\t\tif (direction === \"asc\") {\n\t\t\t// Next cursor: if there are more results, encode the last row\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if we used a cursor to get here, encode the first row\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\t// For backward pagination\n\t\t\t// Next cursor: if we used a cursor, encode the last row (to go forward again)\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if there are more results going backward, encode the first row\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Updates multiple cells in a table. Can update multiple rows or multiple cells in the same row.\n * Groups updates by row and executes them efficiently.\n */\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getDbPool(db);\n\n\t// Group updates by row (using the primary key value)\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data. Please ensure the row has a \"${primaryKey}\" column.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\t// Use transaction for multiple updates\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\t// Execute updates for each row\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, index) => `\"${u.columnName}\" = $${index + 1}`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\t// If the value is an object or array, stringify it for JSON/JSONB columns\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\t// Add the primary key value as the last parameter\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \"${tableName}\"\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \"${primaryKey}\" = $${values.length}\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\tconst result = await pool.query(query, values);\n\t\t\tif (result.rowCount === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowCount ?? 0;\n\t\t}\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import type { DatabaseTypeSchema } from \"shared/types/database.types.js\";\n\n// PostgreSQL DAOs\nimport * as pgAddRecord from \"./add-record.dao.js\";\nimport * as pgBulkInsertRecords from \"./bulk-insert-records.dao.js\";\nimport * as pgCreateTable from \"./create-table.dao.js\";\nimport * as pgDatabaseList from \"./database-list.dao.js\";\nimport * as pgDeleteColumn from \"./delete-column.dao.js\";\nimport * as pgDeleteRecords from \"./delete-records.dao.js\";\nimport * as pgDeleteTable from \"./delete-table.dao.js\";\nimport * as pgExportTable from \"./export-table.dao.js\";\nimport { bulkInsertRecords as mongoBulkInsertRecords } from \"./mongo/bulk-insert-records.mongo.dao.js\";\n// MongoDB DAOs\nimport {\n\tgetMongoConnectionInfo,\n\tgetMongoCurrentDatabase,\n\tgetMongoDatabasesList,\n} from \"./mongo/database-list.dao.js\";\nimport { executeMongoQuery } from \"./mongo/query.dao.js\";\nimport {\n\taddMongoRecord,\n\tdeleteMongoRecords,\n\tforceDeleteMongoRecords,\n\tupdateMongoRecords,\n} from \"./mongo/records.dao.js\";\nimport { getTableSchema as mongoGetTableSchema } from \"./mongo/table-schema.mongo.dao.js\";\nimport {\n\tcreateMongoCollection,\n\tdeleteMongoColumn,\n\texportMongoTableData,\n\tgetMongoTableColumns,\n\tgetMongoTableData,\n\tgetMongoTablesList,\n} from \"./mongo/tables.dao.js\";\n// MSSQL DAOs\nimport * as mssqlAddRecord from \"./mssql/add-record.mssql.dao.js\";\nimport * as mssqlBulkInsertRecords from \"./mssql/bulk-insert-records.mssql.dao.js\";\nimport * as mssqlCreateTable from \"./mssql/create-table.mssql.dao.js\";\nimport * as mssqlDatabaseList from \"./mssql/database-list.mssql.dao.js\";\nimport * as mssqlDeleteColumn from \"./mssql/delete-column.mssql.dao.js\";\nimport * as mssqlDeleteRecords from \"./mssql/delete-records.mssql.dao.js\";\nimport * as mssqlDeleteTable from \"./mssql/delete-table.mssql.dao.js\";\nimport * as mssqlExportTable from \"./mssql/export-table.mssql.dao.js\";\nimport * as mssqlQuery from \"./mssql/query.mssql.dao.js\";\nimport * as mssqlTableColumns from \"./mssql/table-columns.mssql.dao.js\";\nimport * as mssqlTableList from \"./mssql/table-list.mssql.dao.js\";\nimport * as mssqlTableSchema from \"./mssql/table-schema.mssql.dao.js\";\nimport * as mssqlTablesData from \"./mssql/tables-data.mssql.dao.js\";\nimport * as mssqlUpdateRecords from \"./mssql/update-records.mssql.dao.js\";\n// MySQL DAOs\nimport * as mysqlAddRecord from \"./mysql/add-record.mysql.dao.js\";\nimport * as mysqlBulkInsertRecords from \"./mysql/bulk-insert-records.mysql.dao.js\";\nimport * as mysqlCreateTable from \"./mysql/create-table.mysql.dao.js\";\nimport * as mysqlDatabaseList from \"./mysql/database-list.mysql.dao.js\";\nimport * as mysqlDeleteColumn from \"./mysql/delete-column.mysql.dao.js\";\nimport * as mysqlDeleteRecords from \"./mysql/delete-records.mysql.dao.js\";\nimport * as mysqlDeleteTable from \"./mysql/delete-table.mysql.dao.js\";\nimport * as mysqlExportTable from \"./mysql/export-table.mysql.dao.js\";\nimport * as mysqlQuery from \"./mysql/query.mysql.dao.js\";\nimport * as mysqlTableColumns from \"./mysql/table-columns.mysql.dao.js\";\nimport * as mysqlTableList from \"./mysql/table-list.mysql.dao.js\";\nimport * as mysqlTableSchema from \"./mysql/table-schema.mysql.dao.js\";\nimport * as mysqlTablesData from \"./mysql/tables-data.mysql.dao.js\";\nimport * as mysqlUpdateRecords from \"./mysql/update-records.mysql.dao.js\";\nimport * as pgQuery from \"./query.dao.js\";\nimport * as pgTableColumns from \"./table-columns.dao.js\";\nimport * as pgTableList from \"./table-list.dao.js\";\nimport * as pgTableSchema from \"./table-schema.dao.js\";\nimport * as pgTablesData from \"./tables-data.dao.js\";\nimport * as pgUpdateRecords from \"./update-records.dao.js\";\n\n/**\n * DAO Factory - Automatically routes to the correct database implementation\n *\n * Usage:\n * ```typescript\n * const dao = getDaoFactory(dbType);\n * const tables = await dao.getTablesList(db);\n * ```\n */\n\nconst daoRegistry = {\n\tpg: {\n\t\taddRecord: pgAddRecord.addRecord,\n\t\tbulkInsertRecords: pgBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: pgCreateTable.createTable,\n\t\tgetDatabasesList: pgDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: pgDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: pgDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: pgDeleteColumn.deleteColumn,\n\t\tdeleteRecords: pgDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: pgDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: pgDeleteTable.deleteTable,\n\t\texportTableData: pgExportTable.exportTableData,\n\t\texecuteQuery: pgQuery.executeQuery,\n\t\tgetTableColumns: pgTableColumns.getTableColumns,\n\t\tgetTablesList: pgTableList.getTablesList,\n\t\tgetTableSchema: pgTableSchema.getTableSchema,\n\t\tgetTableData: pgTablesData.getTableData,\n\t\tupdateRecords: pgUpdateRecords.updateRecords,\n\t},\n\tmysql: {\n\t\taddRecord: mysqlAddRecord.addRecord,\n\t\tbulkInsertRecords: mysqlBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: mysqlCreateTable.createTable,\n\t\tgetDatabasesList: mysqlDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: mysqlDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: mysqlDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: mysqlDeleteColumn.deleteColumn,\n\t\tdeleteRecords: mysqlDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: mysqlDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: mysqlDeleteTable.deleteTable,\n\t\texportTableData: mysqlExportTable.exportTableData,\n\t\texecuteQuery: mysqlQuery.executeQuery,\n\t\tgetTableColumns: mysqlTableColumns.getTableColumns,\n\t\tgetTablesList: mysqlTableList.getTablesList,\n\t\tgetTableSchema: mysqlTableSchema.getTableSchema,\n\t\tgetTableData: mysqlTablesData.getTableData,\n\t\tupdateRecords: mysqlUpdateRecords.updateRecords,\n\t},\n\tmongodb: {\n\t\taddRecord: ({ db, params }: Parameters<typeof pgAddRecord.addRecord>[0]) =>\n\t\t\taddMongoRecord({ db, params }),\n\t\tbulkInsertRecords: mongoBulkInsertRecords,\n\t\tcreateTable: ({\n\t\t\tdb,\n\t\t\ttableData,\n\t\t}: {\n\t\t\tdb: string;\n\t\t\ttableData: Parameters<typeof pgCreateTable.createTable>[0][\"tableData\"];\n\t\t}) => createMongoCollection({ tableName: tableData?.tableName ?? \"\", tableData, db }),\n\t\tgetDatabasesList: getMongoDatabasesList,\n\t\tgetCurrentDatabase: getMongoCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: getMongoConnectionInfo,\n\t\tdeleteColumn: ({\n\t\t\tdb,\n\t\t\ttableName,\n\t\t\tcolumnName,\n\t\t}: Parameters<typeof pgDeleteColumn.deleteColumn>[0]) =>\n\t\t\tdeleteMongoColumn({ tableName, columnName, db }),\n\t\tdeleteRecords: deleteMongoRecords,\n\t\tforceDeleteRecords: forceDeleteMongoRecords,\n\t\tdeleteTable: async ({ db, tableName }: { db: string; tableName: string }) => {\n\t\t\tconst { getMongoDb } = await import(\"@/db-manager.js\");\n\t\t\tconst mongoDb = await getMongoDb(db);\n\t\t\tawait mongoDb.collection(tableName).drop();\n\t\t},\n\t\texportTableData: ({\n\t\t\tdb,\n\t\t\ttableName,\n\t\t}: Parameters<typeof pgExportTable.exportTableData>[0]) =>\n\t\t\texportMongoTableData({ tableName, db }),\n\t\texecuteQuery: ({ query, db }: Parameters<typeof pgQuery.executeQuery>[0]) =>\n\t\t\texecuteMongoQuery({ query, db }),\n\t\tgetTableColumns: getMongoTableColumns,\n\t\tgetTablesList: ({ db }: { db: string }) => getMongoTablesList(db),\n\t\tgetTableSchema: mongoGetTableSchema,\n\t\tgetTableData: getMongoTableData,\n\t\tupdateRecords: ({ db, params }: Parameters<typeof pgUpdateRecords.updateRecords>[0]) =>\n\t\t\tupdateMongoRecords({ db, params }),\n\t},\n\tmssql: {\n\t\taddRecord: mssqlAddRecord.addRecord,\n\t\tbulkInsertRecords: mssqlBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: mssqlCreateTable.createTable,\n\t\tgetDatabasesList: mssqlDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: mssqlDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: mssqlDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: mssqlDeleteColumn.deleteColumn,\n\t\tdeleteRecords: mssqlDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: mssqlDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: mssqlDeleteTable.deleteTable,\n\t\texportTableData: mssqlExportTable.exportTableData,\n\t\texecuteQuery: mssqlQuery.executeQuery,\n\t\tgetTableColumns: mssqlTableColumns.getTableColumns,\n\t\tgetTablesList: mssqlTableList.getTablesList,\n\t\tgetTableSchema: mssqlTableSchema.getTableSchema,\n\t\tgetTableData: mssqlTablesData.getTableData,\n\t\tupdateRecords: mssqlUpdateRecords.updateRecords,\n\t},\n} as const;\n\nexport type DaoMethods = typeof daoRegistry.pg;\n\n/**\n * Get the DAO implementation for the specified database type\n * @param dbType - The database type (pg, mysql, mssql)\n * @returns DAO methods for the specified database type\n */\nexport function getDaoFactory(dbType: DatabaseTypeSchema): DaoMethods {\n\tif (dbType === \"mongodb\") {\n\t\treturn daoRegistry.mongodb as unknown as DaoMethods;\n\t}\n\treturn daoRegistry[dbType];\n}\n\n/**\n * Execute a DAO method with automatic database type routing\n * @param dbType - The database type\n * @param method - The DAO method name\n * @param args - Arguments to pass to the DAO method\n */\nexport async function executeDaoMethod<K extends keyof DaoMethods>(\n\tdbType: DatabaseTypeSchema,\n\tmethod: K,\n\t...args: Parameters<DaoMethods[K]>\n): Promise<ReturnType<DaoMethods[K]>> {\n\tconst dao = getDaoFactory(dbType);\n\t// @ts-expect-error - Complex type inference, but runtime safe\n\treturn dao[method](...args);\n}\n","import { Hono } from \"hono\";\nimport type {\n\tConnectionInfoSchemaType,\n\tCurrentDatabaseSchemaType,\n\tDatabaseListSchemaType,\n} from \"shared/types\";\nimport type { ApiHandler } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\nimport { getDbType } from \"@/db-manager.js\";\n\n/**\n * /databases routes (at root level, no dbType required)\n * GET /databases - Get list of all databases on the server (name, size, owner, encoding)\n * GET /databases/current - Get the name of the database we are currently connected to\n * GET /databases/connection - Get connection details and server information\n */\nexport const databasesRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /databases/...\n\t */\n\t.basePath(\"/databases\")\n\n\t/**\n\t * GET /databases\n\t * Returns list of all databases on the server (name, size, owner, encoding) and the database type\n\t */\n\t.get(\"/\", async (c): ApiHandler<DatabaseListSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst databases = await dao.getDatabasesList();\n\t\treturn c.json({ data: { databases, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/current\n\t * Returns the name of the database we are currently connected to and the database type\n\t */\n\t.get(\"/current\", async (c): ApiHandler<CurrentDatabaseSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst current = await dao.getCurrentDatabase();\n\t\treturn c.json({ data: { db: current.db, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/connection\n\t * Returns connection details and server information\n\t */\n\t.get(\"/connection\", async (c): ApiHandler<ConnectionInfoSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst info = await dao.getDatabaseConnectionInfo();\n\t\treturn c.json({ data: info }, 200);\n\t});\n\nexport type DatabasesRoutes = typeof databasesRoutes.routes;\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { databaseSchema, type ExecuteQueryResult, executeQuerySchema } from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\n\nexport const queryRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/query/...\n\t */\n\t.basePath(\"/query\")\n\n\t/**\n\t * POST /query\n\t * Executes a SQL query on the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", executeQuerySchema),\n\t\tasync (c): ApiHandler<ExecuteQueryResult> => {\n\t\t\tconst { query } = c.req.valid(\"json\");\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst data = await dao.executeQuery({ query, db });\n\t\t\treturn c.json({ data }, 200);\n\t\t},\n\t);\n\nexport type QueryRoutes = typeof queryRoutes;\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddRecordSchema,\n\tbulkInsertRecordsSchema,\n\ttype DeleteRecordResult,\n\tdatabaseSchema,\n\tdeleteRecordSchema,\n\tupdateRecordsSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\n\nexport const recordsRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/records/...\n\t */\n\t.basePath(\"/records\")\n\n\t/**\n\t * POST /records\n\t * Adds a new record into a table\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", addRecordSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, data } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { insertedCount } = await dao.addRecord({ db, params: { tableName, data } });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Record inserted into \"${tableName}\" with ${insertedCount} rows inserted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /records\n\t * Updates one or more cells in a table\n\t */\n\t.patch(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", updateRecordsSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKey, updates } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { updatedCount } = await dao.updateRecords({\n\t\t\t\tparams: { tableName, primaryKey, updates },\n\t\t\t\tdb,\n\t\t\t});\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Updated ${updatedCount} records in \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records\n\t * Deletes records from a table\n\t */\n\t.delete(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<DeleteRecordResult, 409 | 200> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { deletedCount, fkViolation, relatedRecords } = await dao.deleteRecords({\n\t\t\t\ttableName,\n\t\t\t\tprimaryKeys,\n\t\t\t\tdb,\n\t\t\t});\n\t\t\tif (fkViolation) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdeletedCount: 0,\n\t\t\t\t\t\t\tfkViolation: true,\n\t\t\t\t\t\t\trelatedRecords,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t409,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdeletedCount,\n\t\t\t\t\t\tfkViolation: false,\n\t\t\t\t\t\trelatedRecords: [],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records/force\n\t * Force deletes records and all related FK records\n\t */\n\t.delete(\n\t\t\"/force\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<{ deletedCount: number }> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst deletedCount = await dao.forceDeleteRecords({ tableName, primaryKeys, db });\n\t\t\treturn c.json({ data: deletedCount }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /records/bulk\n\t * Bulk inserts multiple records into a table\n\t */\n\t.post(\n\t\t\"/bulk\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", bulkInsertRecordsSchema),\n\t\tasync (c): ApiHandler<object> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, records } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst result = await dao.bulkInsertRecords({ tableName, records, db });\n\t\t\tconsole.log(\"result\", result);\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t);\n\nexport type RecordsRoutes = typeof recordsRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Adds a column to a PostgreSQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (columnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tlet columnDefinition = `\"${columnName}\" ${columnType}`;\n\n\tif (isArray) {\n\t\tcolumnDefinition += \"[]\";\n\t}\n\n\tif (isPrimaryKey) {\n\t\tcolumnDefinition += \" PRIMARY KEY\";\n\t}\n\n\tif (isUnique && !isPrimaryKey) {\n\t\tcolumnDefinition += \" UNIQUE\";\n\t}\n\n\tif (!isNullable) {\n\t\tcolumnDefinition += \" NOT NULL\";\n\t}\n\n\tif (isIdentity) {\n\t\tcolumnDefinition += \" GENERATED ALWAYS AS IDENTITY\";\n\t}\n\n\tif (defaultValue?.trim() && !isIdentity) {\n\t\tcolumnDefinition += ` DEFAULT ${defaultValue.trim()}`;\n\t}\n\n\tawait pool.query(`ALTER TABLE \"${tableName}\" ADD COLUMN ${columnDefinition}`);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Alters a PostgreSQL column's type, nullability, and default value.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst client = await pool.connect();\n\n\ttry {\n\t\tawait client.query(\"BEGIN\");\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" TYPE ${columnType}`,\n\t\t);\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" ${isNullable ? \"DROP\" : \"SET\"} NOT NULL`,\n\t\t);\n\n\t\tif (defaultValue?.trim()) {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" SET DEFAULT ${defaultValue.trim()}`,\n\t\t\t);\n\t\t} else {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" DROP DEFAULT`,\n\t\t\t);\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tthrow error;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\n/**\n * Adds a field to all documents in a MongoDB collection.\n * Sets a typed default value and updates the collection's JSON Schema validator.\n */\nexport async function addMongoField({\n\ttableName,\n\tcolumnName,\n\tcolumnType,\n\tdefaultValue,\n\tisNullable,\n\tdb,\n}: AddColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\t// Check field doesn't already exist\n\tconst conflict = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [columnName]: { $exists: true } });\n\tif (conflict) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Field \"${columnName}\" already exists in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Resolve a typed default value\n\tconst resolvedDefault = resolveDefault(defaultValue, columnType);\n\n\t// Set the field on all existing documents\n\tawait mongoDb\n\t\t.collection(tableName)\n\t\t.updateMany({}, { $set: { [columnName]: resolvedDefault } });\n\n\t// Update the JSON Schema validator\n\tconst collInfo = collections[0] as {\n\t\toptions?: {\n\t\t\tvalidator?: {\n\t\t\t\t$jsonSchema?: { properties?: Record<string, unknown>; required?: string[] };\n\t\t\t};\n\t\t};\n\t};\n\tconst existingSchema = collInfo.options?.validator?.$jsonSchema ?? {};\n\tconst properties: Record<string, unknown> = {\n\t\t...((existingSchema.properties as Record<string, unknown>) ?? {}),\n\t\t[columnName]: { bsonType: isNullable ? [columnType, \"null\"] : columnType },\n\t};\n\tconst required: string[] = [...(existingSchema.required ?? [])];\n\tif (!isNullable && !required.includes(columnName)) {\n\t\trequired.push(columnName);\n\t}\n\n\tawait mongoDb.command({\n\t\tcollMod: tableName,\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\t...existingSchema,\n\t\t\t\tbsonType: \"object\",\n\t\t\t\tproperties,\n\t\t\t\t...(required.length > 0 ? { required } : {}),\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"warn\",\n\t});\n}\n\nconst resolveDefault = (\n\tdefaultValue: string | null | undefined,\n\tcolumnType: string,\n): unknown => {\n\tif (defaultValue !== undefined && defaultValue !== null && defaultValue.trim() !== \"\") {\n\t\ttry {\n\t\t\treturn JSON.parse(defaultValue);\n\t\t} catch {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\tswitch (columnType) {\n\t\tcase \"string\":\n\t\t\treturn \"\";\n\t\tcase \"int\":\n\t\tcase \"long\":\n\t\tcase \"double\":\n\t\tcase \"decimal\":\n\t\t\treturn 0;\n\t\tcase \"bool\":\n\t\t\treturn false;\n\t\tcase \"array\":\n\t\t\treturn [];\n\t\tcase \"object\":\n\t\t\treturn {};\n\t\tcase \"date\":\n\t\t\treturn new Date();\n\t\tdefault:\n\t\t\treturn null;\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AlterColumnParamsSchemaType, RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\n/**\n * Renames a field across all documents in a collection using $rename.\n */\nexport async function mongoRenameColumn({\n\ttableName,\n\tcolumnName,\n\tnewColumnName,\n\tdb,\n}: RenameColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tif (columnName === \"_id\") {\n\t\tthrow new HTTPException(400, { message: 'Cannot rename the \"_id\" field' });\n\t}\n\n\t// Check if the field exists in at least one document\n\tconst sample = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [columnName]: { $exists: true } });\n\tif (!sample) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Field \"${columnName}\" does not exist in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Check target field doesn't already exist\n\tconst conflict = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [newColumnName]: { $exists: true } });\n\tif (conflict) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Field \"${newColumnName}\" already exists in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait mongoDb\n\t\t.collection(tableName)\n\t\t.updateMany(\n\t\t\t{ [columnName]: { $exists: true } },\n\t\t\t{ $rename: { [columnName]: newColumnName } },\n\t\t);\n}\n\n/**\n * Alters a field across all documents in a collection.\n * MongoDB is schemaless so this updates the collection's JSON Schema validator\n * and optionally converts existing field values to the new type.\n */\nexport async function mongoAlterColumn({\n\ttableName,\n\tcolumnName,\n\tcolumnType,\n\tisNullable,\n\tdb,\n}: AlterColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tif (columnName === \"_id\") {\n\t\tthrow new HTTPException(400, { message: 'Cannot alter the \"_id\" field' });\n\t}\n\n\t// Fetch existing validator if any\n\tconst collInfo = collections[0] as {\n\t\toptions?: {\n\t\t\tvalidator?: {\n\t\t\t\t$jsonSchema?: { properties?: Record<string, unknown>; required?: string[] };\n\t\t\t};\n\t\t};\n\t};\n\tconst existingSchema = collInfo.options?.validator?.$jsonSchema ?? {};\n\tconst properties: Record<string, unknown> = {\n\t\t...((existingSchema.properties as Record<string, unknown>) ?? {}),\n\t};\n\tconst required: string[] = [...(existingSchema.required ?? [])];\n\n\t// Update the field's bsonType in the validator\n\tconst bsonType = isNullable ? [columnType, \"null\"] : columnType;\n\tproperties[columnName] = { bsonType };\n\n\t// Update required list\n\tconst reqIndex = required.indexOf(columnName);\n\tif (!isNullable && reqIndex === -1) {\n\t\trequired.push(columnName);\n\t} else if (isNullable && reqIndex !== -1) {\n\t\trequired.splice(reqIndex, 1);\n\t}\n\n\tawait mongoDb.command({\n\t\tcollMod: tableName,\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\t...existingSchema,\n\t\t\t\tbsonType: \"object\",\n\t\t\t\tproperties,\n\t\t\t\t...(required.length > 0 ? { required } : {}),\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"warn\",\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Adds a column to a MySQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (columnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisPrimaryKey,\n\t\t\tisNullable,\n\t\t\tisUnique,\n\t\t\tisIdentity,\n\t\t\tisArray,\n\t\t},\n\t\t{\n\t\t\tincludePrimaryKey: true,\n\t\t\tincludeUnique: true,\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` ADD COLUMN ${columnDefinition}`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Alters a MySQL column's type, nullability, and default value using MODIFY COLUMN.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT EXTRA\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?\n\t\t LIMIT 1`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnRow = (columnRows as Array<{ EXTRA?: string | null }>)[0];\n\tif (!columnRow) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisNullable,\n\t\t},\n\t\t{\n\t\t\tpreserveAutoIncrement: columnRow.EXTRA?.toLowerCase().includes(\"auto_increment\"),\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` MODIFY COLUMN ${columnDefinition}`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Renames a MySQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [currentColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst currentColumnExists =\n\t\tNumber((currentColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!currentColumnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [nextColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, newColumnName],\n\t);\n\tconst nextColumnExists = Number((nextColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (nextColumnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` RENAME COLUMN \\`${columnName}\\` TO \\`${newColumnName}\\``,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Renames a PostgreSQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: currentColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tcolumnName,\n\t]);\n\tif (!currentColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst { rows: nextColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tnewColumnName,\n\t]);\n\tif (nextColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.query(\n\t\t`ALTER TABLE \"${tableName}\" RENAME COLUMN \"${columnName}\" TO \"${newColumnName}\"`,\n\t);\n}\n","import type { CellValue, FormatType } from \"shared/types\";\nimport { utils, write } from \"xlsx\";\n\ninterface ExportFileOptions {\n\tcols: string[];\n\trows: Record<string, CellValue>[];\n\tformat: FormatType;\n\ttableName: string;\n}\n\n/**\n * Converts table data to the specified export format (CSV, XLSX, or JSON)\n *\n * @param options - The export options\n * @param options.cols - Array of column names\n * @param options.rows - Array of row data objects\n * @param options.format - The export format ('csv', 'xlsx', or 'json')\n * @param options.tableName - The name of the table being exported\n * @returns The file content as a Uint8Array\n */\nexport function getExportFile({ cols, rows, format, tableName }: ExportFileOptions): BodyInit {\n\tswitch (format) {\n\t\tcase \"json\": {\n\t\t\tconst jsonContent = JSON.stringify(rows ?? [], null, 2);\n\t\t\treturn new Uint8Array(Buffer.from(jsonContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"csv\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst csvContent = utils.sheet_to_csv(worksheet);\n\t\t\treturn new Uint8Array(Buffer.from(csvContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"xlsx\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst workbook = utils.book_new();\n\t\t\tutils.book_append_sheet(workbook, worksheet, tableName.slice(0, 31));\n\t\t\tconst buffer = write(workbook, {\n\t\t\t\tbookType: \"xlsx\",\n\t\t\t\ttype: \"buffer\",\n\t\t\t}) as Buffer;\n\t\t\treturn new Uint8Array(buffer);\n\t\t}\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddColumnSchema,\n\talterColumnSchema,\n\ttype ColumnInfoSchemaType,\n\tcreateTableSchema,\n\ttype DeleteTableResult,\n\tdatabaseSchema,\n\tdeleteColumnParamSchema,\n\tdeleteColumnQuerySchema,\n\tdeleteTableQuerySchema,\n\texportTableSchema,\n\trenameColumnSchema,\n\ttype TableDataResultSchemaType,\n\ttype TableInfoSchemaType,\n\ttype TableSchemaResult,\n\ttableDataQuerySchema,\n\ttableNameSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { addColumn as pgAddColumn } from \"@/dao/add-column.dao.js\";\nimport { alterColumn as pgAlterColumn } from \"@/dao/alter-column.dao.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\nimport { addMongoField } from \"@/dao/mongo/add-column.mongo.dao.js\";\nimport { mongoAlterColumn, mongoRenameColumn } from \"@/dao/mongo/alter-column.mongo.dao.js\";\nimport { addColumn as mysqlAddColumn } from \"@/dao/mysql/add-column.mysql.dao.js\";\nimport { alterColumn as mysqlAlterColumn } from \"@/dao/mysql/alter-column.mysql.dao.js\";\nimport { renameColumn as mysqlRenameColumn } from \"@/dao/mysql/rename-column.mysql.dao.js\";\nimport { renameColumn as pgRenameColumn } from \"@/dao/rename-column.dao.js\";\nimport { getExportFile } from \"@/utils/get-export-file.js\";\n\nexport const tablesRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/tables/...\n\t */\n\t.basePath(\"/tables\")\n\n\t/**\n\t * GET /tables\n\t * Returns list of all tables in the currently connected database\n\t */\n\t.get(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tasync (c): ApiHandler<TableInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst tablesList = await dao.getTablesList(db);\n\t\t\treturn c.json({ data: tablesList }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables\n\t * Creates a new table in the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", createTableSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tawait dao.createTable({ tableData: body, db });\n\t\t\treturn c.json({ data: `Table ${body.tableName} created successfully` }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName\n\t * Deletes a table from the database\n\t */\n\t.delete(\n\t\t\"/:tableName\",\n\t\tzValidator(\"query\", deleteTableQuerySchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<DeleteTableResult> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst result = await dao.deleteTable({ tableName, db, cascade });\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName/columns/:columnName\n\t * Deletes a column from a table\n\t */\n\t.delete(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", deleteColumnQuerySchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { deletedCount } = await dao.deleteColumn({ tableName, columnName, cascade, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" deleted successfully from table \"${tableName}\" with ${deletedCount} rows deleted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables/:tableName/columns\n\t * Adds a column to a table\n\t */\n\t.post(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"json\", addColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAddColumn({ tableName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait addMongoField({ tableName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAddColumn({ tableName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${body.columnName}\" added successfully to table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName/rename\n\t * Renames a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName/rename\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", renameColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait mongoRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" renamed to \"${body.newColumnName}\" in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName\n\t * Alters a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", alterColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait mongoAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" updated successfully in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/columns\n\t * Returns list of all columns in a table\n\t */\n\t.get(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<ColumnInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst columns = await dao.getTableColumns({ tableName, db });\n\t\t\treturn c.json({ data: columns }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/schema\n\t * Returns the CREATE TABLE schema for a table\n\t */\n\t.get(\n\t\t\"/:tableName/schema\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<TableSchemaResult> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst schema = await dao.getTableSchema({ tableName, db });\n\t\t\treturn c.json({ data: { schema } }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/data\n\t * Get cursor-paginated data for a table\n\t */\n\t.get(\n\t\t\"/:tableName/data\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", tableDataQuerySchema),\n\t\tasync (c): ApiHandler<TableDataResultSchemaType> => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { cursor, limit, direction, sort, order, filters, db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst tableData = await dao.getTableData({\n\t\t\t\ttableName,\n\t\t\t\tcursor,\n\t\t\t\tlimit,\n\t\t\t\tdirection,\n\t\t\t\tsort,\n\t\t\t\torder,\n\t\t\t\tfilters,\n\t\t\t\tdb,\n\t\t\t});\n\t\t\treturn c.json({ data: tableData }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/export\n\t * Export table data to CSV or XLSX format\n\t */\n\t.get(\n\t\t\"/:tableName/export\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", exportTableSchema),\n\t\tasync (c) => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { db, format } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\n\t\t\tconst { cols, rows } = await dao.exportTableData({ tableName, db });\n\t\t\tconst fileContent = getExportFile({ cols, rows, format, tableName });\n\t\t\tlet contentType: string | undefined;\n\n\t\t\tswitch (format) {\n\t\t\t\tcase \"csv\":\n\t\t\t\t\tcontentType = \"text/csv\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"xlsx\":\n\t\t\t\t\tcontentType = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"json\":\n\t\t\t\t\tcontentType = \"application/json\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn new Response(fileContent, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": contentType ?? \"\",\n\t\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${tableName}_export.${format}\"`,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t);\n\nexport type TablesRoutes = typeof tablesRoutes.routes;\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { prettyJSON } from \"hono/pretty-json\";\nimport { type DatabaseTypeSchema, databaseTypeParamSchema } from \"shared/types\";\nimport type { AppType } from \"@/app.types.js\";\nimport { handleError, validationHook } from \"@/middlewares/error-handler.js\";\nimport { chatRoutes } from \"@/routes/chat.routes.js\";\nimport { databasesRoutes } from \"@/routes/databases.routes.js\";\nimport { queryRoutes } from \"@/routes/query.routes.js\";\nimport { recordsRoutes } from \"@/routes/records.routes.js\";\nimport { tablesRoutes } from \"@/routes/tables.routes.js\";\n\n/**\n * Get the path to the core distribution directory.\n */\nconst getCoreDistPath = () => {\n\tif (process.env.NODE_ENV === \"development\") {\n\t\treturn path.resolve(process.cwd(), \"../core/dist\");\n\t}\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\treturn path.resolve(__dirname, \"./core-dist\");\n};\n\nexport const createServer = () => {\n\tconst app = new Hono<AppType>({ strict: false })\n\t\t/**\n\t\t * Enable CORS\n\t\t */\n\t\t.use(\"/*\", cors())\n\n\t\t/**\n\t\t * Pretty print the JSON response\n\t\t */\n\t\t.use(prettyJSON({ space: 2 }))\n\n\t\t/**\n\t\t * Enable logger in development mode\n\t\t */\n\t\t.use(process.env.NODE_ENV === \"development\" ? logger() : (_, next) => next())\n\n\t\t/**\n\t\t * Serve the favicon.ico file\n\t\t */\n\t\t.use(\n\t\t\t\"/favicon.ico\",\n\t\t\tserveStatic({\n\t\t\t\tpath: path.resolve(getCoreDistPath(), \"favicon.ico\"),\n\t\t\t}),\n\t\t)\n\n\t\t/**\n\t\t * Handle CORS requests\n\t\t */\n\t\t.use(\"*\", async (c, next) => {\n\t\t\tc.header(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\tc.header(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n\t\t\tc.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\t\t\tawait next();\n\t\t})\n\n\t\t/**\n\t\t * Handle errors\n\t\t */\n\t\t.onError(handleError)\n\n\t\t/**\n\t\t * Database routes - available at root level (no dbType required)\n\t\t */\n\t\t.route(\"/\", databasesRoutes)\n\t\t.route(\"/\", chatRoutes)\n\n\t\t/**\n\t\t * Serve static assets (before dbType validation to avoid conflicts)\n\t\t */\n\t\t.use(\"/assets/*\", serveStatic({ root: getCoreDistPath() }))\n\t\t.use(\"/image.png\", serveStatic({ root: getCoreDistPath() }))\n\n\t\t/**\n\t\t * Routes that require dbType validation - under /:dbType/...\n\t\t */\n\t\t.use(\"/:dbType/*\", zValidator(\"param\", databaseTypeParamSchema, validationHook))\n\t\t.use(\"/:dbType/*\", async (c, next) => {\n\t\t\tconst dbType = c.req.param(\"dbType\") as DatabaseTypeSchema;\n\t\t\tc.set(\"dbType\", dbType);\n\t\t\tawait next();\n\t\t})\n\t\t.route(\"/:dbType\", tablesRoutes)\n\t\t.route(\"/:dbType\", recordsRoutes)\n\t\t.route(\"/:dbType\", queryRoutes)\n\n\t\t/**\n\t\t * Serve all other static files as fallback (for SPA)\n\t\t */\n\t\t.use(\"/*\", serveStatic({ root: getCoreDistPath() }));\n\n\treturn { app };\n};\n\nexport type { AppType };\n\n// Export the app type for hc client\nexport type AppRoutes = ReturnType<typeof createServer>[\"app\"];\n","import { intro, outro } from \"@clack/prompts\";\nimport { serve } from \"@hono/node-server\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { args } from \"@/cmd/args.js\";\nimport { getDatabaseUrl } from \"@/cmd/get-db-url.js\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\nimport { showHelp } from \"@/cmd/show-help.js\";\nimport { showStatus } from \"@/cmd/show-status.js\";\nimport { showVersion } from \"@/cmd/show-version.js\";\n\nexport const main = async () => {\n\tconst { env, port, databaseUrl, varName, status, help, version } = args();\n\n\t// Handle help flag\n\tif (help) {\n\t\tshowHelp();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle version flag\n\tif (version) {\n\t\tshowVersion();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle status flag\n\tif (status) {\n\t\tawait showStatus(env, databaseUrl, varName);\n\t\tprocess.exit(0);\n\t}\n\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst PORT = port ? parseInt(port, 10) : DEFAULTS.PORT;\n\tconst VAR_NAME = varName || DEFAULTS.VAR_NAME;\n\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\tconst DATABASE_URL = databaseUrl ? databaseUrl : await getDatabaseUrl(ENV, VAR_NAME);\n\n\t// Set DATABASE_URL in process.env before importing createServer\n\t// This ensures the db pool is initialized with the correct connection string\n\tprocess.env.DATABASE_URL = DATABASE_URL;\n\n\t// Import createServer dynamically after setting DATABASE_URL\n\tconst { createServer } = await import(\"./utils/create-server.js\");\n\tconst { app } = createServer();\n\tserve({\n\t\tfetch: app.fetch,\n\t\tport: PORT,\n\t});\n\n\toutro(color.green(`Server running at ${color.cyan(`http://localhost:${PORT}`)}`));\n};\n\nmain().catch((err) => {\n\tconsole.error(color.red(`❌ Unexpected error: ${err.message}`));\n\tprocess.exit(1);\n});\n","import { program } from \"commander\";\nimport type { Args } from \"shared/types\";\n\n/**\n * Get the arguments from the command line\n */\nexport const args = () => {\n\tprogram\n\t\t.name(\"db-studio\")\n\t\t.option(\"-e, --env <path>\", \"Path to custom .env file\")\n\t\t.option(\"-p, --port <port>\", \"Port to run the server on\")\n\t\t.option(\"-d, --database-url <url>\", \"Database URL to use\")\n\t\t.option(\n\t\t\t\"-n, --var-name <name>\",\n\t\t\t\"Custom environment variable name (default: DATABASE_URL)\",\n\t\t)\n\t\t.option(\"-s, --status\", \"Show status of the server\")\n\t\t.option(\"-h, --help\", \"Show help\")\n\t\t.option(\"-v, --version\", \"Show version\")\n\t\t.parse(process.argv);\n\n\treturn program.opts<Args>();\n};\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { cancel, isCancel, note, select, spinner, text } from \"@clack/prompts\";\nimport { type DotenvParseOutput, parse as parseDotenv } from \"dotenv\";\nimport color from \"picocolors\";\n\n/**\n * Get the database URL from .env file, then process.env\n */\nexport const getDatabaseUrl = async (env?: DotenvParseOutput | null, varName?: string) => {\n\tconst envVarName = varName || \"DATABASE_URL\";\n\n\tif (env?.[envVarName]) {\n\t\treturn env[envVarName];\n\t}\n\n\t// Fall back to process.env (e.g. from shell or package.json script)\n\tif (process.env[envVarName]) {\n\t\treturn process.env[envVarName];\n\t}\n\n\tconst s = spinner();\n\ts.start(\"Looking for database connection...\");\n\n\tif (!env) {\n\t\tnote(color.red(`No .env file found and ${envVarName} not set in process.env`));\n\t} else {\n\t\tnote(color.red(`${envVarName} not found in .env or process.env`));\n\t}\n\n\tconst choice = await select({\n\t\tmessage: `How do you want to provide ${envVarName}?`,\n\t\toptions: [\n\t\t\t{ value: \"manual\", label: \"Enter connection string manually\" },\n\t\t\t{ value: \"other-env\", label: \"Use different .env file\" },\n\t\t\t// todo: add multiple db connections support\n\t\t\t{ value: \"cancel\", label: \"Cancel / Exit\" },\n\t\t],\n\t\tinitialValue: \"manual\",\n\t});\n\tif (isCancel(choice) || choice === \"cancel\") {\n\t\tcancel(\"No database connection provided. Exiting...\");\n\t\tprocess.exit(0);\n\t}\n\n\tif (choice === \"other-env\") {\n\t\ts.start(\"Waiting for path...\");\n\t\tconst customPath = await text({\n\t\t\tmessage: \"Enter path to .env file\",\n\t\t\tplaceholder: \"~/projects/myapp/.env.local or ./special.env\",\n\t\t\tvalidate(value?: string) {\n\t\t\t\tif (!value?.trim()) return \"Path is required\";\n\t\t\t},\n\t\t});\n\n\t\tif (isCancel(customPath)) {\n\t\t\tcancel(\"Cancelled.\");\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ts.stop(\"Trying custom .env...\");\n\n\t\tconst customEnvPath = resolve(customPath);\n\t\ttry {\n\t\t\tconst content = await readFile(customEnvPath, \"utf-8\");\n\t\t\tconst parsed = parseDotenv(content);\n\t\t\tif (parsed[envVarName]) {\n\t\t\t\treturn parsed[envVarName];\n\t\t\t}\n\t\t\tthrow new Error(`${envVarName} still missing in custom file`);\n\t\t} catch (e: unknown) {\n\t\t\tconst error = e as Error;\n\t\t\tcancel(`Cannot read or parse file: ${color.dim(error.message)}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// 3. Manual input\n\ts.stop(\"Manual input...\");\n\n\tconst dbUrl = await text({\n\t\tmessage: `Paste your ${envVarName}`,\n\t\tplaceholder: \"postgresql://user:password@localhost:5432/mydb\",\n\t\tvalidate(value?: string) {\n\t\t\tif (!value?.trim()) return \"Connection string is required!\";\n\t\t\ttry {\n\t\t\t\tnew URL(value); // very basic check\n\t\t\t\treturn undefined;\n\t\t\t} catch {\n\t\t\t\treturn \"Must be a valid URL format\";\n\t\t\t}\n\t\t},\n\t});\n\n\tif (isCancel(dbUrl)) {\n\t\tcancel(\"Cancelled.\");\n\t\tprocess.exit(0);\n\t}\n\n\treturn dbUrl.trim();\n};\n","import { access, readFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { parse as parseDotenv } from \"dotenv\";\n\n/**\n * Find .env path: try cwd, then walk up parent directories until root.\n */\nconst findEnvPath = async (startDir: string): Promise<string | null> => {\n\tlet dir = resolve(startDir);\n\tfor (;;) {\n\t\tconst envPath = resolve(dir, \".env\");\n\t\ttry {\n\t\t\tawait access(envPath);\n\t\t\treturn envPath;\n\t\t} catch {\n\t\t\t// ENOENT or other: try parent\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n};\n\n/**\n * Load the environment variables from the file.\n * When no path is given: tries current directory, then parent directories until a .env is found.\n * When --env path is given: uses that path only (no walk).\n */\nexport const loadEnv = async (env?: string) => {\n\tlet envPath: string | null;\n\n\tif (env) {\n\t\tenvPath = resolve(env);\n\t} else {\n\t\tenvPath = await findEnvPath(process.cwd());\n\t}\n\n\tif (!envPath) return null;\n\n\ttry {\n\t\tconst content = await readFile(envPath, \"utf-8\");\n\t\treturn parseDotenv(content);\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message.includes(\"ENOENT\")) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { META } from \"shared/constants/meta.js\";\n\n/**\n * Display help information\n */\nexport const showHelp = () => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconsole.log(color.bold(\"\\nUsage:\"));\n\tconsole.log(\" db-studio [options]\\n\");\n\n\tconsole.log(color.bold(\"Supported Databases:\"));\n\tconsole.log(\" MySQL, PostgreSQL\\n\");\n\n\tconsole.log(color.bold(\"Options:\"));\n\tconsole.log(\" -e, --env <path> Path to custom .env file\");\n\tconsole.log(\" -p, --port <port> Port to run the server on (default: 3333)\");\n\tconsole.log(\" -d, --database-url <url> Database URL to use\");\n\tconsole.log(\n\t\t\" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)\",\n\t);\n\tconsole.log(\" -s, --status Show status of the database connection\");\n\tconsole.log(\" -h, --help Show this help message\");\n\tconsole.log(\" -v, --version Show version number\\n\");\n\n\tconsole.log(color.bold(\"Examples:\"));\n\tconsole.log(\" db-studio\");\n\tconsole.log(\" db-studio -e .env.local\");\n\tconsole.log(\" db-studio -p 4000\");\n\tconsole.log(\" db-studio -d postgresql://user:pass@localhost:5432/mydb\");\n\tconsole.log(\" db-studio -n MY_DATABASE_URL\");\n\tconsole.log(\" db-studio -e .env.production -n PROD_DB_URL\");\n\tconsole.log(\" db-studio --status\\n\");\n\n\toutro(color.green(`For more information, visit: ${META.SITE_DOCS_LINK}`));\n};\n","import { intro, note, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\n\n/**\n * Show connection status\n */\nexport const showStatus = async (env?: string, databaseUrl?: string, varName?: string) => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst envVarName = varName || DEFAULTS.VAR_NAME;\n\tlet foundUrl: string | null = null;\n\n\t// Check if DATABASE_URL is provided via CLI\n\tif (databaseUrl) {\n\t\tfoundUrl = databaseUrl;\n\t} else {\n\t\t// Try .env file, then process.env\n\t\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\t\tif (ENV?.[envVarName]) {\n\t\t\tfoundUrl = ENV[envVarName];\n\t\t} else if (process.env[envVarName]) {\n\t\t\tfoundUrl = process.env[envVarName] ?? null;\n\t\t}\n\t}\n\n\tif (foundUrl) {\n\t\toutro(color.green(`✓ Database connection configured (using ${envVarName})`));\n\t} else {\n\t\tnote(color.red(`✗ ${envVarName} not found`), \"Status\");\n\t\tconsole.log(color.yellow(\"\\n To configure database connection:\"));\n\t\tconsole.log(color.dim(\" • Supported databases: MySQL, PostgreSQL\"));\n\t\tconsole.log(color.dim(` • Add ${envVarName} to your .env file or set it in process.env`));\n\t\tconsole.log(color.dim(\" • Use -d flag: db-studio -d <url>\"));\n\t\tconsole.log(color.dim(\" • Use -e flag: db-studio -e <path-to-env>\"));\n\t\tconsole.log(color.dim(\" • Use -n flag: db-studio -n <var-name>\\n\"));\n\n\t\toutro(color.yellow(\"⚠ No database connection configured\"));\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\n/**\n * Display version information\n */\nexport const showVersion = () => {\n\tintro(color.inverse(\" db-studio \"));\n\toutro(color.green(`🚀 db-studio v${packageJson.version}`));\n};\n","{\n \"name\": \"db-studio\",\n \"type\": \"module\",\n \"version\": \"1.7.9\",\n \"description\": \"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.\",\n \"keywords\": [\n \"database client\",\n \"database gui\",\n \"database browser\",\n \"sql client\",\n \"sql editor\",\n \"query tool\",\n \"table editor\",\n \"data editor\",\n \"postgres\",\n \"postgresql\",\n \"postgresql client\",\n \"postgresql gui\",\n \"pgadmin alternative\",\n \"mysql\",\n \"mysql client\",\n \"ai sql\",\n \"er diagram\",\n \"database management\",\n \"database studio\"\n ],\n \"author\": \"Hüsam 🥑 <devhsmq@gmail.com>\",\n \"homepage\": \"https://dbstudio.sh\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/husamql3/db-studio.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/husamql3/db-studio/issues\"\n },\n \"license\": \"MIT\",\n \"bin\": {\n \"db-studio\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"NODE_ENV=development tsx watch src/index.ts\",\n \"build\": \"tsup --minify --sourcemap\",\n \"prepack\": \"cd ../core && bun run build && cd ../server && bun run build\",\n \"start\": \"node dist/index.js\",\n \"check\": \"biome check --write --unsafe\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.0.1\",\n \"@hono/node-server\": \"^1.19.7\",\n \"@hono/zod-validator\": \"^0.7.6\",\n \"commander\": \"^14.0.3\",\n \"dotenv\": \"^17.3.1\",\n \"hono\": \"^4.10.4\",\n \"mongodb\": \"^7.1.1\",\n \"mssql\": \"^12.2.0\",\n \"mysql2\": \"^3.18.2\",\n \"pg\": \"^8.13.1\",\n \"picocolors\": \"^1.1.1\",\n \"xlsx\": \"^0.18.5\",\n \"zod\": \"^4.2.1\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.2.6\",\n \"@types/node\": \"^25.6.0\",\n \"@types/pg\": \"^8.16.0\",\n \"@types/mssql\": \"^12.3.0\",\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"shared\": \"workspace:*\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.7.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.0.17\"\n }\n}\n"],"mappings":"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","names":["init_chat","__esmMin","init_column_types_mysql","__esmMin","init_column_types_pgsql","__esmMin","nodeEnv","DEFAULTS","init_defaults","__esmMin","init_links","__esmMin","META","init_meta","__esmMin","init_proxy_limits","__esmMin","init_constants","__esmMin","init_chat","init_column_types_mysql","init_column_types_pgsql","init_defaults","init_links","init_meta","init_proxy_limits","z","databaseSchema","DATABASE_TYPES","databaseTypeSchema","currentDatabaseSchema","databaseTypeParamSchema","tableNameSchema","init_database_types","__esmMin","z","addColumnSchema","addColumnParamsSchema","init_add_column_types","__esmMin","init_database_types","databaseSchema","tableNameSchema","z","addRecordSchema","init_add_record_types","__esmMin","z","deleteColumnQuerySchema","deleteColumnParamSchema","deleteColumnParamsSchema","deleteColumnSuccessResponseSchema","init_delete_column_types","__esmMin","init_database_types","databaseSchema","val","z","alterColumnSchema","alterColumnParamsSchema","init_alter_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","init_api_response_types","__esmMin","z","bulkInsertRecordsSchema","init_bulk_insert_records_type","__esmMin","z","messagePart","chatSchema","init_chat_types","__esmMin","init_database_types","databaseSchema","init_cmd_args_types","__esmMin","z","dataTypes","dataTypesSchema","DataTypes","standardizedDataTypes","standardizedDataTypeSchema","columnInfoSchema","init_column_info_types","__esmMin","mapPostgresToDataType","pgType","normalized","DataTypes","standardizeDataTypeLabel","StandardizedDataType","mapMysqlToDataType","mysqlDataType","columnType","fullType","standardizeMysqlDataTypeLabel","mapMssqlToDataType","mssqlDataType","standardizeMssqlDataTypeLabel","init_column_type","__esmMin","init_column_info_types","z","FOREIGN_KEY_ACTIONS","foreignKeyActionSchema","fieldDataSchema","foreignKeyDataSchema","createTableSchema","init_create_table_types","__esmMin","z","databaseInfoSchema","databaseListSchema","connectionInfoSchema","init_database_list_types","__esmMin","init_database_types","databaseTypeSchema","init_database_schema_type","__esmMin","z","deleteRecordSchema","init_delete_record_types","__esmMin","z","deleteTableQuerySchema","init_delete_table_types","__esmMin","init_database_types","databaseSchema","val","z","executeQuerySchema","init_execute_query_types","__esmMin","z","FORMAT_TYPES","exportTableSchema","init_export_table_types","__esmMin","init_database_types","databaseSchema","init_rate_limit_response_type","__esmMin","z","renameColumnSchema","renameColumnParamsSchema","init_rename_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","z","filterSchema","sortDirections","sortSchema","tableDataMetaSchema","tableDataResultSchema","tableDataQuerySchema","init_table_data_types","__esmMin","init_database_types","databaseSchema","val","parsed","z","tableInfoSchema","init_table_info_type","__esmMin","z","tableSchemaResultSchema","init_table_schema_types","__esmMin","z","updateRecordsSchema","init_update_recors_types","__esmMin","init_types","__esmMin","init_add_column_types","init_add_record_types","init_alter_column_types","init_api_response_types","init_bulk_insert_records_type","init_chat_types","init_cmd_args_types","init_column_type","init_column_info_types","init_create_table_types","init_database_types","init_database_list_types","init_database_schema_type","init_delete_column_types","init_delete_record_types","init_delete_table_types","init_execute_query_types","init_export_table_types","init_rate_limit_response_type","init_rename_column_types","init_table_data_types","init_table_info_type","init_table_schema_types","init_update_recors_types","HTTPException","DatabaseError","ZodError","handleError","e","c","issue","mysqlError","validationHook","init_error_handler","__esmMin","result","db_manager_exports","__export","coerceObjectId","getDbPool","getDbType","getMongoClient","getMongoDb","getMongoDbName","getMssqlPool","getMysqlPool","isValidObjectId","MongoClient","ObjectId","mssql","createMysqlPool","Pool","DatabaseManager","databaseManager","init_db_manager","__esmMin","url","protocol","databaseUrl","error","database","connectionString","poolConfig","pool","err","dbName","config","nextClient","pgClosePromises","mysqlClosePromises","mssqlClosePromises","value","HTTPException","getMongoTablesList","db","mongoDb","getMongoDb","collections","results","collection","name","rowCount","getMongoTableColumns","tableName","documents","SAMPLE_LIMIT","totalDocs","columnMap","ensureColumn","columnName","value","dataType","inferDataType","entry","doc","key","meta","mapDataTypeLabel","getMongoTableData","cursor","limit","direction","sort","order","filters","filterObject","buildMongoFilters","sortObject","buildMongoSort","safeLimit","decodedCursor","decodeCursor","offset","skip","total","rows","normalizedRows","row","normalizeValue","nextOffset","prevOffset","encodeCursor","createMongoCollection","tableData","fields","properties","required","field","bsonType","mapMongoBsonType","MONGO_BSON_TYPES","deleteMongoColumn","exportMongoTableData","normalized","normalizeMongoDocument","buildMongoSortForQuery","toMongoId","canCoerceObjectId","init_tables_dao","__esmMin","init_db_manager","rawType","parsed","item","entries","k","v","andConditions","escapeRegex","parseValue","raw","trimmed","asNumber","isValidObjectId","coerceObjectId","filter","op","sortEntries","s","getMongoDatabaseSchema","db","options","includeSampleData","maxTables","mongoDb","getMongoDb","collections","tablePromises","collection","name","columns","getMongoTableColumns","table","convertColumn","normalized","row","normalizeMongoDocument","key","value","init_schema_dao","__esmMin","init_db_manager","init_tables_dao","col","Pool","dbInstance","getPool","db","init_db","__esmMin","err","error","_target","prop","HTTPException","getTableColumns","tableName","db","pool","getDbPool","query","rows","parsedEnumValues","mapPostgresToDataType","standardizeDataTypeLabel","init_table_columns_dao","__esmMin","init_types","init_db_manager","getTableNames","db","pool","getDbPool","query","rows","r","getTableDescription","tableName","client","getSampleData","convertColumnInfo","col","column","extractRelationships","tables","relationships","table","toTable","toColumn","getDatabaseSchema","options","getDbType","getMongoDatabaseSchema","includeSampleData","includeDescriptions","tablePromises","columns","description","sampleData","getTableColumns","row","key","value","error","getDetailedSchema","init_table_details_schema","__esmMin","init_schema_dao","init_db","init_db_manager","init_table_columns_dao","generateSystemPrompt","schema","dbTypeLower","dbTypeLabel","formatSchemaForPrompt","output","table","col","pkIndicator","fkIndicator","nullable","rel","init_system_prompt_generator","__esmMin","zValidator","Hono","chatRoutes","init_chat_routes","__esmMin","init_constants","init_types","init_table_details_schema","init_system_prompt_generator","c","proxyResponse","DEFAULTS","data","chatSchema","messages","db","conversationId","schema","getDetailedSchema","systemPrompt","generateSystemPrompt","payload","errorData","readable","writable","HTTPException","addRecord","db","params","tableName","data","pool","getDbPool","columns","values","placeholders","_","index","columnNames","col","query","result","init_add_record_dao","__esmMin","init_db_manager","HTTPException","bulkInsertRecords","init_bulk_insert_records_dao","__esmMin","init_db_manager","tableName","records","db","client","getDbPool","columns","columnNames","col","successCount","failureCount","errors","i","record","values","placeholders","_","index","insertSQL","error","createTable","tableData","db","tableName","fields","foreignKeys","pool","getDbPool","columnDefinitions","field","columnDef","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_dao","__esmMin","init_db_manager","parseDatabaseUrl","databaseUrl","url","protocol","defaultPort","init_parse_database_url","__esmMin","HTTPException","getDatabasesList","pool","getDbPool","query","rows","getCurrentDatabase","getDatabaseConnectionInfo","result","connectionInfoSchema","urlDefaults","parseDatabaseUrl","init_database_list_dao","__esmMin","init_types","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","cascade","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","dropColumnSQL","rowCount","init_delete_column_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","constraintsByTable","constraint","key","pkValues","pk","_tableColumn","constraints","placeholders","_","i","relatedQuery","relatedResult","deleteRecords","pkColumn","query","result","error","forceDeleteRecords","totalRelatedDeleted","deletedTables","deleteRelatedRecursively","targetTable","targetColumn","values","nestedFks","nestedFk","nestedPlaceholders","selectQuery","nestedValues","deletePlaceholders","deleteQuery","deleteResult","init_delete_records_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedQuery","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableExistsQuery","tableRows","rowCount","dropTableSQL","error","init_delete_table_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getDbPool","rows","init_export_table_dao","__esmMin","init_db_manager","HTTPException","bulkInsertRecords","init_bulk_insert_records_mongo_dao","__esmMin","init_db_manager","init_tables_dao","tableName","records","db","collection","getMongoDb","docs","record","normalized","normalizeMongoDocument","result","error","HTTPException","getMongoDatabasesList","databases","getMongoClient","db","formatBytes","getMongoCurrentDatabase","getMongoDbName","getMongoConnectionInfo","admin","urlDefaults","parseDatabaseUrl","serverStatus","init_database_list_dao","__esmMin","init_db_manager","init_parse_database_url","bytes","units","value","unitIndex","HTTPException","normalizeIdFilter","executeMongoQuery","init_query_dao","__esmMin","init_db_manager","init_tables_dao","filter","toMongoId","obj","val","query","db","payload","collection","getMongoDb","startTime","rows","rowCount","message","cursor","sort","buildMongoSortForQuery","pipeline","doc","docs","result","duration","normalizedRows","row","normalizeMongoDocument","HTTPException","addMongoRecord","db","params","tableName","data","collection","getMongoDb","payload","normalizeMongoDocument","updateMongoRecords","updates","primaryKey","totalUpdated","pkField","updatesByRow","update","pkValue","updateSet","queryValue","canCoerceObjectId","toMongoId","result","deleteMongoRecords","primaryKeys","pkColumn","pkValues","pk","forceDeleteMongoRecords","init_records_dao","__esmMin","init_db_manager","init_tables_dao","HTTPException","getTableSchema","tableName","db","mongoDb","getMongoDb","collection","docs","SAMPLE_LIMIT","totalDocs","fieldTypes","fieldPresence","doc","key","value","bsonType","inferBsonType","properties","required","field","types","presence","isRequired","typeList","t","isNullable","schema","init_table_schema_mongo_dao","__esmMin","init_db_manager","bson","HTTPException","parseCheckConstraintValues","checkClause","matches","m","getTableColumns","tableName","db","pool","getMssqlPool","result","checkResult","checkEnumMap","row","values","r","dataType","enumValues","mapMssqlToDataType","standardizeMssqlDataTypeLabel","init_table_columns_mssql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMssqlPool","tableColumns","getTableColumns","booleanColumns","col","identityResult","identityColumns","r","columns","values","value","columnNames","paramNames","_col","idx","query","request","result","init_add_record_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","tableName","records","db","transaction","getMssqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","request","values","value","paramNames","_","idx","_col","insertSQL","error","formatMssqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMssql","isArray","normalized","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMssqlPool","columnDefinitions","field","mappedType","columnDef","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mssql_dao","__esmMin","init_db_manager","HTTPException","getDatabasesList","result","getMssqlPool","getCurrentDatabase","getDatabaseConnectionInfo","info","urlDefaults","parseDatabaseUrl","init_database_list_mssql_dao","__esmMin","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMssqlPool","tableCheckResult","columnCheckResult","init_delete_column_mssql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getMssqlPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","request","value","idx","paramList","_","relatedResult","deleteRecords","pkColumn","transaction","result","error","MSSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","selectRequest","val","selectParamList","nestedValues","deleteRequest","deleteParamList","deleteResult","mainRequest","mainParamList","init_delete_records_mssql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getMssqlPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableCheckResult","rowCount","fk","error","MSSQL_FK_DEPENDENCY","init_delete_table_mssql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","result","getMssqlPool","init_export_table_mssql_dao","__esmMin","init_db_manager","HTTPException","executeQuery","init_query_mssql_dao","__esmMin","init_db_manager","query","db","pool","getMssqlPool","cleanedQuery","startTime","result","duration","rows","getTablesList","db","pool","getMssqlPool","result","table","countRow","init_table_list_mssql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMssqlPool","tableCheckResult","schemaResult","columns","col","columnDef","init_table_schema_mssql_dao","__esmMin","init_db_manager","getTableData","init_tables_data_mssql_dao","__esmMin","init_db_manager","tableName","cursor","limit","direction","sort","order","filters","db","pool","getMssqlPool","page","offset","sortClause","s","countResult","totalRows","rows","hasMore","nextCursor","prevCursor","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMssqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","transaction","totalUpdated","rowUpdates","setClauses","u","idx","request","value","query","result","error","init_update_records_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","HTTPException","parseMysqlEnumValues","columnType","match","v","getTableColumns","tableName","db","pool","getMysqlPool","query","rows","dataType","enumValues","mapMysqlToDataType","standardizeMysqlDataTypeLabel","init_table_columns_mysql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","columns","values","value","index","columnName","placeholders","columnNames","query","result","init_add_record_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","tableName","records","db","connection","getMysqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","values","value","placeholders","insertSQL","error","formatMysqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMysql","isArray","normalized","buildMysqlColumnDefinition","field","options","mappedType","columnDef","init_mysql_column_utils","__esmMin","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMysqlPool","columnDefinitions","field","buildMysqlColumnDefinition","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","getDatabasesList","pool","getMysqlPool","rows","getCurrentDatabase","getDatabaseConnectionInfo","infoRows","connRows","info","activeConnections","urlDefaults","parseDatabaseUrl","init_database_list_mysql_dao","__esmMin","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMysqlPool","tableRows","columnRows","result","init_delete_column_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","placeholders","relatedRows","deleteRecords","pkColumn","connection","result","error","MYSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","nestedPlaceholders","selectRows","nestedValues","deletePlaceholders","deleteResult","mainPlaceholders","init_delete_records_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","constraint","relatedRows","getTableRowCount","deleteTable","params","cascade","tableRows","rowCount","connection","error","mysqlError","MYSQL_FK_DEPENDENCY","MYSQL_FK_ROW_REFERENCED","init_delete_table_mysql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getMysqlPool","rows","init_export_table_mysql_dao","__esmMin","init_db_manager","HTTPException","executeQuery","init_query_mysql_dao","__esmMin","init_db_manager","query","db","pool","getMysqlPool","cleanedQuery","startTime","result","fields","duration","rows","f","dmlResult","getTablesList","db","pool","getMysqlPool","tablesQuery","tables","table","countRows","countRow","init_table_list_mysql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMysqlPool","tableRows","rows","row","createTableSql","init_table_schema_mysql_dao","__esmMin","init_db_manager","buildWhereClauseMysql","filters","conditions","values","filter","columnName","buildSortClauseMysql","sorts","order","sort","buildCursorWhereClauseMysql","cursorData","direction","sortDirection","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","operator","init_build_clauses_mysql","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_mysql_dao","__esmMin","init_db_manager","init_build_clauses_mysql","data","cursor","pool","tableName","rows","row","limit","direction","sort","order","filters","db","getMysqlPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClauseMysql","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClauseMysql","combinedWhereClause","sortClause","buildSortClauseMysql","effectiveSortClause","col","countRows","totalRows","fetchLimit","dataRows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","connection","totalUpdated","rowUpdates","setClauses","u","values","query","result","error","init_update_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","executeQuery","init_query_dao","__esmMin","init_db_manager","query","db","pool","getDbPool","cleanedQuery","startTime","result","duration","field","getTablesList","db","pool","getDbPool","tablesQuery","tables","table","safeSchemaName","quoteIdentifier","safeTableName","countQuery","rows","init_table_list_dao","__esmMin","init_db_manager","identifier","HTTPException","getTableSchema","tableName","db","pool","getDbPool","tableExistsQuery","tableExistsRows","columnsQuery","columns","constraintsQuery","constraints","indexesQuery","indexes","schemaLines","columnDefs","col","colDef","formatDataType","constraintMap","constraint","existing","constraintDefs","constraintName","constraintColumns","firstConstraint","columnNames","c","foreignTable","foreignColumn","allDefs","index","data_type","udt_name","character_maximum_length","numeric_precision","numeric_scale","init_table_schema_dao","__esmMin","init_db_manager","buildWhereClause","filters","conditions","values","filter","paramIndex","columnName","buildSortClause","sorts","order","sort","buildCursorWhereClause","cursorData","direction","sortDirection","startParamIndex","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","_","i","operator","init_build_clauses","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_dao","__esmMin","init_db_manager","init_build_clauses","data","cursor","pool","tableName","quotedTableName","row","limit","direction","sort","order","filters","db","getDbPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClause","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClause","combinedWhereClause","sortClause","buildSortClause","effectiveSortClause","col","countRes","totalRows","limitParamIndex","dataRes","rows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getDbPool","updatesByRow","update","pkValue","totalUpdated","rowUpdates","setClauses","u","index","values","query","result","error","init_update_records_dao","__esmMin","init_db_manager","getDaoFactory","dbType","daoRegistry","init_dao_factory","__esmMin","init_add_record_dao","init_bulk_insert_records_dao","init_create_table_dao","init_database_list_dao","init_delete_column_dao","init_delete_records_dao","init_delete_table_dao","init_export_table_dao","init_bulk_insert_records_mongo_dao","init_query_dao","init_records_dao","init_table_schema_mongo_dao","init_tables_dao","init_add_record_mssql_dao","init_bulk_insert_records_mssql_dao","init_create_table_mssql_dao","init_database_list_mssql_dao","init_delete_column_mssql_dao","init_delete_records_mssql_dao","init_delete_table_mssql_dao","init_export_table_mssql_dao","init_query_mssql_dao","init_table_columns_mssql_dao","init_table_list_mssql_dao","init_table_schema_mssql_dao","init_tables_data_mssql_dao","init_update_records_mssql_dao","init_add_record_mysql_dao","init_bulk_insert_records_mysql_dao","init_create_table_mysql_dao","init_database_list_mysql_dao","init_delete_column_mysql_dao","init_delete_records_mysql_dao","init_delete_table_mysql_dao","init_export_table_mysql_dao","init_query_mysql_dao","init_table_columns_mysql_dao","init_table_list_mysql_dao","init_table_schema_mysql_dao","init_tables_data_mysql_dao","init_update_records_mysql_dao","init_table_columns_dao","init_table_list_dao","init_table_schema_dao","init_tables_data_dao","init_update_records_dao","addRecord","bulkInsertRecords","createTable","getDatabasesList","getCurrentDatabase","getDatabaseConnectionInfo","deleteColumn","deleteRecords","forceDeleteRecords","deleteTable","exportTableData","executeQuery","getTableColumns","getTablesList","getTableSchema","getTableData","updateRecords","db","params","addMongoRecord","tableData","createMongoCollection","getMongoDatabasesList","getMongoCurrentDatabase","getMongoConnectionInfo","tableName","columnName","deleteMongoColumn","deleteMongoRecords","forceDeleteMongoRecords","getMongoDb","exportMongoTableData","query","executeMongoQuery","getMongoTableColumns","getMongoTablesList","getMongoTableData","updateMongoRecords","Hono","databasesRoutes","init_databases_routes","__esmMin","init_dao_factory","init_db_manager","c","dbType","getDbType","databases","getDaoFactory","current","info","zValidator","Hono","queryRoutes","init_query_routes","__esmMin","init_types","init_dao_factory","databaseSchema","executeQuerySchema","c","query","db","dbType","data","getDaoFactory","zValidator","Hono","recordsRoutes","init_records_routes","__esmMin","init_types","init_dao_factory","databaseSchema","addRecordSchema","c","db","tableName","data","dbType","dao","getDaoFactory","insertedCount","updateRecordsSchema","primaryKey","updates","updatedCount","deleteRecordSchema","primaryKeys","deletedCount","fkViolation","relatedRecords","bulkInsertRecordsSchema","records","result","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","columnDefinition","init_add_column_dao","__esmMin","init_db_manager","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","client","error","init_alter_column_dao","__esmMin","init_db_manager","HTTPException","addMongoField","tableName","columnName","columnType","defaultValue","isNullable","db","mongoDb","getMongoDb","collections","resolvedDefault","resolveDefault","existingSchema","properties","required","init_add_column_mongo_dao","__esmMin","init_db_manager","HTTPException","mongoRenameColumn","tableName","columnName","newColumnName","db","mongoDb","getMongoDb","mongoAlterColumn","columnType","isNullable","collections","existingSchema","properties","required","bsonType","reqIndex","init_alter_column_mongo_dao","__esmMin","init_db_manager","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getMysqlPool","tableRows","columnRows","columnDefinition","buildMysqlColumnDefinition","init_add_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getMysqlPool","tableRows","columnRows","columnRow","columnDefinition","buildMysqlColumnDefinition","init_alter_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getMysqlPool","tableRows","currentColumnRows","nextColumnRows","init_rename_column_mysql_dao","__esmMin","init_db_manager","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","currentColumnRows","nextColumnRows","init_rename_column_dao","__esmMin","init_db_manager","utils","write","getExportFile","cols","rows","format","tableName","jsonContent","data","row","col","worksheet","csvContent","workbook","buffer","init_get_export_file","__esmMin","zValidator","Hono","tablesRoutes","init_tables_routes","__esmMin","init_types","init_add_column_dao","init_alter_column_dao","init_dao_factory","init_add_column_mongo_dao","init_alter_column_mongo_dao","init_add_column_mysql_dao","init_alter_column_mysql_dao","init_rename_column_mysql_dao","init_rename_column_dao","init_get_export_file","databaseSchema","c","db","dbType","tablesList","getDaoFactory","createTableSchema","body","deleteTableQuerySchema","tableNameSchema","cascade","tableName","result","deleteColumnQuerySchema","deleteColumnParamSchema","columnName","dao","deletedCount","addColumnSchema","addColumn","addMongoField","renameColumnSchema","renameColumn","mongoRenameColumn","alterColumnSchema","alterColumn","mongoAlterColumn","columns","schema","tableDataQuerySchema","cursor","limit","direction","sort","order","filters","tableData","exportTableSchema","format","cols","rows","fileContent","getExportFile","contentType","create_server_exports","__export","createServer","path","fileURLToPath","serveStatic","zValidator","Hono","cors","logger","prettyJSON","getCoreDistPath","init_create_server","__esmMin","init_types","init_error_handler","init_chat_routes","init_databases_routes","init_query_routes","init_records_routes","init_tables_routes","__dirname","_","next","c","handleError","databasesRoutes","chatRoutes","databaseTypeParamSchema","validationHook","dbType","tablesRoutes","recordsRoutes","queryRoutes","init_constants","intro","outro","serve","color","program","args","readFile","resolve","cancel","isCancel","note","select","spinner","text","parseDotenv","color","getDatabaseUrl","env","varName","envVarName","s","choice","customPath","value","customEnvPath","content","parsed","e","error","dbUrl","access","readFile","dirname","resolve","parseDotenv","findEnvPath","startDir","dir","envPath","parent","loadEnv","env","content","err","init_meta","intro","outro","color","showHelp","META","init_constants","intro","note","outro","color","showStatus","env","databaseUrl","varName","intro","color","envVarName","DEFAULTS","foundUrl","ENV","loadEnv","outro","note","intro","outro","color","package_default","showVersion","intro","color","outro","package_default","main","env","port","databaseUrl","varName","status","help","version","args","showHelp","showVersion","showStatus","intro","color","PORT","DEFAULTS","VAR_NAME","ENV","loadEnv","DATABASE_URL","getDatabaseUrl","createServer","app","serve","outro","err"]}
|
|
1
|
+
{"version":3,"sources":["../../shared/src/constants/chat.ts","../../shared/src/constants/column-types-mysql.ts","../../shared/src/constants/column-types-pgsql.ts","../../shared/src/constants/defaults.ts","../../shared/src/constants/links.ts","../../shared/src/constants/meta.ts","../../shared/src/constants/proxy-limits.ts","../../shared/src/constants/index.ts","../../shared/src/types/database.types.ts","../../shared/src/types/add-column.types.ts","../../shared/src/types/add-record.types.ts","../../shared/src/types/delete-column.types.ts","../../shared/src/types/alter-column.types.ts","../../shared/src/types/api-response.types.ts","../../shared/src/types/bulk-insert-records.type.ts","../../shared/src/types/chat.types.ts","../../shared/src/types/cmd-args.types.ts","../../shared/src/types/column-info.types.ts","../../shared/src/types/column.type.ts","../../shared/src/types/create-table.types.ts","../../shared/src/types/database-list.types.ts","../../shared/src/types/database-schema.type.ts","../../shared/src/types/delete-record.types.ts","../../shared/src/types/delete-table.types.ts","../../shared/src/types/execute-query.types.ts","../../shared/src/types/export-table.types.ts","../../shared/src/types/rate-limit-response.type.ts","../../shared/src/types/rename-column.types.ts","../../shared/src/types/table-data.types.ts","../../shared/src/types/table-info.type.ts","../../shared/src/types/table-schema.types.ts","../../shared/src/types/update-recors.types.ts","../../shared/src/types/index.ts","../src/middlewares/error-handler.ts","../src/db-manager.ts","../src/dao/mongo/mongo.utils.ts","../src/dao/mongo/table-columns.mongo.dao.ts","../src/dao/mongo/schema.dao.ts","../src/db.ts","../src/dao/table-columns.dao.ts","../src/dao/table-details-schema.ts","../src/utils/system-prompt-generator.ts","../src/routes/chat.routes.ts","../src/dao/add-record.dao.ts","../src/dao/bulk-insert-records.dao.ts","../src/dao/create-table.dao.ts","../src/utils/parse-database-url.ts","../src/dao/database-list.dao.ts","../src/dao/delete-column.dao.ts","../src/dao/delete-records.dao.ts","../src/dao/delete-table.dao.ts","../src/dao/export-table.dao.ts","../src/dao/mongo/add-record.mongo.dao.ts","../src/dao/mongo/bulk-insert-records.mongo.dao.ts","../src/dao/mongo/create-table.mongo.dao.ts","../src/dao/mongo/database-list.dao.ts","../src/dao/mongo/database-list.mongo.dao.ts","../src/dao/mongo/delete-column.mongo.dao.ts","../src/dao/mongo/delete-records.mongo.dao.ts","../src/dao/mongo/delete-table.mongo.dao.ts","../src/dao/mongo/export-table.mongo.dao.ts","../src/dao/mongo/query.dao.ts","../src/dao/mongo/query.mongo.dao.ts","../src/dao/mongo/table-list.mongo.dao.ts","../src/dao/mongo/table-schema.mongo.dao.ts","../src/dao/mongo/tables-data.mongo.dao.ts","../src/dao/mongo/update-records.mongo.dao.ts","../src/dao/mssql/table-columns.mssql.dao.ts","../src/dao/mssql/add-record.mssql.dao.ts","../src/dao/mssql/bulk-insert-records.mssql.dao.ts","../src/dao/mssql/create-table.mssql.dao.ts","../src/dao/mssql/database-list.mssql.dao.ts","../src/dao/mssql/delete-column.mssql.dao.ts","../src/dao/mssql/delete-records.mssql.dao.ts","../src/dao/mssql/delete-table.mssql.dao.ts","../src/dao/mssql/export-table.mssql.dao.ts","../src/dao/mssql/query.mssql.dao.ts","../src/dao/mssql/table-list.mssql.dao.ts","../src/dao/mssql/table-schema.mssql.dao.ts","../src/dao/mssql/tables-data.mssql.dao.ts","../src/dao/mssql/update-records.mssql.dao.ts","../src/dao/mysql/table-columns.mysql.dao.ts","../src/dao/mysql/add-record.mysql.dao.ts","../src/dao/mysql/bulk-insert-records.mysql.dao.ts","../src/dao/mysql/mysql-column.utils.ts","../src/dao/mysql/create-table.mysql.dao.ts","../src/dao/mysql/database-list.mysql.dao.ts","../src/dao/mysql/delete-column.mysql.dao.ts","../src/dao/mysql/delete-records.mysql.dao.ts","../src/dao/mysql/delete-table.mysql.dao.ts","../src/dao/mysql/export-table.mysql.dao.ts","../src/dao/mysql/query.mysql.dao.ts","../src/dao/mysql/table-list.mysql.dao.ts","../src/dao/mysql/table-schema.mysql.dao.ts","../src/utils/build-clauses-mysql.ts","../src/dao/mysql/tables-data.mysql.dao.ts","../src/dao/mysql/update-records.mysql.dao.ts","../src/dao/query.dao.ts","../src/dao/table-list.dao.ts","../src/dao/table-schema.dao.ts","../src/utils/build-clauses.ts","../src/dao/tables-data.dao.ts","../src/dao/update-records.dao.ts","../src/dao/dao-factory.ts","../src/routes/databases.routes.ts","../src/routes/query.routes.ts","../src/routes/records.routes.ts","../src/dao/add-column.dao.ts","../src/dao/alter-column.dao.ts","../src/dao/mongo/add-column.mongo.dao.ts","../src/dao/mongo/alter-column.mongo.dao.ts","../src/dao/mysql/add-column.mysql.dao.ts","../src/dao/mysql/alter-column.mysql.dao.ts","../src/dao/mysql/rename-column.mysql.dao.ts","../src/dao/rename-column.dao.ts","../src/utils/get-export-file.ts","../src/routes/tables.routes.ts","../src/utils/create-server.ts","../src/index.ts","../src/cmd/args.ts","../src/cmd/get-db-url.ts","../src/cmd/load-env.ts","../src/cmd/show-help.ts","../src/cmd/show-status.ts","../src/cmd/show-version.ts","../package.json"],"sourcesContent":["export const CHAT_SUGGESTIONS = [\n\t\"Show me all tables in my database\",\n\t\"What columns are in the users table?\",\n\t\"Write a query to find all active users\",\n\t\"How many orders were placed last month?\",\n\t\"Find top 5 customers by total spend\",\n\t\"Write a JOIN between users and orders\",\n\t\"Users who haven't made any purchase yet\",\n\t\"Generate monthly revenue summary query\",\n\t\"Suggest useful indexes for better performance\",\n\t\"Show schema of the products / inventory table\",\n\t\"Latest 20 orders with customer names\",\n\t\"Help me write a safe UPDATE query\",\n];\n\n// const MODEL_LIST = [\n// \t{\n// \t\tid: \"gpt-4o\",\n// \t\tname: \"GPT-4o\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"gpt-4o-mini\",\n// \t\tname: \"GPT-4o Mini\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"claude-opus-4-20250514\",\n// \t\tname: \"Claude 4 Opus\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"claude-sonnet-4-20250514\",\n// \t\tname: \"Claude 4 Sonnet\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"gemini-2.0-flash-exp\",\n// \t\tname: \"Gemini 2.0 Flash\",\n// \t\tchef: \"Google\",\n// \t\tchefSlug: \"google\",\n// \t},\n// ];\n","export const MYSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"tinyint\", label: \"tinyint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"mediumint\", label: \"mediumint\" },\n\t{ value: \"int\", label: \"int\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"decimal\", label: \"decimal\" },\n\t{ value: \"float\", label: \"float\" },\n\t{ value: \"double\", label: \"double\" },\n\t{ value: \"bit\", label: \"bit\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"char\", label: \"char\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"tinytext\", label: \"tinytext\" },\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"mediumtext\", label: \"mediumtext\" },\n\t{ value: \"longtext\", label: \"longtext\" },\n\t// Binary\n\t{ value: \"binary\", label: \"binary\" },\n\t{ value: \"varbinary\", label: \"varbinary\" },\n\t{ value: \"tinyblob\", label: \"tinyblob\" },\n\t{ value: \"blob\", label: \"blob\" },\n\t{ value: \"mediumblob\", label: \"mediumblob\" },\n\t{ value: \"longblob\", label: \"longblob\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"datetime\", label: \"datetime\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"year\", label: \"year\" },\n\t// Complex\n\t{ value: \"enum\", label: \"enum\" },\n\t{ value: \"set\", label: \"set\" },\n] as const;\n\nexport type MysqlColumnType = (typeof MYSQL_COLUMN_TYPES)[number][\"value\"];\n","export const PGSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"integer\", label: \"integer\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"numeric\", label: \"numeric\" },\n\t{ value: \"real\", label: \"real\" },\n\t{ value: \"double precision\", label: \"double precision\" },\n\t{ value: \"money\", label: \"money\" },\n\t{ value: \"serial\", label: \"serial\" },\n\t{ value: \"bigserial\", label: \"bigserial\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"char\", label: \"char\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t{ value: \"jsonb\", label: \"jsonb\" },\n\t{ value: \"xml\", label: \"xml\" },\n\t// UUID\n\t{ value: \"uuid\", label: \"uuid\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"timestamptz\", label: \"timestamptz\" },\n\t{ value: \"interval\", label: \"interval\" },\n\t// Binary\n\t{ value: \"bytea\", label: \"bytea\" },\n\t// Network\n\t{ value: \"inet\", label: \"inet\" },\n\t{ value: \"cidr\", label: \"cidr\" },\n\t{ value: \"macaddr\", label: \"macaddr\" },\n\t{ value: \"macaddr8\", label: \"macaddr8\" },\n\t// Geometric\n\t{ value: \"point\", label: \"point\" },\n\t{ value: \"line\", label: \"line\" },\n\t{ value: \"polygon\", label: \"polygon\" },\n] as const;\n\nexport type PgsqlColumnType = (typeof PGSQL_COLUMN_TYPES)[number][\"value\"];\n","const nodeEnv = (\n\tglobalThis as typeof globalThis & {\n\t\tprocess?: {\n\t\t\tenv?: {\n\t\t\t\tNODE_ENV?: string;\n\t\t\t};\n\t\t};\n\t}\n).process?.env?.NODE_ENV;\n\nexport const DEFAULTS = {\n\tPORT: 3333,\n\tENV: \".env\",\n\tVAR_NAME: \"DATABASE_URL\",\n\tBASE_URL: \"http://localhost:3333\",\n\tIS_DEV: nodeEnv === \"development\",\n\tPROXY_URL:\n\t\tnodeEnv === \"development\"\n\t\t\t? \"http://localhost:8787\"\n\t\t\t: \"https://db-studio-proxy.husamql3.workers.dev\",\n};\n","export const HEADER_LINKS = [\n\t{ label: \"Home\", href: \"/\" },\n\t{ label: \"Roadmap\", href: \"/roadmap\" },\n\t{ label: \"Docs\", href: \"/docs/$\" },\n\t{ label: \"Changelog\", href: \"/changelog\" },\n];\n","export const META = {\n\t//* author\n\tAUTHOR: \"Hüsam 🥑 <devhsmq@gmail.com>\",\n\tAUTHOR_NAME: \"Hüsam\",\n\tAUTHOR_AVATAR: \"/avocado.png\",\n\tAUTHOR_USERNAME: \"husamql3\",\n\tAUTHOR_GITHUB_LINK: \"https://github.com/husamql3\",\n\t//* site\n\tSITE_DESCRIPTION: \"The modern pgAdmin alternative that works with every database.\",\n\tSITE_KEYWORDS: [\n\t\t\"pgadmin alternative\",\n\t\t\"database client\",\n\t\t\"database gui\",\n\t\t\"database browser\",\n\t\t\"sql editor\",\n\t\t\"postgresql client\",\n\t\t\"mysql client\",\n\t\t\"table editor\",\n\t\t\"ai sql\",\n\t\t\"er diagram\",\n\t],\n\tSITE_TITLE: \"DB Studio\",\n\tSITE_NAME: \"dbstudio.sh\",\n\tSITE_URL: \"https://dbstudio.sh\",\n\tSITE_X_LINK: \"https://x.com/dbstudio_sh\",\n\tSITE_GITHUB_LINK: \"https://github.com/husamql3/db-studio\",\n\tSITE_GITHUB_NEW_ISSUE_LINK: \"https://github.com/husamql3/db-studio/issues/new/choose\",\n\tSITE_DOCS_LINK: \"https://dbstudio.sh/docs\",\n\tSITE_CHANGELOG_LINK: \"https://dbstudio.sh/changelog\",\n\tSITE_ROADMAP_LINK: \"https://dbstudio.sh/roadmap\",\n\tSITE_IMAGE: \"https://dbstudio.sh/og-image.png\",\n\tSITE_IMAGE_WIDTH: \"1200\",\n\tSITE_IMAGE_HEIGHT: \"630\",\n\tSITE_IMAGE_ALT: \"dbstudio.sh – Modern database management studio\",\n\tSITE_COLOR: \"#1447e6\",\n};\n","export const ONE_DAY = 24 * 60 * 60 * 1000;\nexport const LIMIT = 3;\n","export * from \"./chat.js\";\nexport * from \"./column-types-mysql.js\";\nexport * from \"./column-types-pgsql.js\";\nexport * from \"./defaults.js\";\nexport * from \"./links.js\";\nexport * from \"./meta.js\";\nexport * from \"./proxy-limits.js\";\n","import { z } from \"zod\";\n\nexport const databaseSchema = z.object({\n\tdb: z.string(\"Database name is required\"),\n});\n\nexport type DatabaseSchemaType = z.infer<typeof databaseSchema>;\n\nexport const DATABASE_TYPES = [\"pg\", \"mysql\", \"mssql\", \"mongodb\"] as const;\n\nexport const databaseTypeSchema = z.enum(DATABASE_TYPES, {\n\tmessage: \"Invalid database type\",\n});\nexport type DatabaseTypeSchema = z.infer<typeof databaseTypeSchema>;\n\nexport const currentDatabaseSchema = databaseSchema.extend({\n\tdbType: databaseTypeSchema,\n});\nexport type CurrentDatabaseSchemaType = z.infer<typeof currentDatabaseSchema>;\n\nexport const databaseTypeParamSchema = z.object({\n\tdbType: databaseTypeSchema,\n});\n\nexport const tableNameSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n});\n\nexport type TableNameSchemaType = z.infer<typeof tableNameSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema, tableNameSchema } from \"./database.types\";\n\nexport const addColumnSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\n\nexport type AddColumnSchemaType = z.infer<typeof addColumnSchema>;\n\nexport const addColumnParamSchema = tableNameSchema;\n\nexport type AddColumnParamSchemaType = z.infer<typeof addColumnParamSchema>;\n\nexport const addColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: tableNameSchema.shape.tableName,\n\tcolumnName: addColumnSchema.shape.columnName,\n\tcolumnType: addColumnSchema.shape.columnType,\n\tdefaultValue: addColumnSchema.shape.defaultValue,\n\tisPrimaryKey: addColumnSchema.shape.isPrimaryKey,\n\tisNullable: addColumnSchema.shape.isNullable,\n\tisUnique: addColumnSchema.shape.isUnique,\n\tisIdentity: addColumnSchema.shape.isIdentity,\n\tisArray: addColumnSchema.shape.isArray,\n});\n\nexport type AddColumnParamsSchemaType = z.infer<typeof addColumnParamsSchema>;\n","import { z } from \"zod\";\n\nexport const addRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tdata: z.record(z.string(\"Column name is required\"), z.any()),\n});\n\nexport type AddRecordSchemaType = z.infer<typeof addRecordSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\n\nexport const deleteColumnQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteColumnQuerySchemaType = z.infer<typeof deleteColumnQuerySchema>;\n\nexport const deleteColumnParamSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n});\n\nexport const deleteColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcascade: z.boolean().optional(),\n});\n\nexport type DeleteColumnParamsSchemaType = z.infer<typeof deleteColumnParamsSchema>;\n\nexport const deleteColumnSuccessResponseSchema = z.object({\n\tmessage: z.string(\"Message is required\"),\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n\tdeletedCount: z.number(\"Deleted count is required\").default(0),\n});\n\nexport type DeleteColumnResponseType = z.infer<typeof deleteColumnSuccessResponseSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const alterColumnSchema = z.object({\n\tcolumnType: z.string(\"Column type is required\"),\n\tisNullable: z.boolean(),\n\tdefaultValue: z.string().nullable().optional(),\n});\n\nexport type AlterColumnSchemaType = z.infer<typeof alterColumnSchema>;\n\nexport const alterColumnParamSchema = deleteColumnParamSchema;\n\nexport type AlterColumnParamSchemaType = z.infer<typeof alterColumnParamSchema>;\n\nexport const alterColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcolumnType: alterColumnSchema.shape.columnType,\n\tisNullable: alterColumnSchema.shape.isNullable,\n\tdefaultValue: alterColumnSchema.shape.defaultValue,\n});\n\nexport type AlterColumnParamsSchemaType = z.infer<typeof alterColumnParamsSchema>;\n","/**\n * Standard API success response wrapper type\n * Used by both server and client\n */\nexport type BaseResponse<T> = {\n\tdata: T;\n\tmessage?: string;\n};\n\n/**\n * Standard API error response type\n */\nexport type ApiError = {\n\terror: string;\n\tdetails?: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport type BulkInsertRecordsParams = {\n\ttableName: string;\n\trecords: Record<string, unknown>[];\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type BulkInsertResult = {\n\tsuccess: boolean;\n\tmessage: string;\n\tsuccessCount: number;\n\tfailureCount: number;\n\terrors?: Array<{ recordIndex: number; error: string }>;\n};\n\nexport const bulkInsertRecordsSchema = z.object({\n\ttableName: z.string().min(1, \"Table name is required\"),\n\trecords: z.array(z.record(z.string(), z.any())).min(1, \"At least one record is required\"),\n});\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\n// UI message part schema (from @tanstack/ai-react)\nconst messagePart = z\n\t.object({\n\t\ttype: z.string(),\n\t\tcontent: z.string().optional(),\n\t})\n\t.passthrough();\n\n// `@tanstack/ai-react`'s `fetchServerSentEvents` adapter sends UI messages\n// with `parts` (not `content`) and wraps extra body under `data`.\nexport const chatSchema = z.object({\n\tmessages: z.array(\n\t\tz\n\t\t\t.object({\n\t\t\t\tid: z.string(),\n\t\t\t\trole: z.enum([\"user\", \"assistant\", \"system\", \"tool\"]),\n\t\t\t\tparts: z.array(messagePart),\n\t\t\t})\n\t\t\t.passthrough(),\n\t),\n\tdata: z.object({\n\t\tconversationId: z.string().optional(),\n\t\tdb: databaseSchema.shape.db,\n\t}),\n});\n","export type Args = {\n\tenv?: string;\n\tport?: string;\n\tdatabaseUrl?: string;\n\tvarName?: string;\n\tstatus?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n};\n","import { z } from \"zod\";\n\nconst dataTypes = [\"text\", \"boolean\", \"number\", \"enum\", \"json\", \"date\", \"array\"] as const;\n\nexport const dataTypesSchema = z.enum(dataTypes);\nexport type DataTypes = z.infer<typeof dataTypesSchema>;\n\nexport const DataTypes = {\n\ttext: \"text\",\n\tboolean: \"boolean\",\n\tnumber: \"number\",\n\tenum: \"enum\",\n\tjson: \"json\",\n\tdate: \"date\",\n\tarray: \"array\",\n} as const satisfies Record<DataTypes, string>;\n\nconst standardizedDataTypes = [\n\t// PostgreSQL numeric types\n\t\"int\",\n\t\"bigint\",\n\t\"smallint\",\n\t\"numeric\",\n\t\"float\",\n\t\"double\",\n\t\"money\",\n\t// MySQL numeric types\n\t\"tinyint\",\n\t\"mediumint\",\n\t\"bit\",\n\t// Boolean\n\t\"boolean\",\n\t// Text types (shared)\n\t\"text\",\n\t\"varchar\",\n\t\"char\",\n\t// MySQL text types\n\t\"tinytext\",\n\t\"mediumtext\",\n\t\"longtext\",\n\t// JSON types\n\t\"json\",\n\t\"jsonb\",\n\t\"xml\",\n\t// UUID\n\t\"uuid\",\n\t// Date/Time types (shared)\n\t\"date\",\n\t\"time\",\n\t\"timestamp\",\n\t// PostgreSQL date/time\n\t\"timestamptz\",\n\t\"interval\",\n\t// MySQL date/time\n\t\"datetime\",\n\t\"year\",\n\t// PostgreSQL binary/network/geometric types\n\t\"bytea\",\n\t\"inet\",\n\t\"cidr\",\n\t\"macaddr\",\n\t\"macaddr8\",\n\t\"point\",\n\t\"line\",\n\t\"polygon\",\n\t// MySQL binary types\n\t\"binary\",\n\t\"varbinary\",\n\t\"blob\",\n\t\"tinyblob\",\n\t\"mediumblob\",\n\t\"longblob\",\n\t// Complex types (shared)\n\t\"array\",\n\t\"enum\",\n\t// MySQL set type\n\t\"set\",\n] as const;\n\nexport const standardizedDataTypeSchema = z.enum(standardizedDataTypes);\n\nexport const columnInfoSchema = z.object({\n\tcolumnName: z.string(),\n\tdataType: dataTypesSchema,\n\tdataTypeLabel: standardizedDataTypeSchema,\n\tisNullable: z.boolean(),\n\tcolumnDefault: z.string().nullable(),\n\tisPrimaryKey: z.boolean(),\n\tisForeignKey: z.boolean(),\n\treferencedTable: z.string().nullable(),\n\treferencedColumn: z.string().nullable(),\n\tenumValues: z.array(z.string()).nullable(),\n});\n\nexport type ColumnInfoSchemaType = z.infer<typeof columnInfoSchema>;\n","import { DataTypes } from \"./column-info.types.js\";\n\n/**\n * Maps PostgreSQL data types to generic DataType enum\n */\nexport function mapPostgresToDataType(pgType: string): DataTypes {\n\tconst normalized = pgType?.toLowerCase().trim() || \"\";\n\n\t// Handle array types and date/time types\n\tif (\n\t\tnormalized.includes(\"[]\") ||\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\") ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\") ||\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int2\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\") ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"float4\" ||\n\t\tnormalized === \"double precision\" ||\n\t\tnormalized === \"float8\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\" ||\n\t\tnormalized === \"money\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\" || normalized === \"jsonb\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum types and long text types\n\tif (\n\t\tnormalized.startsWith(\"user-defined\") ||\n\t\tnormalized === \"enum\" ||\n\t\tnormalized === \"text\" ||\n\t\tnormalized === \"xml\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Short string types (varchar, char, uuid, etc.)\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\") ||\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\" ||\n\t\tnormalized === \"uuid\" ||\n\t\tnormalized === \"interval\" ||\n\t\tnormalized.startsWith(\"interval\") ||\n\t\tnormalized === \"bytea\" ||\n\t\tnormalized === \"point\" ||\n\t\tnormalized === \"line\" ||\n\t\tnormalized === \"polygon\" ||\n\t\tnormalized === \"inet\" ||\n\t\tnormalized === \"cidr\" ||\n\t\tnormalized === \"macaddr\" ||\n\t\tnormalized === \"macaddr8\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Default to short for unrecognized types\n\treturn DataTypes.text;\n}\n\n/**\n * Standardized data type labels\n */\nexport const StandardizedDataType = {\n\t// PostgreSQL numeric types\n\tint: \"int\",\n\tbigint: \"bigint\",\n\tsmallint: \"smallint\",\n\tnumeric: \"numeric\",\n\tfloat: \"float\",\n\tdouble: \"double\",\n\tmoney: \"money\",\n\t// MySQL numeric types\n\ttinyint: \"tinyint\",\n\tmediumint: \"mediumint\",\n\tbit: \"bit\",\n\t// Boolean\n\tboolean: \"boolean\",\n\t// Text types (shared)\n\ttext: \"text\",\n\tvarchar: \"varchar\",\n\tchar: \"char\",\n\t// MySQL text types\n\ttinytext: \"tinytext\",\n\tmediumtext: \"mediumtext\",\n\tlongtext: \"longtext\",\n\t// JSON types\n\tjson: \"json\",\n\tjsonb: \"jsonb\",\n\txml: \"xml\",\n\t// UUID\n\tuuid: \"uuid\",\n\t// Date/Time types (shared)\n\tdate: \"date\",\n\ttime: \"time\",\n\ttimestamp: \"timestamp\",\n\t// PostgreSQL date/time\n\ttimestamptz: \"timestamptz\",\n\tinterval: \"interval\",\n\t// MySQL date/time\n\tdatetime: \"datetime\",\n\tyear: \"year\",\n\t// PostgreSQL binary/network/geometric types\n\tbytea: \"bytea\",\n\tinet: \"inet\",\n\tcidr: \"cidr\",\n\tmacaddr: \"macaddr\",\n\tmacaddr8: \"macaddr8\",\n\tpoint: \"point\",\n\tline: \"line\",\n\tpolygon: \"polygon\",\n\t// MySQL binary types\n\tbinary: \"binary\",\n\tvarbinary: \"varbinary\",\n\tblob: \"blob\",\n\ttinyblob: \"tinyblob\",\n\tmediumblob: \"mediumblob\",\n\tlongblob: \"longblob\",\n\t// Complex types (shared)\n\tarray: \"array\",\n\tenum: \"enum\",\n\t// MySQL set type\n\tset: \"set\",\n} as const;\n\nexport type StandardizedDataType =\n\t(typeof StandardizedDataType)[keyof typeof StandardizedDataType];\n\n/**\n * Maps PostgreSQL data types to standardized display labels\n */\nexport function standardizeDataTypeLabel(\n\tpgType: string | null | undefined,\n): StandardizedDataType {\n\tif (!pgType) {\n\t\treturn StandardizedDataType.text; // Default fallback\n\t}\n\tconst normalized = pgType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\"\n\t) {\n\t\treturn StandardizedDataType.int;\n\t}\n\n\tif (\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\"\n\t) {\n\t\treturn StandardizedDataType.bigint;\n\t}\n\n\tif (normalized === \"smallint\" || normalized === \"int2\") {\n\t\treturn StandardizedDataType.smallint;\n\t}\n\n\tif (\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\")\n\t) {\n\t\treturn StandardizedDataType.numeric;\n\t}\n\n\tif (normalized === \"real\" || normalized === \"float4\") {\n\t\treturn StandardizedDataType.float;\n\t}\n\n\tif (normalized === \"double precision\" || normalized === \"float8\" || normalized === \"float\") {\n\t\treturn StandardizedDataType.double;\n\t}\n\n\tif (normalized === \"money\") {\n\t\treturn StandardizedDataType.money;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn StandardizedDataType.boolean;\n\t}\n\n\t// Text types\n\tif (normalized === \"text\") {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\")\n\t) {\n\t\treturn StandardizedDataType.varchar;\n\t}\n\n\tif (\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\"\n\t) {\n\t\treturn StandardizedDataType.char;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\") {\n\t\treturn StandardizedDataType.json;\n\t}\n\n\tif (normalized === \"jsonb\") {\n\t\treturn StandardizedDataType.jsonb;\n\t}\n\n\tif (normalized === \"xml\") {\n\t\treturn StandardizedDataType.xml;\n\t}\n\n\t// UUID\n\tif (normalized === \"uuid\") {\n\t\treturn StandardizedDataType.uuid;\n\t}\n\n\t// Date/Time types\n\tif (normalized === \"date\") {\n\t\treturn StandardizedDataType.date;\n\t}\n\n\tif (\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\")\n\t) {\n\t\treturn StandardizedDataType.time;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\")\n\t) {\n\t\treturn StandardizedDataType.timestamp;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn StandardizedDataType.timestamptz;\n\t}\n\n\tif (normalized === \"interval\" || normalized.startsWith(\"interval\")) {\n\t\treturn StandardizedDataType.interval;\n\t}\n\n\t// Binary\n\tif (normalized === \"bytea\") {\n\t\treturn StandardizedDataType.bytea;\n\t}\n\n\t// Network types\n\tif (normalized === \"inet\") {\n\t\treturn StandardizedDataType.inet;\n\t}\n\n\tif (normalized === \"cidr\") {\n\t\treturn StandardizedDataType.cidr;\n\t}\n\n\tif (normalized === \"macaddr\") {\n\t\treturn StandardizedDataType.macaddr;\n\t}\n\n\tif (normalized === \"macaddr8\") {\n\t\treturn StandardizedDataType.macaddr8;\n\t}\n\n\t// Geometric types\n\tif (normalized === \"point\") {\n\t\treturn StandardizedDataType.point;\n\t}\n\n\tif (normalized === \"line\") {\n\t\treturn StandardizedDataType.line;\n\t}\n\n\tif (normalized === \"polygon\") {\n\t\treturn StandardizedDataType.polygon;\n\t}\n\n\t// Array types\n\t// todo: handle array types\n\tif (normalized.startsWith(\"array\") || normalized.includes(\"[]\")) {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\t// User-defined types (enums)\n\tif (normalized.startsWith(\"user-defined\") || normalized === \"enum\") {\n\t\treturn StandardizedDataType.enum;\n\t}\n\n\t// Default: return the original type\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps MySQL data types to generic DataType enum (used for cell rendering)\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\", \"enum('a','b')\") for finer mapping\n */\nexport function mapMysqlToDataType(mysqlDataType: string, columnType?: string): DataTypes {\n\tconst normalized = mysqlDataType?.toLowerCase().trim() || \"\";\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"mediumint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"double\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"bit\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (explicit)\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"year\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum and set (set behaves like enum for display)\n\tif (normalized === \"enum\" || normalized === \"set\") {\n\t\treturn DataTypes.enum;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps MySQL data types to standardized display labels\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\") for finer mapping\n */\nexport function standardizeMysqlDataTypeLabel(\n\tmysqlDataType: string,\n\tcolumnType?: string,\n): StandardizedDataType {\n\tif (!mysqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mysqlDataType.toLowerCase().trim();\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\")\n\t\treturn StandardizedDataType.boolean;\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"mediumint\") return StandardizedDataType.mediumint;\n\tif (normalized === \"int\" || normalized === \"integer\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\" || normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"double\") return StandardizedDataType.double;\n\tif (normalized === \"bit\") return StandardizedDataType.bit;\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"tinytext\") return StandardizedDataType.tinytext;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"mediumtext\") return StandardizedDataType.mediumtext;\n\tif (normalized === \"longtext\") return StandardizedDataType.longtext;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"tinyblob\") return StandardizedDataType.tinyblob;\n\tif (normalized === \"blob\") return StandardizedDataType.blob;\n\tif (normalized === \"mediumblob\") return StandardizedDataType.mediumblob;\n\tif (normalized === \"longblob\") return StandardizedDataType.longblob;\n\n\t// JSON\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"timestamp\") return StandardizedDataType.timestamp;\n\tif (normalized === \"year\") return StandardizedDataType.year;\n\n\t// Complex types\n\tif (normalized === \"enum\") return StandardizedDataType.enum;\n\tif (normalized === \"set\") return StandardizedDataType.set;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps SQL Server data types to generic DataType enum (used for cell rendering)\n * @param mssqlDataType - The data type from sys.columns or information_schema.columns\n */\nexport function mapMssqlToDataType(mssqlDataType: string): DataTypes {\n\tconst normalized = mssqlDataType?.toLowerCase().trim() || \"\";\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"money\" ||\n\t\tnormalized === \"smallmoney\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (bit with length 1)\n\tif (normalized === \"bit\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"datetime2\" ||\n\t\tnormalized === \"smalldatetime\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"datetimeoffset\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON (SQL Server 2016+)\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps SQL Server data types to standardized display labels\n * @param mssqlDataType - The data type from sys.columns or information_schema.columns\n */\nexport function standardizeMssqlDataTypeLabel(mssqlDataType: string): StandardizedDataType {\n\tif (!mssqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mssqlDataType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"int\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\") return StandardizedDataType.float;\n\tif (normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"money\" || normalized === \"smallmoney\") return StandardizedDataType.money;\n\n\t// Boolean\n\tif (normalized === \"bit\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"nchar\") return StandardizedDataType.char;\n\tif (normalized === \"nvarchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"ntext\") return StandardizedDataType.text;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"image\") return StandardizedDataType.blob;\n\n\t// UUID\n\tif (normalized === \"uniqueidentifier\") return StandardizedDataType.uuid;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"datetime2\") return StandardizedDataType.datetime;\n\tif (normalized === \"smalldatetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"datetimeoffset\") return StandardizedDataType.timestamptz;\n\n\t// JSON and XML\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\tif (normalized === \"xml\") return StandardizedDataType.xml;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n","import { z } from \"zod\";\n\nexport const FOREIGN_KEY_ACTIONS = [\n\t\"CASCADE\",\n\t\"SET NULL\",\n\t\"SET DEFAULT\",\n\t\"RESTRICT\",\n\t\"NO ACTION\",\n] as const;\nexport const foreignKeyActionSchema = z.enum(FOREIGN_KEY_ACTIONS);\n\nexport const fieldDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\nexport type FieldDataType = z.infer<typeof fieldDataSchema>;\n\nexport const foreignKeyDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\treferencedTable: z.string(\"Referenced table is required\"),\n\treferencedColumn: z.string(\"Referenced column is required\"),\n\tonUpdate: foreignKeyActionSchema.default(\"NO ACTION\"),\n\tonDelete: foreignKeyActionSchema.default(\"NO ACTION\"),\n});\nexport type ForeignKeyDataType = z.infer<typeof foreignKeyDataSchema>;\n\nexport const createTableSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tfields: z.array(fieldDataSchema).min(1, \"At least one field is required\"),\n\tforeignKeys: z.array(foreignKeyDataSchema).optional(),\n});\n\nexport type CreateTableSchemaType = z.infer<typeof createTableSchema>;\n","import { z } from \"zod\";\nimport { databaseTypeSchema } from \"./database.types.js\";\n\nexport const databaseInfoSchema = z.object({\n\tname: z.string(\"Name is required\"),\n\tsize: z.string(\"Size is required\"),\n\towner: z.string(\"Owner is required\"),\n\tencoding: z.string(\"Encoding is required\"),\n});\n\nexport type DatabaseInfoSchemaType = z.infer<typeof databaseInfoSchema>;\n\nexport const databaseListSchema = z.object({\n\tdatabases: z.array(databaseInfoSchema),\n\tdbType: databaseTypeSchema,\n});\n\nexport type DatabaseListSchemaType = z.infer<typeof databaseListSchema>;\n\nexport const connectionInfoSchema = z.object({\n\tversion: z.string(\"Version is required\"),\n\tdatabase: z.string(\"Database is required\"),\n\tuser: z.string(\"User is required\"),\n\thost: z.string(\"Host is required\").nullable(),\n\tport: z.number(\"Port is required\").nullable(),\n\tactive_connections: z.coerce.number(\"Active connections is required\"),\n\tmax_connections: z.coerce.number(\"Max connections is required\"),\n});\n\nexport type ConnectionInfoSchemaType = z.infer<typeof connectionInfoSchema>;\n","import type { DatabaseTypeSchema } from \"./database.types\";\n\nexport type DatabaseSchema = {\n\tdbType: DatabaseTypeSchema;\n\ttables: Table[];\n\trelationships: Relationship[];\n};\n\nexport type Table = {\n\tname: string;\n\tdescription?: string;\n\tcolumns: Column[];\n\tsampleData?: Record<string, string>[];\n};\n\nexport type Column = {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n\tisPrimaryKey?: boolean;\n\tforeignKey?: string;\n\tdescription?: string;\n\tenumValues?: string[];\n};\n\nexport type Relationship = {\n\tfromTable: string;\n\tfromColumn: string;\n\ttoTable: string;\n\ttoColumn: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport const deleteRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKeys: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\tvalue: z.any(),\n\t\t\t}),\n\t\t)\n\t\t.min(1, \"At least one primary key is required\"),\n});\n\nexport type DeleteRecordSchemaType = z.infer<typeof deleteRecordSchema>;\n\nexport type DeleteRecordParams = DeleteRecordSchemaType & {\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type DeleteRecordResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n\nexport type ForeignKeyConstraint = {\n\tconstraintName: string;\n\treferencingTable: string;\n\treferencingColumn: string;\n\treferencedTable: string;\n\treferencedColumn: string;\n};\n\nexport type ForeignKeyConstraintRow = {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n};\n\nexport type RelatedRecord = {\n\ttableName: string;\n\tcolumnName: string;\n\tconstraintName: string;\n\trecords: Array<Record<string, unknown>>;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport type { RelatedRecord } from \"./delete-record.types\";\n\nexport const deleteTableQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteTableQuerySchemaType = z.infer<typeof deleteTableQuerySchema>;\n\nexport type DeleteTableParams = {\n\ttableName: string;\n\tdb: string;\n\tcascade?: boolean;\n};\n\nexport type DeleteTableResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n","import { z } from \"zod\";\n\nexport const executeQuerySchema = z.object({\n\tquery: z.string(\"Query is required\"),\n});\n\nexport type ExecuteQueryParams = z.infer<typeof executeQuerySchema>;\n\nexport type ExecuteQueryResult = {\n\tcolumns: string[];\n\trows: Record<string, unknown>[];\n\trowCount: number;\n\tduration: number;\n\tmessage?: string;\n\terror?: string;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const FORMAT_TYPES = [\"csv\", \"xlsx\", \"json\"] as const;\nexport type FormatType = (typeof FORMAT_TYPES)[number];\n\nexport const exportTableSchema = databaseSchema.extend({\n\tformat: z.enum(FORMAT_TYPES, {\n\t\tmessage: \"Invalid format. Supported formats: csv, xlsx, json\",\n\t}),\n});\nexport type ExportTableSchemaType = z.infer<typeof exportTableSchema>;\n\nexport type CellValue = string | number | boolean | Date | null | undefined;\n","export type RateLimitResponse = {\n\tlimit: number;\n\tused: number;\n\tremaining: number;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const renameColumnSchema = z.object({\n\tnewColumnName: z.string(\"New column name is required\"),\n});\n\nexport type RenameColumnSchemaType = z.infer<typeof renameColumnSchema>;\n\nexport const renameColumnParamSchema = deleteColumnParamSchema;\n\nexport type RenameColumnParamSchemaType = z.infer<typeof renameColumnParamSchema>;\n\nexport const renameColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tnewColumnName: renameColumnSchema.shape.newColumnName,\n});\n\nexport type RenameColumnParamsSchemaType = z.infer<typeof renameColumnParamsSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const filterSchema = z.object({\n\tcolumnName: z.string(),\n\toperator: z.string(),\n\tvalue: z.string(),\n});\n\nexport type FilterType = z.infer<typeof filterSchema>;\n\nexport const sortDirections = [\"asc\", \"desc\"] as const;\nexport type SortDirection = (typeof sortDirections)[number];\n\nexport const sortSchema = z.object({\n\tcolumnName: z.string(),\n\tdirection: z.enum(sortDirections),\n});\n\nexport type SortType = z.infer<typeof sortSchema>;\n\nexport const tableDataMetaSchema = z.object({\n\tlimit: z.number(),\n\ttotal: z.number(),\n\thasNextPage: z.boolean(),\n\thasPreviousPage: z.boolean(),\n\tnextCursor: z.string().nullable(),\n\tprevCursor: z.string().nullable(),\n});\n\nexport const tableDataResultSchema = z.object({\n\tdata: z.array(z.record(z.string(), z.unknown())),\n\tmeta: tableDataMetaSchema,\n});\n\nexport type TableDataResultSchemaType = z.infer<typeof tableDataResultSchema>;\n\nexport const tableDataQuerySchema = z.object({\n\tdb: databaseSchema.shape.db,\n\tcursor: z.string().optional(), // Base64 encoded cursor for pagination\n\tlimit: z.string().optional().default(\"50\").transform(Number),\n\tdirection: z.enum(sortDirections).optional().default(sortDirections[0]), // Pagination direction\n\tsort: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return \"\";\n\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(val);\n\t\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t} catch {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t}),\n\torder: z.enum(sortDirections).optional(),\n\tfilters: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return [];\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(val);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}),\n});\n\nexport type TableDataQuerySchemaType = z.infer<typeof tableDataQuerySchema>;\n\nexport interface CursorData {\n\tvalues: Record<string, unknown>;\n\tsortColumns: string[];\n}\n","import { z } from \"zod\";\n\nexport const tableInfoSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tschemaName: z.string().optional(),\n\trowCount: z.coerce.number(\"Row count is required\"),\n});\n\nexport type TableInfoSchemaType = z.infer<typeof tableInfoSchema>;\n","import { z } from \"zod\";\n\nexport const tableSchemaResultSchema = z.object({\n\tschema: z.string(),\n});\n\nexport type TableSchemaResult = z.infer<typeof tableSchemaResultSchema>;\n","import { z } from \"zod\";\n\nexport const updateRecordsSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKey: z.string(\"Primary key is required\").default(\"id\"),\n\tupdates: z\n\t\t.array(\n\t\t\tz.object(\n\t\t\t\t{\n\t\t\t\t\trowData: z.record(z.string(\"Column name is required\"), z.any()),\n\t\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\t\tvalue: z.any(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Each update must have a row data, column name, and value.\",\n\t\t\t\t},\n\t\t\t),\n\t\t)\n\t\t.min(1, \"At least one update is required\"),\n});\n\nexport type UpdateRecordsSchemaType = z.infer<typeof updateRecordsSchema>;\n","export * from \"./add-column.types.js\";\nexport * from \"./add-record.types.js\"; // done\nexport * from \"./alter-column.types.js\";\nexport * from \"./api-response.types.js\";\nexport * from \"./bulk-insert-records.type.js\";\nexport * from \"./chat.types.js\"; // done\nexport * from \"./cmd-args.types.js\"; // done\nexport * from \"./column.type.js\";\nexport * from \"./column-info.types.js\";\nexport * from \"./create-table.types.js\"; // done\nexport * from \"./database.types.js\"; // done\nexport * from \"./database-list.types.js\"; // done\nexport * from \"./database-schema.type.js\"; // done\nexport * from \"./delete-column.types.js\"; // done\nexport * from \"./delete-record.types.js\"; // done\nexport * from \"./delete-table.types.js\"; // done\nexport * from \"./execute-query.types.js\"; // done\nexport * from \"./export-table.types.js\";\nexport * from \"./rate-limit-response.type.js\";\nexport * from \"./rename-column.types.js\";\nexport * from \"./table-data.types.js\"; // done\nexport * from \"./table-info.type.js\"; // done\nexport * from \"./table-schema.types.js\"; // done\nexport * from \"./update-recors.types.js\"; // done\n","import type { Context } from \"hono\";\nimport { HTTPException } from \"hono/http-exception\";\nimport { DatabaseError } from \"pg\";\nimport type { ApiError } from \"shared/types/api-response.types.js\";\nimport { ZodError } from \"zod\";\n\n/**\n * Centralized error handler for the application\n */\nexport function handleError(e: Error | unknown, c: Context) {\n\tconsole.error(\"handleError:\", e);\n\n\tif (e instanceof HTTPException) {\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: e.message ?? \"Internal server error\",\n\t\t\t},\n\t\t\te.status,\n\t\t);\n\t}\n\n\tif (e instanceof ZodError) {\n\t\tconst issue = e.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue.message,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tif (e instanceof Error) {\n\t\t// MySQL-specific error codes\n\t\tconst mysqlError = e as { code?: string; errno?: number };\n\t\tconst isMysqlConnectionError =\n\t\t\tmysqlError.code === \"ECONNREFUSED\" ||\n\t\t\tmysqlError.code === \"ENOTFOUND\" ||\n\t\t\tmysqlError.code === \"ETIMEDOUT\" ||\n\t\t\tmysqlError.code === \"ER_ACCESS_DENIED_ERROR\" ||\n\t\t\tmysqlError.code === \"ER_BAD_HOST_ERROR\" ||\n\t\t\tmysqlError.code === \"ECONNRESET\" ||\n\t\t\tmysqlError.errno === 1045 || // ER_ACCESS_DENIED_ERROR\n\t\t\tmysqlError.errno === 2003 || // Can't connect to MySQL server\n\t\t\tmysqlError.errno === 2002; // Can't connect to local MySQL server\n\n\t\tconst isConnectionError =\n\t\t\tisMysqlConnectionError ||\n\t\t\te.message.includes(\"ECONNREFUSED\") ||\n\t\t\te.message.includes(\"connection refused\") ||\n\t\t\te.message.includes(\"timeout expired\") ||\n\t\t\te.message.includes(\"Connection terminated\") ||\n\t\t\te.message.includes(\"MongoNetworkError\") ||\n\t\t\te.message.includes(\"MongoServerSelectionError\") ||\n\t\t\t(e instanceof DatabaseError && e.code?.startsWith(\"08\")); // PostgreSQL connection exception class\n\n\t\tif (isConnectionError) {\n\t\t\treturn c.json<ApiError>(\n\t\t\t\t{ error: \"Database connection failed\", details: e.message },\n\t\t\t\t503,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn c.json<ApiError>(\n\t\t{\n\t\t\terror: e instanceof Error ? e.message : \"Internal server error\",\n\t\t},\n\t\t500,\n\t);\n}\n\nexport const validationHook = (\n\tresult: {\n\t\tsuccess: boolean;\n\t\tdata?: unknown;\n\t\terror?: { issues: { message: string }[] };\n\t},\n\tc: Context,\n): Response | undefined => {\n\tif (!result.success) {\n\t\tconst issue = result.error?.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue?.message ?? \"Unknown validation error\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n","import { MongoClient, ObjectId } from \"mongodb\";\nimport type { ConnectionPool as MssqlPool } from \"mssql\";\nimport mssql from \"mssql\";\nimport type { Pool as MysqlPool } from \"mysql2/promise\";\nimport { createPool as createMysqlPool } from \"mysql2/promise\";\nimport { Pool, type PoolConfig } from \"pg\";\nimport type { DatabaseTypeSchema } from \"shared/types\";\n\n/**\n * DatabaseManager - Manages multiple database connection pools for PostgreSQL, MySQL, SQL Server, and MongoDB\n */\nclass DatabaseManager {\n\tprivate pgPools: Map<string, Pool> = new Map();\n\tprivate mysqlPools: Map<string, MysqlPool> = new Map();\n\tprivate mssqlPools: Map<string, MssqlPool> = new Map();\n\tprivate mongoClient: MongoClient | null = null;\n\tprivate baseConfig: {\n\t\turl: string;\n\t\thost: string;\n\t\tport: number;\n\t\tuser: string;\n\t\tpassword: string;\n\t\tdbType: DatabaseTypeSchema;\n\t} | null = null;\n\n\tconstructor() {\n\t\tthis.initializeBaseConfig();\n\t}\n\n\t/**\n\t * Detect database type from URL protocol\n\t */\n\tprivate detectDbType(url: URL): DatabaseTypeSchema {\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tswitch (protocol) {\n\t\t\tcase \"postgres\":\n\t\t\tcase \"postgresql\":\n\t\t\t\treturn \"pg\";\n\t\t\tcase \"mysql\":\n\t\t\tcase \"mysql2\":\n\t\t\t\treturn \"mysql\";\n\t\t\tcase \"mssql\":\n\t\t\tcase \"sqlserver\":\n\t\t\t\treturn \"mssql\";\n\t\t\tcase \"mongodb\":\n\t\t\tcase \"mongodb+srv\":\n\t\t\t\treturn \"mongodb\";\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unsupported database type: ${protocol}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://).`,\n\t\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Parse DATABASE_URL and extract connection details\n\t */\n\tprivate initializeBaseConfig() {\n\t\tconst databaseUrl = process.env.DATABASE_URL;\n\t\tif (!databaseUrl) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(databaseUrl);\n\t\t\tthis.baseConfig = {\n\t\t\t\turl: databaseUrl,\n\t\t\t\thost: url.hostname,\n\t\t\t\tport:\n\t\t\t\t\tNumber.parseInt(url.port, 10) ||\n\t\t\t\t\t(this.detectDbType(url) === \"mysql\"\n\t\t\t\t\t\t? 3306\n\t\t\t\t\t\t: this.detectDbType(url) === \"mssql\"\n\t\t\t\t\t\t\t? 1433\n\t\t\t\t\t\t\t: 5432),\n\t\t\t\tuser: url.username,\n\t\t\t\tpassword: url.password,\n\t\t\t\tdbType: this.detectDbType(url),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new Error(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/**\n\t * Get the detected database type\n\t */\n\tgetDbType(): DatabaseTypeSchema {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\treturn this.baseConfig.dbType;\n\t}\n\n\t/**\n\t * Build a connection string for the specified database\n\t */\n\tbuildConnectionString(database?: string): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tif (!database) {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\tdatabase = url.pathname.slice(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\turl.pathname = `/${database}`;\n\t\t\treturn url.toString();\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to build connection string for database \"${database}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get or create a PostgreSQL connection pool for the specified database\n\t */\n\tgetPgPool(database?: string): Pool {\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.pgPools.has(connectionString)) {\n\t\t\tconst poolConfig: PoolConfig = {\n\t\t\t\tconnectionString,\n\t\t\t\tmax: 10,\n\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\tconnectionTimeoutMillis: 2000,\n\t\t\t};\n\n\t\t\tconst pool = new Pool(poolConfig);\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on PostgreSQL pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.pgPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.pgPools.get(connectionString) ?? new Pool({ connectionString });\n\t}\n\n\t/**\n\t * Get or create a MySQL connection pool for the specified database\n\t */\n\tgetMysqlPool(database?: string): MysqlPool {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mysqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst pool = createMysqlPool({\n\t\t\t\thost: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\twaitForConnections: true,\n\t\t\t\tconnectionLimit: 10,\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t// Enable multiple statements for raw query support\n\t\t\t\tmultipleStatements: false,\n\t\t\t});\n\n\t\t\tthis.mysqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created MySQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mysqlPools.get(connectionString) as MysqlPool;\n\t}\n\n\t/**\n\t * Get or create a SQL Server connection pool for the specified database\n\t */\n\tasync getMssqlPool(database?: string): Promise<MssqlPool> {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mssqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst config: mssql.config = {\n\t\t\t\tserver: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\toptions: {\n\t\t\t\t\tencrypt: false, // Use true for Azure\n\t\t\t\t\ttrustServerCertificate: true,\n\t\t\t\t\tenableArithAbort: true,\n\t\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t},\n\t\t\t\tpool: {\n\t\t\t\t\tmax: 10,\n\t\t\t\t\tmin: 0,\n\t\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst pool = await new mssql.ConnectionPool(config).connect();\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on SQL Server pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.mssqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created SQL Server connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mssqlPools.get(connectionString) as MssqlPool;\n\t}\n\n\t/**\n\t * Get the appropriate pool based on database type (legacy/PG-only helper)\n\t */\n\tgetPool(database?: string): Pool {\n\t\treturn this.getPgPool(database);\n\t}\n\n\t/**\n\t * Close a specific PostgreSQL pool by connection string\n\t */\n\tasync closePgPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.pgPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.pgPools.delete(connectionString);\n\t\t\tconsole.log(`Closed PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific MySQL pool by connection string\n\t */\n\tasync closeMysqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mysqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.mysqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed MySQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific SQL Server pool by connection string\n\t */\n\tasync closeMssqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mssqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.close();\n\t\t\tthis.mssqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed SQL Server connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific database pool by connection string (both types)\n\t */\n\tasync closePool(connectionString: string): Promise<void> {\n\t\tawait this.closePgPool(connectionString);\n\t\tawait this.closeMysqlPool(connectionString);\n\t\tawait this.closeMssqlPool(connectionString);\n\t}\n\n\t/**\n\t * Close a specific database pool by database name\n\t */\n\tasync closePoolByDatabase(database: string): Promise<void> {\n\t\tconst connectionString = this.buildConnectionString(database);\n\t\tawait this.closePool(connectionString);\n\t}\n\n\t/**\n\t * Get or create a MongoDB client\n\t */\n\tasync getMongoClient(): Promise<MongoClient> {\n\t\tif (!this.mongoClient) {\n\t\t\tif (!this.baseConfig) {\n\t\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t\t}\n\t\t\tconst nextClient = new MongoClient(this.baseConfig.url);\n\t\t\ttry {\n\t\t\t\tawait nextClient.connect();\n\t\t\t\tthis.mongoClient = nextClient;\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait nextClient.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore close errors\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn this.mongoClient;\n\t}\n\n\t/**\n\t * Get the MongoDB database name from the connection URL\n\t */\n\tgetMongoDbName(): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\tconst path = new URL(this.baseConfig.url).pathname?.replace(/^\\//, \"\");\n\t\treturn path || \"admin\";\n\t}\n\n\t/**\n\t * Get a MongoDB database instance\n\t */\n\tasync getMongoDb(dbName?: string) {\n\t\tconst mongoClient = await this.getMongoClient();\n\t\treturn mongoClient.db(dbName ?? this.getMongoDbName());\n\t}\n\n\t/**\n\t * Close all database pools\n\t */\n\tasync closeAll(): Promise<void> {\n\t\tconst pgClosePromises = Array.from(this.pgPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed PostgreSQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mysqlClosePromises = Array.from(this.mysqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed MySQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mssqlClosePromises = Array.from(this.mssqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.close();\n\t\t\t\tconsole.log(`Closed SQL Server pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all([...pgClosePromises, ...mysqlClosePromises, ...mssqlClosePromises]);\n\t\tthis.pgPools.clear();\n\t\tthis.mysqlPools.clear();\n\t\tthis.mssqlPools.clear();\n\t\tif (this.mongoClient) {\n\t\t\tawait this.mongoClient.close();\n\t\t\tthis.mongoClient = null;\n\t\t}\n\t}\n\n\t/**\n\t * Get all active pool connection strings\n\t */\n\tgetActivePools(): string[] {\n\t\treturn [\n\t\t\t...Array.from(this.pgPools.keys()),\n\t\t\t...Array.from(this.mysqlPools.keys()),\n\t\t\t...Array.from(this.mssqlPools.keys()),\n\t\t];\n\t}\n}\n\n// Singleton instance\nconst databaseManager = new DatabaseManager();\n\n/**\n * Get a PostgreSQL pool for the specified database\n */\nexport const getDbPool = (database?: string): Pool => {\n\treturn databaseManager.getPgPool(database);\n};\n\n/**\n * Get a MySQL pool for the specified database\n */\nexport const getMysqlPool = (database?: string): MysqlPool => {\n\treturn databaseManager.getMysqlPool(database);\n};\n\n/**\n * Get a SQL Server pool for the specified database\n */\nexport const getMssqlPool = async (database?: string): Promise<MssqlPool> => {\n\treturn databaseManager.getMssqlPool(database);\n};\n\n/**\n * Get the detected database type from DATABASE_URL\n */\nexport const getDbType = (): DatabaseTypeSchema => {\n\treturn databaseManager.getDbType();\n};\n\n/**\n * Build a connection string for the specified database\n */\nconst _buildDbConnectionString = (database?: string): string => {\n\treturn databaseManager.buildConnectionString(database);\n};\n\n/**\n * Close a specific database pool by database name\n */\nconst _closeDbPool = async (database: string): Promise<void> => {\n\treturn databaseManager.closePoolByDatabase(database);\n};\n\n/**\n * Close a specific database pool by connection string\n */\nconst _closeDbPoolByConnectionString = async (connectionString: string): Promise<void> => {\n\treturn databaseManager.closePool(connectionString);\n};\n\n/**\n * Close all database pools\n */\nconst _closeAllDbPools = async (): Promise<void> => {\n\treturn databaseManager.closeAll();\n};\n\n/**\n * Get list of active pool connection strings\n */\nconst _getActivePools = (): string[] => {\n\treturn databaseManager.getActivePools();\n};\n\n/**\n * Get or create the MongoDB client\n */\nexport const getMongoClient = (): Promise<MongoClient> => {\n\treturn databaseManager.getMongoClient();\n};\n\n/**\n * Get the MongoDB database name from the connection URL\n */\nexport const getMongoDbName = (): string => {\n\treturn databaseManager.getMongoDbName();\n};\n\n/**\n * Get a MongoDB database instance\n */\nexport const getMongoDb = (dbName?: string) => {\n\treturn databaseManager.getMongoDb(dbName);\n};\n\nexport const isValidObjectId = (value: unknown): value is string => {\n\treturn typeof value === \"string\" && ObjectId.isValid(value);\n};\n\nexport const coerceObjectId = (value: unknown): unknown => {\n\tif (typeof value === \"string\" && ObjectId.isValid(value)) {\n\t\treturn new ObjectId(value);\n\t}\n\treturn value;\n};\n","import type { DataTypes, FilterType, SortType, TableDataQuerySchemaType } from \"shared/types\";\nimport { coerceObjectId, isValidObjectId } from \"@/db-manager.js\";\n\nconst normalizeValue = (value: unknown): unknown => {\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\tif (typeof value === \"bigint\") {\n\t\treturn value.toString();\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tif (\"_bsontype\" in value && (value as { _bsontype?: string })._bsontype === \"ObjectId\") {\n\t\t\treturn (value as { toHexString: () => string }).toHexString();\n\t\t}\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value.map((item) => normalizeValue(item));\n\t\t}\n\t\tconst entries = Object.entries(value as Record<string, unknown>).map(([k, v]) => [\n\t\t\tk,\n\t\t\tnormalizeValue(v),\n\t\t]);\n\t\treturn Object.fromEntries(entries);\n\t}\n\treturn value;\n};\n\nconst inferDataType = (value: unknown): DataTypes => {\n\tif (value instanceof Date) return \"date\";\n\tif (value && typeof value === \"object\") {\n\t\tif (Array.isArray(value)) return \"array\";\n\t\tif (\"_bsontype\" in value) return \"text\";\n\t\treturn \"json\";\n\t}\n\tif (typeof value === \"boolean\") return \"boolean\";\n\tif (typeof value === \"number\" || typeof value === \"bigint\") return \"number\";\n\treturn \"text\";\n};\n\nconst mapDataTypeLabel = (dataType: DataTypes): string => {\n\tswitch (dataType) {\n\t\tcase \"number\":\n\t\t\treturn \"numeric\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"json\":\n\t\t\treturn \"json\";\n\t\tcase \"date\":\n\t\t\treturn \"date\";\n\t\tcase \"array\":\n\t\t\treturn \"array\";\n\t\tcase \"enum\":\n\t\t\treturn \"enum\";\n\t\tdefault:\n\t\t\treturn \"text\";\n\t}\n};\n\nconst buildMongoFilters = (filters: FilterType[]): Record<string, unknown> => {\n\tif (!filters || filters.length === 0) return {};\n\tconst andConditions: Record<string, unknown>[] = [];\n\tconst escapeRegex = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\tconst parseValue = (raw: string) => {\n\t\tconst trimmed = raw.trim();\n\t\tif (trimmed === \"null\") return null;\n\t\tif (trimmed === \"true\") return true;\n\t\tif (trimmed === \"false\") return false;\n\t\tconst asNumber = Number(trimmed);\n\t\tif (!Number.isNaN(asNumber) && trimmed !== \"\") return asNumber;\n\t\tif (isValidObjectId(trimmed)) return coerceObjectId(trimmed);\n\t\treturn trimmed;\n\t};\n\n\tfor (const filter of filters) {\n\t\tconst field = filter.columnName;\n\t\tconst value = parseValue(filter.value);\n\t\tconst op = filter.operator.toLowerCase();\n\n\t\tif (!field) continue;\n\n\t\tswitch (op) {\n\t\t\tcase \"=\":\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t\tcase \"!=\":\n\t\t\t\tandConditions.push({ [field]: { $ne: value } });\n\t\t\t\tbreak;\n\t\t\tcase \">\":\n\t\t\t\tandConditions.push({ [field]: { $gt: value } });\n\t\t\t\tbreak;\n\t\t\tcase \">=\":\n\t\t\t\tandConditions.push({ [field]: { $gte: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"<\":\n\t\t\t\tandConditions.push({ [field]: { $lt: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"<=\":\n\t\t\t\tandConditions.push({ [field]: { $lte: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tandConditions.push({ [field]: { $ne: value } });\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$regex: escapeRegex(String(value)),\n\t\t\t\t\t\t$options: \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$not: { $regex: escapeRegex(String(value)), $options: \"\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$regex: escapeRegex(String(value)),\n\t\t\t\t\t\t$options: \"i\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tandConditions.push({\n\t\t\t\t\t[field]: {\n\t\t\t\t\t\t$not: { $regex: escapeRegex(String(value)), $options: \"i\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tandConditions.push({ [field]: value });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn andConditions.length ? { $and: andConditions } : {};\n};\n\nconst buildMongoSort = (\n\tsort: TableDataQuerySchemaType[\"sort\"],\n\torder?: TableDataQuerySchemaType[\"order\"],\n): Record<string, 1 | -1> => {\n\tif (!sort) return { _id: 1 };\n\n\tif (Array.isArray(sort)) {\n\t\tconst sortEntries = (sort as SortType[]).map((s) => [\n\t\t\ts.columnName,\n\t\t\ts.direction === \"desc\" ? -1 : 1,\n\t\t]);\n\t\treturn Object.fromEntries(sortEntries);\n\t}\n\n\tif (typeof sort === \"string\" && sort.length > 0) {\n\t\treturn { [sort]: order === \"desc\" ? -1 : 1 };\n\t}\n\n\treturn { _id: 1 };\n};\n\nexport {\n\tbuildMongoFilters,\n\tbuildMongoSort,\n\tcanCoerceObjectId,\n\tcoerceObjectId as toMongoId,\n\tinferDataType,\n\tmapDataTypeLabel,\n\tnormalizeValue as normalizeMongoDocument,\n};\n\nfunction canCoerceObjectId(value: unknown): boolean {\n\treturn typeof value === \"string\" && isValidObjectId(value);\n}\n","import type { ColumnInfoSchemaType, DatabaseSchemaType, DataTypes } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { inferDataType, mapDataTypeLabel } from \"./mongo.utils.js\";\n\nconst SAMPLE_LIMIT = 200;\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst documents = await collection.find({}).limit(SAMPLE_LIMIT).toArray();\n\tconst totalDocs = documents.length;\n\n\tconst columnMap = new Map<\n\t\tstring,\n\t\t{\n\t\t\ttypes: Set<DataTypes>;\n\t\t\tnullable: boolean;\n\t\t\tpresentCount: number;\n\t\t}\n\t>();\n\n\tconst ensureColumn = (columnName: string, value: unknown) => {\n\t\tconst dataType = inferDataType(value);\n\t\tif (!columnMap.has(columnName)) {\n\t\t\tcolumnMap.set(columnName, {\n\t\t\t\ttypes: new Set([dataType]),\n\t\t\t\tnullable: false,\n\t\t\t\tpresentCount: 1,\n\t\t\t});\n\t\t} else {\n\t\t\tconst entry = columnMap.get(columnName);\n\t\t\tif (entry) {\n\t\t\t\tentry.types.add(dataType);\n\t\t\t\tentry.presentCount += 1;\n\t\t\t}\n\t\t}\n\t};\n\n\tfor (const doc of documents) {\n\t\tfor (const [key, value] of Object.entries(doc)) {\n\t\t\tif (value === null || value === undefined) {\n\t\t\t\tif (!columnMap.has(key)) {\n\t\t\t\t\tcolumnMap.set(key, {\n\t\t\t\t\t\ttypes: new Set([\"text\"]),\n\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\tpresentCount: 1,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst entry = columnMap.get(key);\n\t\t\t\t\tif (entry) entry.nullable = true;\n\t\t\t\t\tif (entry) entry.presentCount += 1;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tensureColumn(key, value);\n\t\t}\n\t}\n\n\tif (totalDocs > 0) {\n\t\tfor (const entry of columnMap.values()) {\n\t\t\tif (entry.presentCount < totalDocs) {\n\t\t\t\tentry.nullable = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!columnMap.has(\"_id\")) {\n\t\tcolumnMap.set(\"_id\", {\n\t\t\ttypes: new Set([\"text\"]),\n\t\t\tnullable: false,\n\t\t\tpresentCount: totalDocs,\n\t\t});\n\t}\n\n\treturn Array.from(columnMap.entries()).map(([columnName, meta]) => {\n\t\tconst dataType = meta.types.values().next().value ?? \"text\";\n\t\treturn {\n\t\t\tcolumnName,\n\t\t\tdataType,\n\t\t\tdataTypeLabel: mapDataTypeLabel(dataType) as ColumnInfoSchemaType[\"dataTypeLabel\"],\n\t\t\tisNullable: meta.nullable,\n\t\t\tcolumnDefault: null,\n\t\t\tisPrimaryKey: columnName === \"_id\",\n\t\t\tisForeignKey: false,\n\t\t\treferencedTable: null,\n\t\t\treferencedColumn: null,\n\t\t\tenumValues: null,\n\t\t};\n\t});\n}\n","import type { Column, DatabaseSchema, DatabaseSchemaType, Table } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { normalizeMongoDocument } from \"./mongo.utils.js\";\nimport { getTableColumns } from \"./table-columns.mongo.dao.js\";\n\nconst convertColumn = (col: {\n\tcolumnName: string;\n\tdataTypeLabel: string;\n\tisNullable: boolean;\n\tisPrimaryKey: boolean;\n}): Column => ({\n\tname: col.columnName,\n\ttype: col.dataTypeLabel,\n\tnullable: col.isNullable,\n\tisPrimaryKey: col.isPrimaryKey,\n});\n\nexport async function getMongoDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tconst { includeSampleData = false, maxTables } = options;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections().toArray();\n\tconst limitedCollections =\n\t\ttypeof maxTables === \"number\" && maxTables > 0\n\t\t\t? collections.slice(0, maxTables)\n\t\t\t: collections;\n\n\tconst tablePromises = limitedCollections.map(async (collection) => {\n\t\tconst name = collection.name;\n\t\tconst columns = await getTableColumns({ tableName: name, db });\n\t\tconst table: Table = {\n\t\t\tname,\n\t\t\tcolumns: columns.map(convertColumn),\n\t\t};\n\n\t\tif (includeSampleData) {\n\t\t\tconst rows = await mongoDb.collection(name).find({}).limit(3).toArray();\n\t\t\tconst normalized = rows.map(\n\t\t\t\t(row) => normalizeMongoDocument(row) as Record<string, unknown>,\n\t\t\t);\n\t\t\ttable.sampleData = normalized.map((row) =>\n\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t);\n\t\t}\n\n\t\treturn table;\n\t});\n\n\tconst tables = await Promise.all(tablePromises);\n\n\treturn {\n\t\tdbType: \"mongodb\",\n\t\ttables,\n\t\trelationships: [],\n\t};\n}\n","import { Pool } from \"pg\";\n\nlet dbInstance: Pool | null = null;\n\nconst getPool = (): Pool => {\n\tif (!dbInstance) {\n\t\tif (!process.env.DATABASE_URL) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\t\ttry {\n\t\t\tdbInstance = new Pool({\n\t\t\t\tconnectionString: process.env.DATABASE_URL,\n\t\t\t});\n\n\t\t\t// Handle pool errors to prevent server crashes\n\t\t\t// This catches connection errors, idle client errors, etc.\n\t\t\tdbInstance.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\"Unexpected database pool error:\", err.message);\n\t\t\t\t// Don't throw - just log the error to prevent server crash\n\t\t\t\t// The pool will automatically retry connections\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to create database pool:\", error);\n\t\t\t// Re-throw initialization errors as they indicate a configuration problem\n\t\t\tthrow error;\n\t\t}\n\t}\n\treturn dbInstance;\n};\n\n// Export db as a Proxy that lazily initializes the pool\n// This allows process.env.DATABASE_URL to be set after module import\nexport const db = new Proxy({} as Pool, {\n\tget(_target, prop) {\n\t\ttry {\n\t\t\treturn getPool()[prop as keyof Pool];\n\t\t} catch (error) {\n\t\t\t// If pool initialization fails, log and re-throw\n\t\t\tconsole.error(\"Database pool access error:\", error);\n\t\t\tthrow error;\n\t\t}\n\t},\n});\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\ttype DatabaseSchemaType,\n\tmapPostgresToDataType,\n\tstandardizeDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n SELECT \n c.column_name as \"columnName\",\n c.data_type as \"dataType\",\n c.udt_name as \"udtName\",\n c.is_nullable = 'YES' as \"isNullable\",\n c.column_default as \"columnDefault\",\n CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as \"isPrimaryKey\",\n CASE WHEN fk.column_name IS NOT NULL THEN true ELSE false END as \"isForeignKey\",\n fk.referenced_table as \"referencedTable\",\n fk.referenced_column as \"referencedColumn\",\n CASE \n WHEN c.data_type = 'USER-DEFINED' THEN \n (SELECT array_agg(e.enumlabel ORDER BY e.enumsortorder)\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE t.typname = c.udt_name)\n ELSE NULL\n END as \"enumValues\"\n FROM information_schema.columns c\n LEFT JOIN (\n SELECT ku.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage ku\n ON tc.constraint_name = ku.constraint_name\n AND tc.table_schema = ku.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) pk ON c.column_name = pk.column_name\n LEFT JOIN (\n SELECT \n kcu.column_name,\n ccu.table_name AS referenced_table,\n ccu.column_name AS referenced_column\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) fk ON c.column_name = fk.column_name\n WHERE c.table_schema = 'public'\n AND c.table_name = $1\n ORDER BY c.ordinal_position;\n `;\n\n\tconst { rows } = await pool.query(query, [tableName]);\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\t// Parse enumValues to always return string[] | null\n\t\tlet parsedEnumValues: string[] | null = null;\n\t\tif (r.enumValues) {\n\t\t\tif (Array.isArray(r.enumValues)) {\n\t\t\t\t// Already an array, use as-is\n\t\t\t\tparsedEnumValues = r.enumValues;\n\t\t\t} else if (typeof r.enumValues === \"string\") {\n\t\t\t\t// Parse PostgreSQL array format: \"{VALUE1,VALUE2,VALUE3}\"\n\t\t\t\tparsedEnumValues = r.enumValues.replace(/[{}]/g, \"\").split(\",\").filter(Boolean);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapPostgresToDataType(r.dataType),\n\t\t\tdataTypeLabel: standardizeDataTypeLabel(r.dataType),\n\t\t\tisNullable: r.isNullable,\n\t\t\tcolumnDefault: r.columnDefault,\n\t\t\tisPrimaryKey: r.isPrimaryKey,\n\t\t\tisForeignKey: r.isForeignKey,\n\t\t\treferencedTable: r.referencedTable,\n\t\t\treferencedColumn: r.referencedColumn,\n\t\t\tenumValues: parsedEnumValues,\n\t\t};\n\t});\n}\n","import type {\n\tColumn,\n\tColumnInfoSchemaType,\n\tDatabaseSchema,\n\tDatabaseSchemaType,\n\tRelationship,\n\tTable,\n} from \"shared/types\";\nimport { getMongoDatabaseSchema } from \"@/dao/mongo/schema.dao.js\";\nimport { db } from \"@/db.js\";\nimport { getDbPool, getDbType } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.dao.js\";\n\n/**\n * Get all table names from the database\n */\nasync function getTableNames(db: DatabaseSchemaType[\"db\"]): Promise<string[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n\t\tSELECT table_name\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t\tAND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\tconst { rows } = await pool.query(query);\n\treturn rows.map((r) => r.table_name);\n}\n\n/**\n * Get table comment/description if available\n */\nasync function getTableDescription(tableName: string): Promise<string | undefined> {\n\tconst client = await db.connect();\n\ttry {\n\t\tconst res = await client.query(\n\t\t\t`\n SELECT obj_description(oid) as description\n FROM pg_class\n WHERE relname = $1\n AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');\n `,\n\t\t\t[tableName],\n\t\t);\n\t\treturn res.rows[0]?.description || undefined;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Get sample data from a table (first 3 rows)\n */\nasync function getSampleData(tableName: string): Promise<Record<string, unknown>[]> {\n\tconst client = await db.connect();\n\ttry {\n\t\t// Sanitize table name to prevent SQL injection\n\t\t// In production, validate tableName against known tables list\n\t\tconst res = await client.query(`SELECT * FROM \"${tableName}\" LIMIT 3`);\n\t\treturn res.rows;\n\t} catch (error) {\n\t\tconsole.warn(`Could not fetch sample data for table ${tableName}:`, error);\n\t\treturn [];\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Convert ColumnInfo to the schema Column format\n */\nfunction convertColumnInfo(col: ColumnInfoSchemaType): Column {\n\tconst column: Column = {\n\t\tname: col.columnName,\n\t\ttype: col.dataTypeLabel,\n\t\tnullable: col.isNullable,\n\t};\n\n\tif (col.isPrimaryKey) {\n\t\tcolumn.isPrimaryKey = true;\n\t}\n\n\tif (col.isForeignKey && col.referencedTable && col.referencedColumn) {\n\t\tcolumn.foreignKey = `${col.referencedTable}.${col.referencedColumn}`;\n\t}\n\n\tif (col.enumValues && col.enumValues.length > 0) {\n\t\tcolumn.enumValues = col.enumValues;\n\t\tcolumn.description = `Enum values: ${col.enumValues.join(\", \")}`;\n\t}\n\n\treturn column;\n}\n\n/**\n * Extract all relationships from table columns\n */\nfunction extractRelationships(tables: Table[]): Relationship[] {\n\tconst relationships: Relationship[] = [];\n\n\tfor (const table of tables) {\n\t\tfor (const column of table.columns) {\n\t\t\tif (column.foreignKey) {\n\t\t\t\tconst [toTable, toColumn] = column.foreignKey.split(\".\");\n\t\t\t\trelationships.push({\n\t\t\t\t\tfromTable: table.name,\n\t\t\t\t\tfromColumn: column.name,\n\t\t\t\t\ttoTable,\n\t\t\t\t\ttoColumn,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\n/**\n * Get complete database schema with all tables, columns, and relationships\n */\nasync function getDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tincludeDescriptions?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tif (getDbType() === \"mongodb\") {\n\t\treturn getMongoDatabaseSchema(db, {\n\t\t\tincludeSampleData: options.includeSampleData,\n\t\t});\n\t}\n\n\tconst {\n\t\tincludeSampleData = false,\n\t\tincludeDescriptions = true,\n\t\t// maxTables = 50, // Prevent overwhelming the context\n\t} = options;\n\n\ttry {\n\t\tconst tableNames = await getTableNames(db);\n\n\t\t// Fetch schema info for each table in parallel\n\t\tconst tablePromises = tableNames.map(async (tableName) => {\n\t\t\tconst [columns, description, sampleData] = await Promise.all([\n\t\t\t\tgetTableColumns({ tableName, db }),\n\t\t\t\tincludeDescriptions ? getTableDescription(tableName) : Promise.resolve(undefined),\n\t\t\t\tincludeSampleData ? getSampleData(tableName) : Promise.resolve([]),\n\t\t\t]);\n\n\t\t\tconst table: Table = {\n\t\t\t\tname: tableName,\n\t\t\t\tcolumns: columns.map(convertColumnInfo),\n\t\t\t};\n\n\t\t\tif (description) {\n\t\t\t\ttable.description = description;\n\t\t\t}\n\n\t\t\tif (sampleData.length > 0) {\n\t\t\t\ttable.sampleData = sampleData.map((row) =>\n\t\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn table;\n\t\t});\n\n\t\tconst tables = await Promise.all(tablePromises);\n\n\t\t// Extract relationships from foreign keys\n\t\tconst relationships = extractRelationships(tables);\n\n\t\treturn {\n\t\t\tdbType: \"pg\",\n\t\t\ttables,\n\t\t\trelationships,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Error fetching database schema:\", error);\n\t\tthrow new Error(\n\t\t\t`Failed to fetch database schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Get detailed schema with sample data (for initial conversation context)\n */\nexport async function getDetailedSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<DatabaseSchema> {\n\treturn getDatabaseSchema(db, {\n\t\tincludeSampleData: true,\n\t\tincludeDescriptions: true,\n\t\t// maxTables: 30, // todo: DELETE THIS AFTER TESTING\n\t});\n}\n","import type { DatabaseSchema } from \"shared/types\";\n\n/**\n * Generate system prompt with database context\n */\nexport function generateSystemPrompt(schema: DatabaseSchema): string {\n\tconst dbTypeLower = schema.dbType.toLowerCase();\n\tconst dbTypeLabel = schema.dbType === \"pg\" ? \"PostgreSQL\" : schema.dbType;\n\tif (dbTypeLower.includes(\"mongo\")) {\n\t\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating a query\n2. When generating MongoDB queries:\n - Provide 1 sentence explanation\n - The MongoDB query in a JSON code block\n - 1 sentence about expected results\n3. Use exact collection/field names from the schema\n4. If query is unclear, ask ONE specific clarifying question\n5. No preamble, no apologies, get straight to the answer\n6. IMPORTANT: When the user asks about collections, fields, or any schema information, answer DIRECTLY from the \"Database Context\" above — do NOT generate a query to retrieve schema info you already have\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct MongoDB queries\n2. Use proper collection/field names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`json code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. Warn about potentially expensive operations (collection scans, large aggregations)\n8. Consider data privacy - remind users not to share sensitive data externally\n\n**Query Format:**\nReturn a JSON object with the following shape:\n{\n \"collection\": \"collectionName\",\n \"operation\": \"find|aggregate|insertOne|insertMany|updateOne|updateMany|deleteOne|deleteMany|count\",\n \"filter\": { ... },\n \"pipeline\": [ ... ],\n \"document\": { ... } | [ ... ],\n \"update\": { ... },\n \"options\": { ... },\n \"sort\": { \"field\": 1 },\n \"limit\": 100,\n \"skip\": 0\n}\n\nOnly include the fields needed for the chosen operation.\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll aggregate orders to calculate total revenue per customer.\n\n\\`\\`\\`json\n{\n \"collection\": \"orders\",\n \"operation\": \"aggregate\",\n \"pipeline\": [\n { \"$group\": { \"_id\": \"$customer_id\", \"total\": { \"$sum\": \"$total_amount\" } } },\n { \"$sort\": { \"total\": -1 } },\n { \"$limit\": 5 }\n ]\n}\n\\`\\`\\`\n\nThis will return the top 5 customers by revenue.\"`;\n\t}\n\n\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating SQL\n2. When generating SQL:\n - Provide 1 sentence explanation\n - The SQL query in a code block\n - 1 sentence about expected results\n - NO verbose explanations\n3. Use exact table/column names from the schema\n4. Generate valid ${dbTypeLabel} syntax\n5. If query is unclear, ask ONE specific clarifying question\n6. No preamble, no apologies, get straight to the answer\n7. IMPORTANT: When the user asks about tables, columns, relationships, or any schema information, answer DIRECTLY from the \"Database Context\" above — do NOT generate a SQL query to retrieve schema info you already have\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct SQL for the database type (${dbTypeLabel})\n2. Use proper table/column names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`sql code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. For complex queries, break down the logic step-by-step\n8. Warn about potentially expensive operations (full table scans, etc.)\n9. Consider data privacy - remind users not to share sensitive data externally\n\n**Response Format:**\nWhen generating queries, use this structure:\n- Brief explanation of what you'll do\n- The SQL query in a code block\n- Expected results description\n- Optional: suggestions for related queries\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll query the orders and customers tables to find your highest-value customers.\n\n\\`\\`\\`sql\nSELECT \n c.customer_name,\n SUM(o.total_amount) as total_revenue\nFROM customers c\nJOIN orders o ON c.id = o.customer_id\nGROUP BY c.id, c.customer_name\nORDER BY total_revenue DESC\nLIMIT 5;\n\\`\\`\\`\n\nThis will return the 5 customers with the highest total order value. You might also want to see:\n- Revenue trends over time for these customers\n- Their most frequently ordered products\"`;\n}\n\n/**\n * Format schema information for the prompt\n */\nfunction formatSchemaForPrompt(schema: DatabaseSchema): string {\n\tconst dbTypeLabel = schema.dbType === \"pg\" ? \"PostgreSQL\" : schema.dbType;\n\tlet output = `Database Type: ${dbTypeLabel}\\n\\n`;\n\n\toutput += \"**Tables and Columns:**\\n\";\n\tfor (const table of schema.tables) {\n\t\toutput += `\\n### ${table.name}\\n`;\n\t\tif (table.description) {\n\t\t\toutput += `Description: ${table.description}\\n`;\n\t\t}\n\t\toutput += \"Columns:\\n\";\n\n\t\tfor (const col of table.columns) {\n\t\t\tconst pkIndicator = col.isPrimaryKey ? \" [PRIMARY KEY]\" : \"\";\n\t\t\tconst fkIndicator = col.foreignKey ? ` [FK -> ${col.foreignKey}]` : \"\";\n\t\t\tconst nullable = col.nullable ? \"NULL\" : \"NOT NULL\";\n\n\t\t\toutput += ` - ${col.name}: ${col.type} ${nullable}${pkIndicator}${fkIndicator}\\n`;\n\t\t\tif (col.description) {\n\t\t\t\toutput += ` ${col.description}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add sample data if available\n\t\tif (table.sampleData && table.sampleData.length > 0) {\n\t\t\toutput += `Sample data (${table.sampleData.length} rows):\\n`;\n\t\t\toutput += `${JSON.stringify(table.sampleData.slice(0, 3), null, 2)}\\n`;\n\t\t}\n\t}\n\n\t// Add relationships\n\tif (schema.relationships && schema.relationships.length > 0) {\n\t\toutput += \"\\n**Relationships:**\\n\";\n\t\tfor (const rel of schema.relationships) {\n\t\t\toutput += ` - ${rel.fromTable}.${rel.fromColumn} -> ${rel.toTable}.${rel.toColumn}\\n`;\n\t\t}\n\t}\n\n\treturn output;\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { chatSchema } from \"shared/types\";\nimport { getDetailedSchema } from \"@/dao/table-details-schema.js\";\nimport { generateSystemPrompt } from \"@/utils/system-prompt-generator.js\";\n\nexport const chatRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /:dbType/chat/...\n\t */\n\t.basePath(\"/chat\")\n\n\t/**\n\t * GET /chat/limit - Proxy rate limit check to Cloudflare Worker\n\t */\n\t.get(\"/limit\", async (c) => {\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat/limit`, {\n\t\t\theaders: {\n\t\t\t\t\"cf-connecting-ip\": c.req.header(\"cf-connecting-ip\") ?? \"\",\n\t\t\t\t\"x-real-ip\": c.req.header(\"x-real-ip\") ?? \"\",\n\t\t\t\t\"x-forwarded-for\": c.req.header(\"x-forwarded-for\") ?? \"\",\n\t\t\t\t\"x-api-key\": c.req.header(\"x-api-key\") ?? \"\",\n\t\t\t},\n\t\t});\n\t\tconst data = await proxyResponse.json();\n\t\treturn c.json(data, proxyResponse.status as 200 | 500);\n\t})\n\n\t/**\n\t * POST /chat - Handle AI chat requests with streaming\n\t * Proxies to the Cloudflare Worker which has the Gemini API key\n\t */\n\t.post(\"/\", zValidator(\"json\", chatSchema), async (c) => {\n\t\tconst { messages, data } = c.req.valid(\"json\");\n\t\tconst { db, conversationId } = data;\n\t\tconsole.log(\"POST /chat messages\", messages);\n\n\t\t// Get the database schema and generate system prompt\n\t\tconst schema = await getDetailedSchema(db);\n\t\tconst systemPrompt = generateSystemPrompt(schema);\n\n\t\tconst payload = {\n\t\t\tmessages,\n\t\t\tconversationId,\n\t\t\tsystemPrompt,\n\t\t};\n\n\t\t// Forward request to the proxy with the system prompt.\n\t\t// Pass through IP headers so the proxy rate-limiter keys on the real user IP.\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"cf-connecting-ip\": c.req.header(\"cf-connecting-ip\") ?? \"\",\n\t\t\t\t\"x-real-ip\": c.req.header(\"x-real-ip\") ?? \"\",\n\t\t\t\t\"x-forwarded-for\": c.req.header(\"x-forwarded-for\") ?? \"\",\n\t\t\t\t\"x-api-key\": c.req.header(\"x-api-key\") ?? \"\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\n\t\tif (!proxyResponse.ok) {\n\t\t\tconst errorData = await proxyResponse.json();\n\t\t\treturn c.json(\n\t\t\t\t{ error: errorData.error || \"Proxy request failed\" },\n\t\t\t\tproxyResponse.status as 400 | 500,\n\t\t\t);\n\t\t}\n\n\t\t// Stream the SSE response back to the client\n\t\tconst { readable, writable } = new TransformStream();\n\t\tproxyResponse.body?.pipeTo(writable);\n\n\t\treturn new Response(readable, {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\tConnection: \"keep-alive\",\n\t\t\t},\n\t\t});\n\t});\n\nexport type ChatRoutes = typeof chatRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getDbPool(db);\n\n\t// Extract column names and values\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data);\n\n\t// Build the INSERT query\n\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\tconst query = `\n\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\tVALUES (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\tconst result = await pool.query(query, values);\n\tif (result.rowCount === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getDbPool(db);\n\tconst client = await pool.connect();\n\n\ttry {\n\t\t// Get column names from the first record\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\t\tlet successCount = 0;\n\t\tconst failureCount = 0;\n\t\tconst errors: Array<{ recordIndex: number; error: string }> = [];\n\n\t\t// Execute inserts in a transaction\n\t\tawait client.query(\"BEGIN\");\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => record[col]);\n\n\t\t\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait client.query(insertSQL, values);\n\t\t\t\tsuccessCount++;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\n\t\treturn {\n\t\t\tsuccess: failureCount === 0,\n\t\t\tmessage: `Bulk insert completed: ${successCount} records inserted${failureCount > 0 ? `, ${failureCount} failed` : \"\"}`,\n\t\t\tsuccessCount,\n\t\t\tfailureCount,\n\t\t\terrors: errors.length > 0 ? errors : undefined,\n\t\t};\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tclient.release();\n\t}\n};\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getDbPool(db);\n\n\t// Build column definitions\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tlet columnDef = `\"${field.columnName}\" ${field.columnType}`;\n\n\t\t// Add array suffix if needed\n\t\tif (field.isArray) {\n\t\t\tcolumnDef += \"[]\";\n\t\t}\n\n\t\t// Add PRIMARY KEY constraint\n\t\tif (field.isPrimaryKey) {\n\t\t\tcolumnDef += \" PRIMARY KEY\";\n\t\t}\n\n\t\t// Add UNIQUE constraint\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" UNIQUE\";\n\t\t}\n\n\t\t// Add NOT NULL constraint (if not nullable)\n\t\tif (!field.isNullable) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Add GENERATED ALWAYS AS IDENTITY for identity columns\n\t\tif (field.isIdentity) {\n\t\t\tcolumnDef += \" GENERATED ALWAYS AS IDENTITY\";\n\t\t}\n\n\t\t// Add default value\n\t\tif (field.defaultValue && !field.isIdentity) {\n\t\t\tcolumnDef += ` DEFAULT ${field.defaultValue}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Build foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \"${constraintName}\" FOREIGN KEY (\"${fk.columnName}\") REFERENCES \"${fk.referencedTable}\" (\"${fk.referencedColumn}\") ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\t// Combine column definitions and foreign key constraints\n\tconst allDefinitions = [...columnDefinitions, ...foreignKeyConstraints];\n\n\t// Create the table\n\tconst createTableSQL = `\n\t\t\tCREATE TABLE \"${tableName}\" (\n\t\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\\t\")}\n\t\t\t);\n\t\t`;\n\n\tawait pool.query(createTableSQL);\n}\n","/**\n * Parse DATABASE_URL to extract host and port\n */\nexport function parseDatabaseUrl(): { host: string; port: number } {\n\tconst databaseUrl = process.env.DATABASE_URL;\n\n\tif (!databaseUrl) {\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n\n\ttry {\n\t\tconst url = new URL(databaseUrl);\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tconst defaultPort = protocol === \"mongodb\" || protocol === \"mongodb+srv\" ? 27017 : 5432;\n\t\treturn {\n\t\t\thost: url.hostname || \"localhost\",\n\t\t\tport: Number.parseInt(url.port, 10) || defaultPort,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Failed to parse DATABASE_URL:\", error);\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ConnectionInfoSchemaType,\n\tconnectionInfoSchema,\n\ttype DatabaseInfoSchemaType,\n\ttype DatabaseSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all normal databases on the PostgreSQL server.\n * Returns name, size (human readable), owner, and encoding.\n *\n * @returns List of database information objects\n * @throws Error if query fails or no databases are found\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n d.datname as name,\n pg_size_pretty(pg_database_size(d.datname)) as size,\n pg_catalog.pg_get_userbyid(d.datdba) as owner,\n pg_encoding_to_char(d.encoding) as encoding\n FROM pg_catalog.pg_database d\n WHERE d.datistemplate = false\n ORDER BY d.datname;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from database\",\n\t\t});\n\t}\n\n\treturn rows;\n}\n\n/**\n * Gets the name of the database we are currently using.\n *\n * @returns Object with current database name\n * @throws Error if query fails or no name is returned\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = \"SELECT current_database() as database;\";\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from database\",\n\t\t});\n\t}\n\n\treturn rows[0];\n}\n\n/**\n * Gets useful information about the connection and PostgreSQL server.\n * Includes version, host, port, user, database name, active connections, etc.\n *\n * Uses fallback values from DATABASE_URL if some fields are missing.\n *\n * @returns Connection and server information object\n * @throws Error if query fails or result is invalid\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n version() as version,\n current_database() as database,\n current_user as user,\n inet_server_addr() as host,\n inet_server_port() as port,\n (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,\n (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from database\",\n\t\t});\n\t}\n\n\t// Validate main result\n\tconst result = connectionInfoSchema.parse(rows[0]);\n\n\t// Use DATABASE_URL as backup for host/port if needed\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: result.host || urlDefaults.host,\n\t\tport: result.port || urlDefaults.port,\n\t\tuser: result.user,\n\t\tdatabase: result.database,\n\t\tversion: result.version.toString(),\n\t\tactive_connections: result.active_connections,\n\t\tmax_connections: result.max_connections,\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a table using ALTER TABLE DROP COLUMN.\n * Uses CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies.\n *\n * @param params.tableName - Name of the table containing the column\n * @param params.columnName - Name of the column to delete\n * @param params.cascade - If true, uses CASCADE; if false, uses RESTRICT\n * @param params.db - Optional database name to connect to\n * @returns {Object} Object with deleted count\n * @throws HTTPException if table or column does not exist\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, cascade, db } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check if column exists\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns \n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Use CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies\n\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\tconst dropColumnSQL = `ALTER TABLE \"${tableName}\" DROP COLUMN \"${columnName}\" ${dropMode}`;\n\n\tconst { rowCount } = await pool.query(dropColumnSQL);\n\n\treturn { deletedCount: rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Finds all records in other tables that reference the given primary key values\n */\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\t// Group constraints by referencing table and column for efficiency\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) {\n\t\t\tconstraintsByTable.set(key, []);\n\t\t}\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\t// Get the primary key values that we're looking for\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\t// Find which primary key column matches this FK's referenced column\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\t// Build query to find related records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tWHERE \"${constraint.referencingColumn}\" IN (${placeholders})\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery, pkValues);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Attempts to delete records. If FK violation occurs, returns related records.\n */\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\n\tconst query = `\n\t\tDELETE FROM \"${tableName}\"\n\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\tRETURNING *\n\t`;\n\n\ttry {\n\t\tawait pool.query(\"BEGIN\");\n\t\tconst result = await pool.query(query, pkValues);\n\t\tawait pool.query(\"COMMIT\");\n\t\treturn { deletedCount: result.rowCount ?? 0, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\t// Check if this is a foreign key violation\n\t\tconst pgError = error as {\n\t\t\tcode?: string;\n\t\t\tdetail?: string;\n\t\t\tconstraint?: string;\n\t\t};\n\n\t\tif (pgError.code === \"23503\") {\n\t\t\t// Fetch related records to show the user\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\n/**\n * Force deletes records by first deleting all related records in referencing tables (cascade)\n */\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\t// Get all FK constraints that reference this table\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\t\tlet totalRelatedDeleted = 0;\n\n\t\t// Delete related records in reverse dependency order\n\t\t// We need to handle nested FKs recursively\n\t\tconst deletedTables = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t) => {\n\t\t\t// First, find if there are tables referencing the target table\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\t// Get the values that will be deleted from the target table\n\t\t\t\tconst nestedPlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\t\tconst selectQuery = `\n\t\t\t\t\tSELECT \"${nestedFk.referencedColumn}\" FROM \"${targetTable}\"\n\t\t\t\t\tWHERE \"${targetColumn}\" IN (${nestedPlaceholders})\n\t\t\t\t`;\n\n\t\t\t\tconst selectResult = await pool.query(selectQuery, values);\n\t\t\t\tconst nestedValues = selectResult.rows.map(\n\t\t\t\t\t({ row }: { row: { [nestedFk.referencedColumn]: unknown } }) =>\n\t\t\t\t\t\trow[nestedFk.referencedColumn],\n\t\t\t\t);\n\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Now delete from the target table\n\t\t\tconst deletePlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\tconst deleteQuery = `\n\t\t\t\tDELETE FROM \"${targetTable}\"\n\t\t\t\tWHERE \"${targetColumn}\" IN (${deletePlaceholders})\n\t\t\t`;\n\n\t\t\tconst deleteResult = await pool.query(deleteQuery, values);\n\t\t\ttotalRelatedDeleted += deleteResult.rowCount ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\t// Delete from all referencing tables first\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t);\n\t\t}\n\n\t\t// Finally delete the main records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst query = `\n\t\t\tDELETE FROM \"${tableName}\"\n\t\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\t\tconst result = await pool.query(query, pkValues);\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\tconst mainDeleted = result.rowCount ?? 0;\n\n\t\treturn { deletedCount: mainDeleted + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Gets related records from tables that reference this table\n */\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Gets the total row count for a table\n */\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(`SELECT COUNT(*) as count FROM \"${tableName}\"`);\n\treturn Number.parseInt(result.rows[0]?.count ?? \"0\", 10);\n}\n\n/**\n * Deletes a table from the database.\n * If there are FK constraints referencing this table, returns the related records.\n *\n * @param params.tableName - Name of the table to delete\n * @param params.db - Database name\n * @param params.cascade - If true, uses CASCADE to drop dependent objects\n * @returns DeleteTableResult with deletedCount, fkViolation flag, and relatedRecords\n */\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get row count before deletion\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\t// If not cascade, check for FK constraints first\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\t}\n\n\ttry {\n\t\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\t\tconst dropTableSQL = `DROP TABLE \"${tableName}\" ${dropMode}`;\n\n\t\tawait pool.query(dropTableSQL);\n\n\t\treturn {\n\t\t\tdeletedCount: rowCount,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error) {\n\t\tconst pgError = error as { code?: string; detail?: string };\n\n\t\t// Check if this is a dependency error (foreign key constraint)\n\t\tif (pgError.code === \"2BP01\") {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getDbPool(db);\n\tconst { rows } = await pool.query(`SELECT * FROM \"${tableName}\"`);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { normalizeMongoDocument } from \"./mongo.utils.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst payload = normalizeMongoDocument(data) as Record<string, unknown>;\n\tif (payload._id === \"\" || payload._id === null) {\n\t\tdelete payload._id;\n\t}\n\tconst result = await collection.insertOne(payload);\n\tif (!result.insertedId) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\treturn { insertedCount: 1 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { normalizeMongoDocument } from \"./mongo.utils.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, { message: \"At least one record is required\" });\n\t}\n\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tconst docs = records.map((record) => {\n\t\tconst normalized = normalizeMongoDocument(record) as Record<string, unknown>;\n\t\tif (normalized._id === \"\" || normalized._id === null) delete normalized._id;\n\t\treturn normalized;\n\t});\n\n\ttry {\n\t\tconst result = await collection.insertMany(docs, { ordered: false });\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${result.insertedCount} record${result.insertedCount !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: result.insertedCount,\n\t\t\tfailureCount: records.length - result.insertedCount,\n\t\t};\n\t} catch (error) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Bulk insert failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t});\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CreateTableSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nconst MONGO_BSON_TYPES = new Set([\n\t\"double\",\n\t\"string\",\n\t\"object\",\n\t\"array\",\n\t\"binData\",\n\t\"undefined\",\n\t\"objectId\",\n\t\"bool\",\n\t\"date\",\n\t\"null\",\n\t\"regex\",\n\t\"dbPointer\",\n\t\"javascript\",\n\t\"symbol\",\n\t\"javascriptWithScope\",\n\t\"int\",\n\t\"timestamp\",\n\t\"long\",\n\t\"decimal\",\n\t\"minKey\",\n\t\"maxKey\",\n]);\n\nconst mapMongoBsonType = (rawType: string): string => {\n\tconst normalized = rawType.trim();\n\tif (MONGO_BSON_TYPES.has(normalized)) return normalized;\n\n\tswitch (normalized.toLowerCase()) {\n\t\tcase \"boolean\":\n\t\t\treturn \"bool\";\n\t\tcase \"objectid\":\n\t\t\treturn \"objectId\";\n\t\tcase \"binary\":\n\t\t\treturn \"binData\";\n\t\tdefault:\n\t\t\treturn normalized;\n\t}\n};\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<void> {\n\tconst tableName = tableData?.tableName ?? \"\";\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length > 0) {\n\t\tthrow new HTTPException(400, { message: `Collection \"${tableName}\" already exists` });\n\t}\n\n\tconst fields = tableData?.fields ?? [];\n\tif (fields.length === 0) {\n\t\tawait mongoDb.createCollection(tableName);\n\t\treturn;\n\t}\n\n\tconst properties: Record<string, unknown> = {};\n\tconst required: string[] = [];\n\n\tfor (const field of fields) {\n\t\tconst bsonType = mapMongoBsonType(field.columnType);\n\t\tif (!MONGO_BSON_TYPES.has(bsonType)) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Unsupported MongoDB BSON type \"${field.columnType}\" for field \"${field.columnName}\"`,\n\t\t\t});\n\t\t}\n\n\t\tif (field.isArray) {\n\t\t\tproperties[field.columnName] = {\n\t\t\t\tbsonType: \"array\",\n\t\t\t\t...(bsonType !== \"array\" ? { items: { bsonType } } : {}),\n\t\t\t};\n\t\t} else {\n\t\t\tproperties[field.columnName] = { bsonType };\n\t\t}\n\n\t\tif (!field.isNullable) {\n\t\t\trequired.push(field.columnName);\n\t\t}\n\t}\n\n\tawait mongoDb.createCollection(tableName, {\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\tbsonType: \"object\",\n\t\t\t\trequired,\n\t\t\t\tproperties,\n\t\t\t\tadditionalProperties: true,\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"error\",\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMongoClient, getMongoDbName } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\nconst formatBytes = (bytes: number): string => {\n\tif (!Number.isFinite(bytes)) return \"n/a\";\n\tconst units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\tlet value = bytes;\n\tlet unitIndex = 0;\n\twhile (value >= 1024 && unitIndex < units.length - 1) {\n\t\tvalue /= 1024;\n\t\tunitIndex += 1;\n\t}\n\treturn `${value.toFixed(1)} ${units[unitIndex]}`;\n};\n\nexport async function getMongoDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst client = await getMongoClient();\n\tconst admin = client.db().admin();\n\tconst result = await admin.listDatabases();\n\tconst databases = result.databases ?? [];\n\n\tif (!databases[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from MongoDB\",\n\t\t});\n\t}\n\n\treturn databases.map((db) => ({\n\t\tname: db.name,\n\t\tsize: formatBytes(db.sizeOnDisk ?? 0),\n\t\towner: \"n/a\",\n\t\tencoding: \"n/a\",\n\t}));\n}\n\nexport async function getMongoCurrentDatabase(): Promise<DatabaseSchemaType> {\n\treturn { db: getMongoDbName() };\n}\n\nexport async function getMongoConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst client = await getMongoClient();\n\tconst admin = client.db().admin();\n\tconst urlDefaults = parseDatabaseUrl();\n\tlet serverStatus: {\n\t\tversion?: string;\n\t\tconnections?: { current?: number; available?: number };\n\t} = {};\n\ttry {\n\t\tserverStatus = await admin.serverStatus();\n\t} catch (error) {\n\t\tconsole.warn(\"Failed to read MongoDB serverStatus:\", error);\n\t}\n\n\treturn {\n\t\thost: urlDefaults.host,\n\t\tport: urlDefaults.port,\n\t\tuser: \"n/a\",\n\t\tdatabase: getMongoDbName(),\n\t\tversion: serverStatus.version ?? \"unknown\",\n\t\tactive_connections: serverStatus.connections?.current ?? 0,\n\t\tmax_connections:\n\t\t\t(serverStatus.connections?.current ?? 0) + (serverStatus.connections?.available ?? 0),\n\t};\n}\n","export {\n\tgetMongoConnectionInfo as getDatabaseConnectionInfo,\n\tgetMongoConnectionInfo,\n\tgetMongoCurrentDatabase as getCurrentDatabase,\n\tgetMongoCurrentDatabase,\n\tgetMongoDatabasesList as getDatabasesList,\n\tgetMongoDatabasesList,\n} from \"./database-list.dao.js\";\n","import type { DatabaseSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nexport async function deleteColumn({\n\ttableName,\n\tcolumnName,\n\tdb,\n}: {\n\ttableName: string;\n\tcolumnName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ deletedCount: number }> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst result = await collection.updateMany({}, { $unset: { [columnName]: \"\" } });\n\treturn { deletedCount: result.modifiedCount };\n}\n","import type { DeleteRecordParams, DeleteResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { canCoerceObjectId, toMongoId } from \"./mongo.utils.js\";\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteResult> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tconst pkColumn = primaryKeys[0]?.columnName ?? \"_id\";\n\tconst pkValues = primaryKeys.map((pk) =>\n\t\tpkColumn === \"_id\" && canCoerceObjectId(pk.value) ? toMongoId(pk.value) : pk.value,\n\t);\n\n\tconst result = await collection.deleteMany({ [pkColumn]: { $in: pkValues } });\n\treturn { deletedCount: result.deletedCount ?? 0 };\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst result = await deleteRecords({ tableName, primaryKeys, db });\n\treturn { deletedCount: result.deletedCount };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteTableParams, DeleteTableResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nexport async function deleteTable({\n\ttableName,\n\tdb,\n}: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\ttry {\n\t\tconst rowCount = await collection.estimatedDocumentCount();\n\t\tawait collection.drop();\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import type { DatabaseSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { normalizeMongoDocument } from \"./mongo.utils.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: string;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, unknown>[] }> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst rows = await collection.find({}).limit(10000).toArray();\n\tconst normalized = rows.map((row) => normalizeMongoDocument(row) as Record<string, unknown>);\n\tconst cols = Array.from(new Set(normalized.flatMap((row) => Object.keys(row))));\n\treturn { cols, rows: normalized };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { buildMongoSort, normalizeMongoDocument, toMongoId } from \"./mongo.utils.js\";\n\ntype MongoQueryPayload = {\n\tcollection: string;\n\toperation:\n\t\t| \"find\"\n\t\t| \"aggregate\"\n\t\t| \"insertOne\"\n\t\t| \"insertMany\"\n\t\t| \"updateOne\"\n\t\t| \"updateMany\"\n\t\t| \"deleteOne\"\n\t\t| \"deleteMany\"\n\t\t| \"count\";\n\tfilter?: Record<string, unknown>;\n\tpipeline?: Record<string, unknown>[];\n\tdocument?: Record<string, unknown> | Record<string, unknown>[];\n\tupdate?: Record<string, unknown>;\n\toptions?: Record<string, unknown>;\n\tsort?: Record<string, 1 | -1>;\n\tlimit?: number;\n\tskip?: number;\n};\n\nconst normalizeIdFilter = (filter: Record<string, unknown>) => {\n\tif (filter._id && typeof filter._id === \"string\") {\n\t\treturn { ...filter, _id: toMongoId(filter._id) };\n\t}\n\tif (filter._id && typeof filter._id === \"object\") {\n\t\tconst obj = filter._id as Record<string, unknown>;\n\t\tif (Array.isArray(obj.$in)) {\n\t\t\treturn {\n\t\t\t\t...filter,\n\t\t\t\t_id: {\n\t\t\t\t\t...obj,\n\t\t\t\t\t$in: obj.$in.map((val) => (typeof val === \"string\" ? toMongoId(val) : val)),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (Array.isArray(obj.$nin)) {\n\t\t\treturn {\n\t\t\t\t...filter,\n\t\t\t\t_id: {\n\t\t\t\t\t...obj,\n\t\t\t\t\t$nin: obj.$nin.map((val) => (typeof val === \"string\" ? toMongoId(val) : val)),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\treturn filter;\n};\n\nexport const executeMongoQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tlet payload: MongoQueryPayload;\n\ttry {\n\t\tpayload = JSON.parse(query) as MongoQueryPayload;\n\t} catch (_error) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Mongo query must be valid JSON\",\n\t\t});\n\t}\n\n\tif (!payload.collection || !payload.operation) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Mongo query must include collection and operation\",\n\t\t});\n\t}\n\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(payload.collection);\n\n\tconst startTime = performance.now();\n\tlet rows: Record<string, unknown>[] = [];\n\tlet rowCount = 0;\n\tlet message: string | undefined;\n\n\tswitch (payload.operation) {\n\t\tcase \"find\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst cursor = collection.find(filter, payload.options ?? {});\n\t\t\tconst sort = payload.sort ?? buildMongoSort(\"\", undefined);\n\t\t\tcursor.sort(sort);\n\t\t\tif (payload.skip) cursor.skip(payload.skip);\n\t\t\tif (payload.limit) cursor.limit(payload.limit);\n\t\t\trows = await cursor.toArray();\n\t\t\trowCount = rows.length;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"aggregate\": {\n\t\t\tconst pipeline = payload.pipeline ?? [];\n\t\t\trows = await collection.aggregate(pipeline, payload.options ?? {}).toArray();\n\t\t\trowCount = rows.length;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"insertOne\": {\n\t\t\tconst doc = payload.document as Record<string, unknown> | undefined;\n\t\t\tif (!doc) throw new HTTPException(400, { message: \"document is required\" });\n\t\t\tconst result = await collection.insertOne(doc);\n\t\t\trowCount = result.insertedId ? 1 : 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"insertMany\": {\n\t\t\tconst docs = payload.document as Record<string, unknown>[] | undefined;\n\t\t\tif (!Array.isArray(docs))\n\t\t\t\tthrow new HTTPException(400, { message: \"document array is required\" });\n\t\t\tconst result = await collection.insertMany(docs);\n\t\t\trowCount = result.insertedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"updateOne\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tif (!payload.update) throw new HTTPException(400, { message: \"update is required\" });\n\t\t\tconst result = await collection.updateOne(filter, payload.update, payload.options ?? {});\n\t\t\trowCount = result.matchedCount ?? 0;\n\t\t\tmessage = `OK (${result.modifiedCount ?? 0} modified)`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"updateMany\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tif (!payload.update) throw new HTTPException(400, { message: \"update is required\" });\n\t\t\tconst result = await collection.updateMany(\n\t\t\t\tfilter,\n\t\t\t\tpayload.update,\n\t\t\t\tpayload.options ?? {},\n\t\t\t);\n\t\t\trowCount = result.matchedCount ?? 0;\n\t\t\tmessage = `OK (${result.modifiedCount ?? 0} modified)`;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"deleteOne\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst result = await collection.deleteOne(filter, payload.options ?? {});\n\t\t\trowCount = result.deletedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"deleteMany\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\tconst result = await collection.deleteMany(filter, payload.options ?? {});\n\t\t\trowCount = result.deletedCount ?? 0;\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"count\": {\n\t\t\tconst filter = normalizeIdFilter(payload.filter ?? {});\n\t\t\trowCount = await collection.countDocuments(filter);\n\t\t\trows = [{ count: rowCount }];\n\t\t\tmessage = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tthrow new HTTPException(400, { message: \"Unsupported Mongo operation\" });\n\t}\n\n\tconst duration = performance.now() - startTime;\n\n\tconst normalizedRows = rows.map(\n\t\t(row) => normalizeMongoDocument(row) as Record<string, unknown>,\n\t);\n\n\tconst columns = normalizedRows[0] ? Object.keys(normalizedRows[0]) : [];\n\treturn {\n\t\tcolumns,\n\t\trows: normalizedRows,\n\t\trowCount,\n\t\tduration,\n\t\tmessage,\n\t};\n};\n","export { executeMongoQuery, executeMongoQuery as executeQuery } from \"./query.dao.js\";\n","import type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections().toArray();\n\n\tconst results: TableInfoSchemaType[] = [];\n\tfor (const collection of collections) {\n\t\tconst name = collection.name;\n\t\tconst rowCount = await mongoDb.collection(name).estimatedDocumentCount();\n\t\tresults.push({ tableName: name, rowCount });\n\t}\n\n\treturn results;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\nconst SAMPLE_LIMIT = 200;\n\nconst inferBsonType = (value: unknown): string => {\n\tif (value === null || value === undefined) return \"null\";\n\tif (value instanceof Date) return \"date\";\n\tif (typeof value === \"boolean\") return \"bool\";\n\tif (typeof value === \"number\") return Number.isInteger(value) ? \"int\" : \"double\";\n\tif (typeof value === \"bigint\") return \"long\";\n\tif (Array.isArray(value)) return \"array\";\n\tif (typeof value === \"object\") {\n\t\tif (\"_bsontype\" in (value as object)) {\n\t\t\tconst bson = (value as { _bsontype: string })._bsontype;\n\t\t\tif (bson === \"ObjectId\") return \"objectId\";\n\t\t\tif (bson === \"Decimal128\") return \"decimal\";\n\t\t\tif (bson === \"Binary\") return \"binData\";\n\t\t\tif (bson === \"Timestamp\") return \"timestamp\";\n\t\t\treturn bson.toLowerCase();\n\t\t}\n\t\treturn \"object\";\n\t}\n\treturn \"string\";\n};\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tconst collection = mongoDb.collection(tableName);\n\tconst docs = await collection.find({}).limit(SAMPLE_LIMIT).toArray();\n\tconst totalDocs = await collection.estimatedDocumentCount();\n\n\t// Build field → bson types map\n\tconst fieldTypes = new Map<string, Set<string>>();\n\tconst fieldPresence = new Map<string, number>();\n\n\tfor (const doc of docs) {\n\t\tfor (const [key, value] of Object.entries(doc)) {\n\t\t\tconst bsonType = inferBsonType(value);\n\t\t\tif (!fieldTypes.has(key)) {\n\t\t\t\tfieldTypes.set(key, new Set());\n\t\t\t\tfieldPresence.set(key, 0);\n\t\t\t}\n\t\t\tfieldTypes.get(key)?.add(bsonType);\n\t\t\tfieldPresence.set(key, (fieldPresence.get(key) ?? 0) + 1);\n\t\t}\n\t}\n\n\tconst properties: Record<string, unknown> = {};\n\tconst required: string[] = [];\n\n\tfor (const [field, types] of fieldTypes.entries()) {\n\t\tconst presence = fieldPresence.get(field) ?? 0;\n\t\tconst isRequired = presence === docs.length && docs.length > 0;\n\t\tconst typeList = Array.from(types).filter((t) => t !== \"null\");\n\t\tconst isNullable = types.has(\"null\") || presence < docs.length;\n\n\t\tif (isRequired && !isNullable) required.push(field);\n\n\t\tproperties[field] =\n\t\t\ttypeList.length === 1\n\t\t\t\t? { bsonType: isNullable ? [typeList[0], \"null\"] : typeList[0] }\n\t\t\t\t: { bsonType: isNullable ? [...typeList, \"null\"] : typeList };\n\t}\n\n\tconst schema = {\n\t\tcollection: tableName,\n\t\testimatedDocumentCount: totalDocs,\n\t\tsampledDocuments: docs.length,\n\t\tjsonSchema: {\n\t\t\tbsonType: \"object\",\n\t\t\trequired: required.length > 0 ? required : undefined,\n\t\t\tproperties,\n\t\t},\n\t};\n\n\treturn JSON.stringify(schema, null, 2);\n}\n","import type {\n\tDatabaseSchemaType,\n\tTableDataQuerySchemaType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { buildMongoFilters, buildMongoSort, normalizeMongoDocument } from \"./mongo.utils.js\";\n\nconst encodeCursor = (offset: number): string =>\n\tBuffer.from(JSON.stringify({ offset })).toString(\"base64url\");\n\nconst decodeCursor = (cursor?: string): number => {\n\tif (!cursor) return 0;\n\ttry {\n\t\tconst parsed = JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\")) as {\n\t\t\toffset?: number;\n\t\t};\n\t\treturn typeof parsed.offset === \"number\" ? parsed.offset : 0;\n\t} catch {\n\t\treturn 0;\n\t}\n};\n\nexport async function getTableData({\n\ttableName,\n\tcursor,\n\tlimit,\n\tdirection,\n\tsort,\n\torder,\n\tfilters,\n\tdb,\n}: {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: TableDataQuerySchemaType[\"direction\"];\n\tsort?: TableDataQuerySchemaType[\"sort\"];\n\torder?: TableDataQuerySchemaType[\"order\"];\n\tfilters?: TableDataQuerySchemaType[\"filters\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<TableDataResultSchemaType> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\tconst filterObject = buildMongoFilters(filters ?? []);\n\tconst sortObject = buildMongoSort(sort ?? \"\", order);\n\n\tconst safeLimit = limit && limit > 0 ? limit : 50;\n\tconst decodedCursor = decodeCursor(cursor);\n\tconst offset = Number.isFinite(decodedCursor) && decodedCursor >= 0 ? decodedCursor : 0;\n\tconst skip = direction === \"desc\" ? Math.max(offset - safeLimit, 0) : offset;\n\n\tconst [total, rows] = await Promise.all([\n\t\tcollection.countDocuments(filterObject),\n\t\tcollection.find(filterObject).sort(sortObject).skip(skip).limit(safeLimit).toArray(),\n\t]);\n\n\tconst normalizedRows = rows.map(\n\t\t(row) => normalizeMongoDocument(row) as Record<string, unknown>,\n\t);\n\tconst nextOffset = skip + safeLimit;\n\tconst prevOffset = Math.max(skip - safeLimit, 0);\n\n\treturn {\n\t\tdata: normalizedRows,\n\t\tmeta: {\n\t\t\tlimit: safeLimit,\n\t\t\ttotal,\n\t\t\thasNextPage: nextOffset < total,\n\t\t\thasPreviousPage: skip > 0,\n\t\t\tnextCursor: nextOffset < total ? encodeCursor(nextOffset) : null,\n\t\t\tprevCursor: skip > 0 ? encodeCursor(prevOffset) : null,\n\t\t},\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\nimport { canCoerceObjectId, toMongoId } from \"./mongo.utils.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst mongoDb = await getMongoDb(db);\n\tconst collection = mongoDb.collection(tableName);\n\n\tlet totalUpdated = 0;\n\tconst pkField = primaryKey || \"_id\";\n\tconst updatesByRow = new Map<unknown, Record<string, unknown>>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[pkField];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${pkField}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, {});\n\t\t}\n\t\tupdatesByRow.get(pkValue)![update.columnName] = update.value;\n\t}\n\n\tfor (const [pkValue, updateSet] of updatesByRow.entries()) {\n\t\tconst queryValue =\n\t\t\tpkField === \"_id\" && canCoerceObjectId(pkValue) ? toMongoId(pkValue) : pkValue;\n\n\t\tconst result = await collection.updateOne({ [pkField]: queryValue }, { $set: updateSet });\n\n\t\tif (result.matchedCount === 0) {\n\t\t\tthrow new HTTPException(404, {\n\t\t\t\tmessage: `Record with ${pkField} = ${String(pkValue)} not found in \"${tableName}\"`,\n\t\t\t});\n\t\t}\n\n\t\ttotalUpdated += result.modifiedCount;\n\t}\n\n\treturn { updatedCount: totalUpdated };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMssqlToDataType,\n\tstandardizeMssqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow {\n\tcolumnName: string;\n\tdataType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\nfunction parseCheckConstraintValues(checkClause: string): string[] | null {\n\t// Match all single-quoted string literals in the CHECK clause\n\t// e.g. ([status]='active' OR [status]='inactive') → ['active', 'inactive']\n\tconst matches = checkClause.match(/'([^']+)'/g);\n\tif (!matches || matches.length === 0) return null;\n\treturn matches.map((m) => m.slice(1, -1));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t CASE WHEN c.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t CASE \n\t\t WHEN pk.COLUMN_NAME IS NOT NULL THEN 1 \n\t\t ELSE 0 \n\t\t END AS isPrimaryKey,\n\t\t CASE \n\t\t WHEN fk.COLUMN_NAME IS NOT NULL THEN 1 \n\t\t ELSE 0 \n\t\t END AS isForeignKey,\n\t\t fk.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t fk.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM INFORMATION_SCHEMA.COLUMNS c\n\t\tLEFT JOIN (\n\t\t SELECT \n\t\t ku.TABLE_SCHEMA,\n\t\t ku.TABLE_NAME,\n\t\t ku.COLUMN_NAME\n\t\t FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t AND tc.TABLE_SCHEMA = ku.TABLE_SCHEMA\n\t\t AND tc.TABLE_NAME = ku.TABLE_NAME\n\t\t WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'\n\t\t) pk ON c.TABLE_SCHEMA = pk.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = pk.TABLE_NAME\n\t\t AND c.COLUMN_NAME = pk.COLUMN_NAME\n\t\tLEFT JOIN (\n\t\t SELECT \n\t\t ku.TABLE_SCHEMA,\n\t\t ku.TABLE_NAME,\n\t\t ku.COLUMN_NAME,\n\t\t ku2.TABLE_NAME AS REFERENCED_TABLE_NAME,\n\t\t ku2.COLUMN_NAME AS REFERENCED_COLUMN_NAME\n\t\t FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t ON rc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t AND rc.CONSTRAINT_SCHEMA = ku.TABLE_SCHEMA\n\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku2\n\t\t ON rc.UNIQUE_CONSTRAINT_NAME = ku2.CONSTRAINT_NAME\n\t\t AND rc.UNIQUE_CONSTRAINT_SCHEMA = ku2.TABLE_SCHEMA\n\t\t) fk ON c.TABLE_SCHEMA = fk.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = fk.TABLE_NAME\n\t\t AND c.COLUMN_NAME = fk.COLUMN_NAME\n\t\tWHERE c.TABLE_CATALOG = DB_NAME()\n\t\t AND c.TABLE_NAME = @tableName\n\t\t AND c.TABLE_SCHEMA = 'dbo'\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst result = await pool.request().input(\"tableName\", tableName).query(query);\n\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Fetch CHECK constraints to simulate enum values\n\tconst checkResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\tSELECT\n\t\t cc.COLUMN_NAME AS columnName,\n\t\t chk.CHECK_CLAUSE AS checkClause\n\t\tFROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS chk\n\t\tJOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc\n\t\t ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME\n\t\t AND cc.TABLE_SCHEMA = 'dbo'\n\t\tWHERE cc.TABLE_NAME = @tableName\n\t\t AND cc.TABLE_CATALOG = DB_NAME()\n\t`);\n\n\tconst checkEnumMap = new Map<string, string[]>();\n\tfor (const row of checkResult.recordset as { columnName: string; checkClause: string }[]) {\n\t\tconst values = parseCheckConstraintValues(row.checkClause);\n\t\tif (values) {\n\t\t\tcheckEnumMap.set(row.columnName, values);\n\t\t}\n\t}\n\n\treturn (result.recordset as ColumnRow[]).map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst enumValues = checkEnumMap.get(r.columnName) ?? null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: enumValues ? \"enum\" : mapMssqlToDataType(dataType),\n\t\t\tdataTypeLabel: enumValues ? \"enum\" : standardizeMssqlDataTypeLabel(dataType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = await getMssqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\t// Fetch identity columns and exclude them from the insert\n\tconst identityResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(\n\t\t\t`SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1`,\n\t\t);\n\tconst identityColumns = new Set(\n\t\t(identityResult.recordset as { name: string }[]).map((r) => r.name),\n\t);\n\n\tconst columns = Object.keys(data).filter((col) => !identityColumns.has(col));\n\tconst values = columns.map((col) => {\n\t\tconst value = data[col];\n\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst columnNames = columns.map((col) => `[${col}]`).join(\", \");\n\tconst paramNames = columns.map((_col, idx) => `@param${idx}`).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO [${tableName}] (${columnNames})\n\t\tVALUES (${paramNames})\n\t`;\n\n\tconst request = pool.request();\n\tcolumns.forEach((_col, idx) => {\n\t\trequest.input(`param${idx}`, values[idx]);\n\t});\n\n\tconst result = await request.query(query);\n\n\tif (result.rowsAffected[0] === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowsAffected[0] ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = await getMssqlPool(db);\n\tconst transaction = pool.transaction();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `[${col}]`).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait transaction.begin();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst request = transaction.request();\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\n\t\t\tconst paramNames = columns.map((_, idx) => `@p${i}_${idx}`).join(\", \");\n\t\t\tcolumns.forEach((_col, idx) => {\n\t\t\t\trequest.input(`p${i}_${idx}`, values[idx]);\n\t\t\t});\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO [${tableName}] (${columnNames})\n\t\t\t\tVALUES (${paramNames})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait request.query(insertSQL);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait transaction.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t}\n};\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n/**\n * Formats default values for SQL Server compatibility\n */\nfunction formatMssqlDefaultValue(defaultValue: string, columnType: string): string | null {\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Function calls\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\tif (trimmed.includes(\"newid()\")) {\n\t\t\t// NEWID() for uniqueidentifier columns\n\t\t\tif (!columnType.toUpperCase().includes(\"UNIQUEIDENTIFIER\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"NEWID()\";\n\t\t}\n\n\t\tif (trimmed.includes(\"getdate\") || trimmed.includes(\"current_timestamp\")) {\n\t\t\treturn \"GETDATE()\";\n\t\t}\n\n\t\treturn defaultValue.trim();\n\t}\n\n\t// Keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PostgreSQL-style column types to SQL Server types\n */\nfunction mapColumnTypeToMssql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// SQL Server doesn't support native array types — use NVARCHAR(MAX) for JSON\n\t\treturn \"NVARCHAR(MAX)\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT IDENTITY(1,1)\",\n\t\tserial4: \"INT IDENTITY(1,1)\",\n\t\tbigserial: \"BIGINT IDENTITY(1,1)\",\n\t\tserial8: \"BIGINT IDENTITY(1,1)\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\ttinyint: \"TINYINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"NUMERIC\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"REAL\",\n\t\tfloat4: \"REAL\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"FLOAT\",\n\t\tfloat8: \"FLOAT\",\n\t\tmoney: \"MONEY\",\n\t\t// Boolean\n\t\tboolean: \"BIT\",\n\t\tbool: \"BIT\",\n\t\t// Text\n\t\ttext: \"NVARCHAR(MAX)\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"UNIQUEIDENTIFIER\",\n\t\t// JSON\n\t\tjson: \"NVARCHAR(MAX)\",\n\t\tjsonb: \"NVARCHAR(MAX)\",\n\t\txml: \"XML\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME2\",\n\t\t\"timestamp without time zone\": \"DATETIME2\",\n\t\t\"timestamp with time zone\": \"DATETIMEOFFSET\",\n\t\ttimestamptz: \"DATETIMEOFFSET\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"VARBINARY(MAX)\",\n\t\t// Network / geometric — store as text in SQL Server\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = await getMssqlPool(db);\n\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tconst mappedType = mapColumnTypeToMssql(field.columnType, field.isArray ?? false);\n\t\tlet columnDef = `[${field.columnName}] ${mappedType}`;\n\n\t\t// NOT NULL\n\t\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Default value (skip for IDENTITY columns)\n\t\tif (field.defaultValue && !mappedType.includes(\"IDENTITY\")) {\n\t\t\tconst defaultValue = formatMssqlDefaultValue(field.defaultValue, mappedType);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t\t}\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `[${f.columnName}]`).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(`UNIQUE ([${field.columnName}])`);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `FK_${tableName}_${fk.columnName}`;\n\t\t\treturn `CONSTRAINT [${constraintName}] FOREIGN KEY ([${fk.columnName}]) REFERENCES [${fk.referencedTable}] ([${fk.referencedColumn}]) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE [${tableName}] (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t)\n\t`;\n\n\tawait pool.request().query(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases on the SQL Server instance.\n * Returns name, size (human-readable), owner (connected user), and encoding (collation).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = await getMssqlPool();\n\n\tconst result = await pool.request().query(`\n\t\tSELECT\n\t\t d.name AS name,\n\t\t CAST(\n\t\t ROUND(\n\t\t CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)),\n\t\t 2\n\t\t ) AS VARCHAR(20)\n\t\t ) + ' MB' AS size,\n\t\t SUSER_SNAME(d.owner_sid) AS owner,\n\t\t d.collation_name AS encoding\n\t\tFROM sys.databases d\n\t\tJOIN sys.master_files mf ON d.database_id = mf.database_id\n\t\tWHERE d.database_id > 4 -- Exclude system databases\n\t\tGROUP BY d.name, d.owner_sid, d.collation_name\n\t\tORDER BY d.name\n\t`);\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn result.recordset as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = await getMssqlPool();\n\tconst result = await pool.request().query(\"SELECT DB_NAME() AS db\");\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn result.recordset[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for SQL Server.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = await getMssqlPool();\n\n\tconst result = await pool.request().query(`\n\t\tSELECT\n\t\t @@VERSION AS version,\n\t\t DB_NAME() AS database_name,\n\t\t SUSER_NAME() AS [user],\n\t\t @@SERVERNAME AS host,\n\t\t (SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID) AS port,\n\t\t @@MAX_CONNECTIONS AS max_connections,\n\t\t (SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections\n\t`);\n\n\tif (!result.recordset[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = result.recordset[0] as Record<string, string | number>;\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: Number(info.active_connections ?? 0),\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a SQL Server table using ALTER TABLE DROP COLUMN\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = await getMssqlPool(db);\n\n\t// Check table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst columnCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.input(\"columnName\", columnName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.COLUMNS\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND COLUMN_NAME = @columnName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst columnExists = Number(columnCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst result = await pool\n\t\t.request()\n\t\t.query(`ALTER TABLE [${tableName}] DROP COLUMN [${columnName}]`);\n\n\treturn { deletedCount: result.rowsAffected[0] ?? 1 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n// SQL Server FK violation error number\nconst MSSQL_FK_VIOLATION = 547;\n\ninterface FkConstraintRow {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n}\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT\n\t\t\t\tfk.name AS constraint_name,\n\t\t\t\tOBJECT_NAME(fk.parent_object_id) AS referencing_table,\n\t\t\t\tCOL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS referencing_column,\n\t\t\t\tOBJECT_NAME(fk.referenced_object_id) AS referenced_table,\n\t\t\t\tCOL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n\t\t\tFROM sys.foreign_keys fk\n\t\t\tINNER JOIN sys.foreign_key_columns fkc\n\t\t\t\tON fk.object_id = fkc.constraint_object_id\n\t\t\tWHERE OBJECT_NAME(fk.referenced_object_id) = @tableName\n\t\t`);\n\n\treturn (result.recordset as FkConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = await getMssqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst request = pool.request();\n\t\tpkValues.forEach((value, idx) => {\n\t\t\trequest.input(`pk${idx}`, value);\n\t\t});\n\t\tconst paramList = pkValues.map((_, idx) => `@pk${idx}`).join(\", \");\n\n\t\tconst relatedResult = await request.query(`\n\t\t\tSELECT TOP 100 * FROM [${constraint.referencingTable}]\n\t\t\tWHERE [${constraint.referencingColumn}] IN (${paramList})\n\t\t`);\n\n\t\tif (relatedResult.recordset.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.recordset as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tconst request = transaction.request();\n\t\tpkValues.forEach((value, idx) => {\n\t\t\trequest.input(`pk${idx}`, value);\n\t\t});\n\t\tconst paramList = pkValues.map((_, idx) => `@pk${idx}`).join(\", \");\n\n\t\tconst result = await request.query(\n\t\t\t`DELETE FROM [${tableName}] WHERE [${pkColumn}] IN (${paramList})`,\n\t\t);\n\n\t\tawait transaction.commit();\n\t\treturn {\n\t\t\tdeletedCount: result.rowsAffected[0] ?? 0,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error: any) {\n\t\tawait transaction.rollback();\n\n\t\tif (error.number === MSSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst selectRequest = transaction.request();\n\t\t\t\tvalues.forEach((val, idx) => {\n\t\t\t\t\tselectRequest.input(`val${idx}`, val);\n\t\t\t\t});\n\t\t\t\tconst selectParamList = values.map((_, idx) => `@val${idx}`).join(\", \");\n\n\t\t\t\tconst selectResult = await selectRequest.query(`\n\t\t\t\t\tSELECT [${nestedFk.referencedColumn}] FROM [${targetTable}]\n\t\t\t\t\tWHERE [${targetColumn}] IN (${selectParamList})\n\t\t\t\t`);\n\n\t\t\t\tconst nestedValues = (selectResult.recordset as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deleteRequest = transaction.request();\n\t\t\tvalues.forEach((val, idx) => {\n\t\t\t\tdeleteRequest.input(`delVal${idx}`, val);\n\t\t\t});\n\t\t\tconst deleteParamList = values.map((_, idx) => `@delVal${idx}`).join(\", \");\n\n\t\t\tconst deleteResult = await deleteRequest.query(\n\t\t\t\t`DELETE FROM [${targetTable}] WHERE [${targetColumn}] IN (${deleteParamList})`,\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.rowsAffected[0] ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainRequest = transaction.request();\n\t\tpkValues.forEach((val, idx) => {\n\t\t\tmainRequest.input(`mainPk${idx}`, val);\n\t\t});\n\t\tconst mainParamList = pkValues.map((_, idx) => `@mainPk${idx}`).join(\", \");\n\n\t\tconst result = await mainRequest.query(\n\t\t\t`DELETE FROM [${tableName}] WHERE [${pkColumn}] IN (${mainParamList})`,\n\t\t);\n\n\t\tawait transaction.commit();\n\n\t\treturn { deletedCount: (result.rowsAffected[0] ?? 0) + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\n// SQL Server error number for FK dependency\nconst MSSQL_FK_DEPENDENCY = 3726;\n\ninterface FkConstraintRow {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n}\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT\n\t\t\t\tfk.name AS constraint_name,\n\t\t\t\tOBJECT_NAME(fk.parent_object_id) AS referencing_table,\n\t\t\t\tCOL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS referencing_column,\n\t\t\t\tOBJECT_NAME(fk.referenced_object_id) AS referenced_table,\n\t\t\t\tCOL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n\t\t\tFROM sys.foreign_keys fk\n\t\t\tINNER JOIN sys.foreign_key_columns fkc\n\t\t\t\tON fk.object_id = fkc.constraint_object_id\n\t\t\tWHERE OBJECT_NAME(fk.referenced_object_id) = @tableName\n\t\t`);\n\n\treturn (result.recordset as FkConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = await getMssqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedResult = await pool\n\t\t\t.request()\n\t\t\t.query(`SELECT TOP 100 * FROM [${constraint.referencingTable}]`);\n\n\t\tif (relatedResult.recordset.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.recordset as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool.request().query(`SELECT COUNT(*) as count FROM [${tableName}]`);\n\treturn Number(result.recordset[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = await getMssqlPool(db);\n\n\t// Check if table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// Drop all FK constraints referencing this table first\n\t\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\t\tfor (const fk of fkConstraints) {\n\t\t\t\tawait pool\n\t\t\t\t\t.request()\n\t\t\t\t\t.query(\n\t\t\t\t\t\t`ALTER TABLE [${fk.referencingTable}] DROP CONSTRAINT [${fk.constraintName}]`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait pool.request().query(`DROP TABLE [${tableName}]`);\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error: any) {\n\t\tif (error.number === MSSQL_FK_DEPENDENCY) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = await getMssqlPool(db);\n\tconst result = await pool.request().query(`SELECT * FROM [${tableName}]`);\n\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(result.recordset[0]);\n\n\treturn { cols, rows: result.recordset as Record<string, CellValue>[] };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = await getMssqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.request().query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\t// Check if query returned data (SELECT-like)\n\tif (result.recordset) {\n\t\tconst rows = result.recordset as Record<string, unknown>[];\n\t\tconst columns = result.recordset.columns\n\t\t\t? Object.keys(result.recordset.columns)\n\t\t\t: Object.keys(rows[0] ?? {});\n\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows,\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: result.rowsAffected[0] ?? 0,\n\t\tduration,\n\t\tmessage: `OK — ${result.rowsAffected[0] ?? 0} row(s) affected`,\n\t};\n};\n","import type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = await getMssqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name AS tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_catalog = DB_NAME()\n\t\t AND table_type = 'BASE TABLE'\n\t\t AND table_schema = 'dbo'\n\t\tORDER BY table_name\n\t`;\n\n\tconst result = await pool.request().query(tablesQuery);\n\tif (!result.recordset || result.recordset.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst tablesList: TableInfoSchemaType[] = await Promise.all(\n\t\t(result.recordset as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst countResult = await pool\n\t\t\t\t.request()\n\t\t\t\t.query(`SELECT COUNT(*) as count FROM [${table.tableName}]`);\n\t\t\tconst countRow = countResult.recordset[0] as { count: number };\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn tablesList;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = await getMssqlPool(db);\n\n\t// Check if table exists\n\tconst tableCheckResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT COUNT(*) as cnt\n\t\t\tFROM INFORMATION_SCHEMA.TABLES\n\t\t\tWHERE TABLE_CATALOG = DB_NAME()\n\t\t\t AND TABLE_NAME = @tableName\n\t\t\t AND TABLE_SCHEMA = 'dbo'\n\t\t`);\n\n\tconst tableExists = Number(tableCheckResult.recordset[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get table schema using sp_help which provides comprehensive table information\n\t// Note: We could also use INFORMATION_SCHEMA or sys.columns for more structured output\n\tconst schemaResult = await pool\n\t\t.request()\n\t\t.input(\"tableName\", tableName)\n\t\t.query(`\n\t\t\tSELECT \n\t\t\t c.COLUMN_NAME,\n\t\t\t c.DATA_TYPE,\n\t\t\t c.CHARACTER_MAXIMUM_LENGTH,\n\t\t\t c.NUMERIC_PRECISION,\n\t\t\t c.NUMERIC_SCALE,\n\t\t\t c.IS_NULLABLE,\n\t\t\t c.COLUMN_DEFAULT,\n\t\t\t CASE \n\t\t\t WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY'\n\t\t\t WHEN fk.COLUMN_NAME IS NOT NULL THEN 'FOREIGN KEY'\n\t\t\t ELSE ''\n\t\t\t END AS KEY_TYPE,\n\t\t\t fk.REFERENCED_TABLE_NAME,\n\t\t\t fk.REFERENCED_COLUMN_NAME\n\t\t\tFROM INFORMATION_SCHEMA.COLUMNS c\n\t\t\tLEFT JOIN (\n\t\t\t SELECT ku.TABLE_SCHEMA, ku.TABLE_NAME, ku.COLUMN_NAME\n\t\t\t FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t\t ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t\t WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'\n\t\t\t) pk ON c.TABLE_SCHEMA = pk.TABLE_SCHEMA\n\t\t\t AND c.TABLE_NAME = pk.TABLE_NAME\n\t\t\t AND c.COLUMN_NAME = pk.COLUMN_NAME\n\t\t\tLEFT JOIN (\n\t\t\t SELECT \n\t\t\t ku.TABLE_SCHEMA,\n\t\t\t ku.TABLE_NAME,\n\t\t\t ku.COLUMN_NAME,\n\t\t\t ku2.TABLE_NAME AS REFERENCED_TABLE_NAME,\n\t\t\t ku2.COLUMN_NAME AS REFERENCED_COLUMN_NAME\n\t\t\t FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku\n\t\t\t ON rc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME\n\t\t\t JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku2\n\t\t\t ON rc.UNIQUE_CONSTRAINT_NAME = ku2.CONSTRAINT_NAME\n\t\t\t) fk ON c.TABLE_SCHEMA = fk.TABLE_SCHEMA\n\t\t\t AND c.TABLE_NAME = fk.TABLE_NAME\n\t\t\t AND c.COLUMN_NAME = fk.COLUMN_NAME\n\t\t\tWHERE c.TABLE_CATALOG = DB_NAME()\n\t\t\t AND c.TABLE_NAME = @tableName\n\t\t\t AND c.TABLE_SCHEMA = 'dbo'\n\t\t\tORDER BY c.ORDINAL_POSITION\n\t\t`);\n\n\tif (!schemaResult.recordset || schemaResult.recordset.length === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Build a CREATE TABLE statement from the schema information\n\tconst columns = schemaResult.recordset.map((col: any) => {\n\t\tlet columnDef = ` [${col.COLUMN_NAME}] ${col.DATA_TYPE}`;\n\n\t\t// Add length/precision\n\t\tif (col.CHARACTER_MAXIMUM_LENGTH) {\n\t\t\tcolumnDef +=\n\t\t\t\tcol.CHARACTER_MAXIMUM_LENGTH === -1 ? \"(MAX)\" : `(${col.CHARACTER_MAXIMUM_LENGTH})`;\n\t\t} else if (col.NUMERIC_PRECISION) {\n\t\t\tif (col.NUMERIC_SCALE) {\n\t\t\t\tcolumnDef += `(${col.NUMERIC_PRECISION},${col.NUMERIC_SCALE})`;\n\t\t\t} else {\n\t\t\t\tcolumnDef += `(${col.NUMERIC_PRECISION})`;\n\t\t\t}\n\t\t}\n\n\t\t// Add NULL/NOT NULL\n\t\tcolumnDef += col.IS_NULLABLE === \"YES\" ? \" NULL\" : \" NOT NULL\";\n\n\t\t// Add default\n\t\tif (col.COLUMN_DEFAULT) {\n\t\t\tcolumnDef += ` DEFAULT ${col.COLUMN_DEFAULT}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\tconst createTableSql = `CREATE TABLE [${tableName}] (\\n${columns.join(\",\\n\")}\\n)`;\n\n\treturn createTableSql;\n}\n","import type {\n\tDatabaseSchemaType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: any[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\n/**\n * Simplified implementation of getTableData for SQL Server\n * This version supports basic pagination with OFFSET/FETCH and simple sorting\n *\n * Note: A full implementation would include:\n * - Cursor-based pagination\n * - Complex filtering\n * - Multiple sort columns\n * - Foreign key relationships\n */\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = await getMssqlPool(db);\n\n\t// Basic implementation: Use OFFSET/FETCH for pagination\n\t// Parse cursor as page number (simplified)\n\tconst page = cursor ? Number.parseInt(cursor, 10) : 0;\n\tconst offset = page * limit;\n\n\t// Build sort clause\n\tlet sortClause = \"\";\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tconst sortParts = sort.map((s) => `[${s.columnName}] ${s.direction.toUpperCase()}`);\n\t\tsortClause = `ORDER BY ${sortParts.join(\", \")}`;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortClause = `ORDER BY [${sort}] ${order.toUpperCase()}`;\n\t} else {\n\t\t// Default sort - use first column or (SELECT NULL)\n\t\tsortClause = \"ORDER BY (SELECT NULL)\";\n\t}\n\n\t// Get total count\n\tconst countResult = await pool\n\t\t.request()\n\t\t.query(`SELECT COUNT(*) as total FROM [${tableName}]`);\n\tconst totalRows = Number(countResult.recordset[0]?.total ?? 0);\n\n\t// Get paginated data\n\tconst dataResult = await pool.request().query(`\n\t\tSELECT *\n\t\tFROM [${tableName}]\n\t\t${sortClause}\n\t\tOFFSET ${offset} ROWS\n\t\tFETCH NEXT ${limit + 1} ROWS ONLY\n\t`);\n\n\tlet rows = dataResult.recordset as Record<string, unknown>[];\n\tconst hasMore = rows.length > limit;\n\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tconst nextCursor = hasMore ? String(page + 1) : null;\n\tconst prevCursor = page > 0 ? String(page - 1) : null;\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: hasMore,\n\t\t\thasPreviousPage: page > 0,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMssqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mssql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = await getMssqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst transaction = pool.transaction();\n\tawait transaction.begin();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, idx) => `[${u.columnName}] = @value${idx}`);\n\t\t\tconst request = transaction.request();\n\n\t\t\trowUpdates.forEach((u, idx) => {\n\t\t\t\tlet value = u.value;\n\t\t\t\tif (value !== null && typeof value === \"object\") {\n\t\t\t\t\tvalue = JSON.stringify(value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof value === \"string\") {\n\t\t\t\t\tvalue = value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\trequest.input(`value${idx}`, value);\n\t\t\t});\n\n\t\t\trequest.input(\"pkValue\", pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE [${tableName}]\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE [${primaryKey}] = @pkValue\n\t\t\t`;\n\n\t\t\tconst result = await request.query(query);\n\n\t\t\tif (result.rowsAffected[0] === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowsAffected[0] ?? 0;\n\t\t}\n\n\t\tawait transaction.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait transaction.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMysqlToDataType,\n\tstandardizeMysqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow extends RowDataPacket {\n\tcolumnName: string;\n\tdataType: string;\n\tcolumnType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\n/**\n * Parse MySQL enum/set values from COLUMN_TYPE, e.g. \"enum('a','b','c')\" → [\"a\",\"b\",\"c\"]\n */\nfunction parseMysqlEnumValues(columnType: string): string[] | null {\n\tconst match = columnType.match(/^(?:enum|set)\\((.+)\\)$/i);\n\tif (!match?.[1]) return null;\n\treturn match[1].split(\",\").map((v) => v.trim().replace(/^'|'$/g, \"\"));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t c.COLUMN_TYPE AS columnType,\n\t\t (c.IS_NULLABLE = 'YES') AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t (c.COLUMN_KEY = 'PRI') AS isPrimaryKey,\n\t\t (kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,\n\t\t kcu.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t kcu.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM information_schema.COLUMNS c\n\t\tLEFT JOIN information_schema.KEY_COLUMN_USAGE kcu\n\t\t ON c.TABLE_SCHEMA = kcu.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = kcu.TABLE_NAME\n\t\t AND c.COLUMN_NAME = kcu.COLUMN_NAME\n\t\t AND kcu.REFERENCED_TABLE_NAME IS NOT NULL\n\t\tWHERE c.TABLE_SCHEMA = DATABASE()\n\t\t AND c.TABLE_NAME = ?\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst [rows] = await pool.execute<ColumnRow[]>(query, [tableName]);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst columnType = r.columnType as string;\n\t\tconst isEnum = dataType === \"enum\" || dataType === \"set\";\n\t\tconst enumValues = isEnum ? parseMysqlEnumValues(columnType) : null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapMysqlToDataType(dataType, columnType),\n\t\t\tdataTypeLabel: standardizeMysqlDataTypeLabel(dataType, columnType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data).map((value, index) => {\n\t\tconst columnName = columns[index];\n\t\tif (booleanColumns.has(columnName) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\tVALUES (${placeholders})\n\t`;\n\n\tconst [result] = await pool.execute<ResultSetHeader>(query, values);\n\n\tif (result.affectedRows === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getMysqlPool(db);\n\tconst connection = await pool.getConnection();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait connection.beginTransaction();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\t\tawait connection.execute<ResultSetHeader>(insertSQL, values as any);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait connection.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait connection.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n};\n","type MysqlColumnDefinitionInput = {\n\tcolumnName: string;\n\tcolumnType: string;\n\tdefaultValue?: string | null;\n\tisPrimaryKey?: boolean;\n\tisNullable?: boolean;\n\tisUnique?: boolean;\n\tisIdentity?: boolean;\n\tisArray?: boolean;\n};\n\ntype BuildMysqlColumnDefinitionOptions = {\n\tincludePrimaryKey?: boolean;\n\tincludeUnique?: boolean;\n\tpreserveAutoIncrement?: boolean;\n};\n\n/**\n * Formats default values for MySQL compatibility.\n * MySQL requires function calls in DEFAULT clauses to be wrapped in parentheses.\n */\nexport function formatMysqlDefaultValue(\n\tdefaultValue: string | null | undefined,\n\tcolumnType: string,\n): string | null {\n\tif (!defaultValue?.trim()) {\n\t\treturn null;\n\t}\n\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Check if it's a function call (contains parentheses)\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\t// MySQL 8.0+ requires function calls to be wrapped in parentheses for DEFAULT\n\t\t// But UUID() returns a string, not compatible with INT columns\n\t\tif (trimmed.includes(\"uuid()\")) {\n\t\t\t// UUID() only makes sense for CHAR(36) or VARCHAR columns\n\t\t\tif (\n\t\t\t\t!columnType.toUpperCase().includes(\"CHAR\") &&\n\t\t\t\t!columnType.toUpperCase().includes(\"TEXT\")\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"(UUID())\";\n\t\t}\n\n\t\t// Other function calls like CURRENT_TIMESTAMP, NOW(), etc.\n\t\tif (trimmed.includes(\"current_timestamp\") || trimmed.includes(\"now()\")) {\n\t\t\treturn \"(CURRENT_TIMESTAMP)\";\n\t\t}\n\n\t\tif (trimmed.includes(\"current_date\")) {\n\t\t\treturn \"(CURRENT_DATE)\";\n\t\t}\n\n\t\t// Wrap other function calls in parentheses\n\t\treturn `(${defaultValue.trim()})`;\n\t}\n\n\t// For non-function defaults (literals), return as-is\n\t// Handle special keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\t// Return the value as-is (could be a number, quoted string, etc.)\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PG-style column types from the UI schema to MySQL-compatible types.\n * The UI uses PostgreSQL-style type names, so we translate them for MySQL.\n */\nexport function mapColumnTypeToMysql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// MySQL does not support native array types - use JSON as fallback\n\t\treturn \"JSON\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT AUTO_INCREMENT\",\n\t\tserial4: \"INT AUTO_INCREMENT\",\n\t\tbigserial: \"BIGINT AUTO_INCREMENT\",\n\t\tserial8: \"BIGINT AUTO_INCREMENT\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"DECIMAL\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"FLOAT\",\n\t\tfloat4: \"FLOAT\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"DOUBLE\",\n\t\tfloat8: \"DOUBLE\",\n\t\tmoney: \"DECIMAL(19, 4)\",\n\t\t// Boolean\n\t\tboolean: \"TINYINT(1)\",\n\t\tbool: \"TINYINT(1)\",\n\t\t// Text\n\t\ttext: \"LONGTEXT\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"CHAR(36)\",\n\t\t// JSON\n\t\tjson: \"JSON\",\n\t\tjsonb: \"JSON\",\n\t\txml: \"LONGTEXT\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME\",\n\t\t\"timestamp without time zone\": \"DATETIME\",\n\t\t\"timestamp with time zone\": \"DATETIME\",\n\t\ttimestamptz: \"DATETIME\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"LONGBLOB\",\n\t\t// Network / geometric - store as text in MySQL\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t\tpoint: \"POINT\",\n\t\tline: \"LINESTRING\",\n\t\tpolygon: \"POLYGON\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport function buildMysqlColumnDefinition(\n\tfield: MysqlColumnDefinitionInput,\n\toptions: BuildMysqlColumnDefinitionOptions = {},\n): string {\n\tconst mappedType = mapColumnTypeToMysql(field.columnType, field.isArray ?? false);\n\tlet columnDef = `\\`${field.columnName}\\` ${mappedType}`;\n\n\t// NOT NULL\n\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\tcolumnDef += \" NOT NULL\";\n\t}\n\n\t// Default value (skip for AUTO_INCREMENT columns)\n\tif (field.defaultValue && !mappedType.includes(\"AUTO_INCREMENT\")) {\n\t\tconst defaultValue = formatMysqlDefaultValue(field.defaultValue, mappedType);\n\t\tif (defaultValue !== null) {\n\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t}\n\t}\n\n\t// isIdentity -> AUTO_INCREMENT (already embedded in type map via SERIAL mapping)\n\tif (\n\t\t(field.isIdentity || options.preserveAutoIncrement) &&\n\t\t!mappedType.includes(\"AUTO_INCREMENT\")\n\t) {\n\t\tcolumnDef += \" AUTO_INCREMENT\";\n\t}\n\n\tif (options.includeUnique && field.isUnique && !field.isPrimaryKey) {\n\t\tcolumnDef += \" UNIQUE\";\n\t}\n\n\tif (options.includePrimaryKey && field.isPrimaryKey) {\n\t\tcolumnDef += \" PRIMARY KEY\";\n\t}\n\n\treturn columnDef;\n}\n","import type { ResultSetHeader } from \"mysql2\";\nimport type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getMysqlPool(db);\n\n\tconst columnDefinitions = fields.map((field) => buildMysqlColumnDefinition(field));\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `\\`${f.columnName}\\``).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(\n\t\t\t\t`UNIQUE KEY \\`uq_${tableName}_${field.columnName}\\` (\\`${field.columnName}\\`)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \\`${constraintName}\\` FOREIGN KEY (\\`${fk.columnName}\\`) REFERENCES \\`${fk.referencedTable}\\` (\\`${fk.referencedColumn}\\`) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE \\`${tableName}\\` (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci\n\t`;\n\n\tawait pool.execute<ResultSetHeader>(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases (schemas) on the MySQL server.\n * Returns name, size (human-readable), owner (connected user), and encoding (charset).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getMysqlPool();\n\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t s.SCHEMA_NAME AS name,\n\t\t CONCAT(\n\t\t ROUND(\n\t\t COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024,\n\t\t 2\n\t\t ),\n\t\t ' MB'\n\t\t ) AS size,\n\t\t CURRENT_USER() AS owner,\n\t\t s.DEFAULT_CHARACTER_SET_NAME AS encoding\n\t\tFROM information_schema.SCHEMATA s\n\t\tLEFT JOIN information_schema.TABLES t\n\t\t ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n\t\tGROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME\n\t\tORDER BY s.SCHEMA_NAME\n\t`);\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn rows as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getMysqlPool();\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\"SELECT DATABASE() AS db\");\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn (rows as Array<{ db: string }>)[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for MySQL.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getMysqlPool();\n\n\tconst [infoRows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t VERSION() AS version,\n\t\t DATABASE() AS database_name,\n\t\t CURRENT_USER() AS user,\n\t\t @@hostname AS host,\n\t\t @@port AS port,\n\t\t @@max_connections AS max_connections\n\t`);\n\n\tconst [connRows] = await pool.execute<RowDataPacket[]>(\n\t\t\"SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST\",\n\t);\n\n\tif (!infoRows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = (infoRows as Array<Record<string, string | number>>)[0];\n\tconst activeConnections = Number((connRows as Array<{ cnt: number }>)[0]?.cnt ?? 0);\n\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: activeConnections,\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a MySQL table using ALTER TABLE DROP COLUMN.\n * Note: MySQL does not support CASCADE/RESTRICT on DROP COLUMN — the cascade param is accepted\n * for API compatibility but does not change behavior.\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [result] = await pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` DROP COLUMN \\`${columnName}\\``,\n\t);\n\n\treturn { deletedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL FK violation error number\nconst MYSQL_FK_VIOLATION = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\`\n\t\t\t WHERE \\`${constraint.referencingColumn}\\` IN (${placeholders})\n\t\t\t LIMIT 100`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${placeholders})`,\n\t\t\tpkValues,\n\t\t);\n\t\tawait connection.commit();\n\t\treturn { deletedCount: result.affectedRows, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (mysqlError.errno === MYSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\t// Disable FK checks temporarily for cascade delete\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst nestedPlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\t\tconst [selectRows] = await connection.execute<RowDataPacket[]>(\n\t\t\t\t\t`SELECT \\`${nestedFk.referencedColumn}\\` FROM \\`${targetTable}\\`\n\t\t\t\t\t WHERE \\`${targetColumn}\\` IN (${nestedPlaceholders})`,\n\t\t\t\t\tvalues as any[],\n\t\t\t\t);\n\t\t\t\tconst nestedValues = (selectRows as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deletePlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\tconst [deleteResult] = await connection.execute<ResultSetHeader>(\n\t\t\t\t`DELETE FROM \\`${targetTable}\\` WHERE \\`${targetColumn}\\` IN (${deletePlaceholders})`,\n\t\t\t\tvalues as any[],\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.affectedRows;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainPlaceholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${mainPlaceholders})`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\tawait connection.commit();\n\n\t\treturn { deletedCount: result.affectedRows + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL error number for FK dependency preventing DROP TABLE\nconst MYSQL_FK_DEPENDENCY = 1217;\nconst MYSQL_FK_ROW_REFERENCED = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\` LIMIT 100`,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as count FROM \\`${tableName}\\``,\n\t);\n\treturn Number((rows as Array<{ count: number }>)[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// MySQL doesn't support CASCADE on DROP TABLE natively the same way PG does.\n\t\t\t// We disable FK checks, drop the table, then re-enable.\n\t\t\tconst connection = await pool.getConnection();\n\t\t\ttry {\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\t\t\t\tawait connection.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\t\t} finally {\n\t\t\t\tconnection.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait pool.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t}\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\t// Re-enable FK checks in case we disabled them\n\t\tawait pool.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (\n\t\t\tmysqlError.errno === MYSQL_FK_DEPENDENCY ||\n\t\t\tmysqlError.errno === MYSQL_FK_ROW_REFERENCED\n\t\t) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SELECT * FROM \\`${tableName}\\``);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows: rows as Record<string, CellValue>[] };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { FieldPacket, ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getMysqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\t// mysql2 returns [rows, fields] for SELECT and [ResultSetHeader, fields] for DML\n\tconst [result, fields] = (await pool.execute(cleanedQuery)) as [\n\t\tRowDataPacket[] | ResultSetHeader,\n\t\tFieldPacket[],\n\t];\n\tconst duration = performance.now() - startTime;\n\n\t// SELECT-like results have an array of rows\n\tif (Array.isArray(result)) {\n\t\tconst rows = result as RowDataPacket[];\n\t\tconst columns = fields ? fields.map((f) => f.name) : Object.keys(rows[0] ?? {});\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows: rows as Record<string, unknown>[],\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\tconst dmlResult = result as ResultSetHeader;\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: dmlResult.affectedRows,\n\t\tduration,\n\t\tmessage: `OK — ${dmlResult.affectedRows} row(s) affected`,\n\t};\n};\n","import type { RowDataPacket } from \"mysql2\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name as tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = DATABASE()\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name\n\t`;\n\n\tconst [tables] = await pool.execute<RowDataPacket[]>(tablesQuery);\n\tif (!tables || tables.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\t(tables as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t\t`SELECT COUNT(*) as count FROM \\`${table.tableName}\\``,\n\t\t\t);\n\t\t\tconst countRow = (countRows as Array<{ count: number }>)[0];\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// SHOW CREATE TABLE returns the full DDL including column types, indexes, FK constraints\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SHOW CREATE TABLE \\`${tableName}\\``);\n\tconst row = (rows as Array<Record<string, string>>)[0];\n\n\t// The result row has \"Create Table\" key\n\tconst createTableSql = row?.[\"Create Table\"] ?? row?.create_table ?? \"\";\n\tif (!createTableSql) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn createTableSql;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\n/**\n * MySQL-specific WHERE clause builder.\n * Uses ? placeholders and backtick identifiers.\n * ILIKE/NOT ILIKE map to LIKE/NOT LIKE (MySQL is case-insensitive by default on most collations).\n */\nexport function buildWhereClauseMysql(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst columnName = `\\`${filter.columnName}\\``;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\tcase \"ilike\":\n\t\t\t\t// MySQL LIKE is case-insensitive by default on most collations\n\t\t\t\tconditions.push(`${columnName} LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName} NOT LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\n/**\n * MySQL-specific ORDER BY clause builder.\n * Uses backtick identifiers.\n */\nexport function buildSortClauseMysql(\n\tsorts: SortType[] | string,\n\torder: SortDirection,\n): string {\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\\`${sort.columnName}\\` ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \\`${sorts}\\` ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * MySQL-specific cursor WHERE clause builder.\n * Uses ? placeholders (no index tracking needed since all placeholders are ?).\n */\nexport function buildCursorWhereClauseMysql(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\\`${col}\\``).join(\", \");\n\t\tconst placeholders = sortColumns.map(() => \"?\").join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClauseMysql,\n\tbuildSortClauseMysql,\n\tbuildWhereClauseMysql,\n} from \"@/utils/build-clauses-mysql.js\";\n\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getMysqlPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COLUMN_NAME as column_name\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE()\n\t\t AND TABLE_NAME = ?\n\t\t AND COLUMN_KEY = 'PRI'\n\t\t ORDER BY ORDINAL_POSITION`,\n\t\t[tableName],\n\t);\n\treturn (rows as Array<{ column_name: string }>).map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getMysqlPool(db);\n\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// MySQL has no ctid equivalent — if no cursor columns, use empty (rely on natural order)\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClauseMysql(filters);\n\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClauseMysql(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\tconst sortClause = buildSortClauseMysql(Array.isArray(sort) ? sort : sort, order);\n\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else if (cursorColumns.length > 0) {\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as total FROM \\`${tableName}\\` ${filterWhereClause}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\tfilterValues as any,\n\t);\n\tconst totalRows = Number((countRows as Array<{ total: number }>)[0]?.total ?? 0);\n\n\tconst fetchLimit = Math.floor(limit) + 1;\n\tconst [dataRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT * FROM \\`${tableName}\\` ${combinedWhereClause} ${effectiveSortClause} LIMIT ${fetchLimit}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t[...filterValues, ...cursorValues] as any,\n\t);\n\n\tlet rows = dataRows as Record<string, unknown>[];\n\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\n\tif (rows.length > 0 && cursorColumns.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\n\t\tif (direction === \"asc\") {\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u) => `\\`${u.columnName}\\` = ?`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof u.value === \"string\") {\n\t\t\t\t\treturn u.value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \\`${tableName}\\`\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \\`${primaryKey}\\` = ?\n\t\t\t`;\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\tconst [result] = await connection.execute<ResultSetHeader>(query, values as any);\n\n\t\t\tif (result.affectedRows === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.affectedRows;\n\t\t}\n\n\t\tawait connection.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getDbPool(db);\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\t// Clean the query - remove trailing semicolons and whitespace\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\tconst columns = result.fields.map((field) => field.name);\n\n\treturn {\n\t\tcolumns,\n\t\trows: result.rows,\n\t\trowCount: result.rows.length,\n\t\tduration,\n\t\tmessage: result.rows.length === 0 ? \"OK\" : undefined,\n\t};\n};\n","import type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nconst quoteIdentifier = (identifier: string): string => identifier.replaceAll('\"', '\"\"');\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\n\t// First, get all table names\n\tconst tablesQuery = `\n\t\tSELECT table_schema as \"schemaName\", table_name as \"tableName\"\n\t\tFROM information_schema.tables\n\t\tWHERE table_type = 'BASE TABLE'\n\t\t AND table_schema NOT IN ('pg_catalog', 'information_schema')\n\t\t AND table_schema NOT LIKE 'pg_toast%'\n\t\tORDER BY table_schema, table_name;\n\t`;\n\n\tconst { rows: tables } = await pool.query(tablesQuery);\n\tif (!tables[0]) {\n\t\treturn [];\n\t}\n\n\t// Get accurate row count for each table\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\ttables.map(async (table: { schemaName: string; tableName: string }) => {\n\t\t\tconst safeSchemaName = quoteIdentifier(table.schemaName);\n\t\t\tconst safeTableName = quoteIdentifier(table.tableName);\n\t\t\tconst countQuery = `SELECT COUNT(*)::integer as count FROM \"${safeSchemaName}\".\"${safeTableName}\"`;\n\t\t\tconst { rows } = await pool.query(countQuery);\n\t\t\treturn {\n\t\t\t\tschemaName: table.schemaName,\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: rows[0]?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\ninterface ColumnInfo {\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string;\n\tis_nullable: string;\n\tcolumn_default: string | null;\n\tcharacter_maximum_length: number | null;\n\tnumeric_precision: number | null;\n\tnumeric_scale: number | null;\n}\n\ninterface ConstraintInfo {\n\tconstraint_name: string;\n\tconstraint_type: string;\n\tcolumn_name: string;\n\tforeign_table_name: string | null;\n\tforeign_column_name: string | null;\n}\n\ninterface IndexInfo {\n\tindexname: string;\n\tindexdef: string;\n}\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\t) as exists\n\t`;\n\tconst { rows: tableExistsRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableExistsRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get column information\n\tconst columnsQuery = `\n\t\tSELECT \n\t\t\tcolumn_name,\n\t\t\tdata_type,\n\t\t\tudt_name,\n\t\t\tis_nullable,\n\t\t\tcolumn_default,\n\t\t\tcharacter_maximum_length,\n\t\t\tnumeric_precision,\n\t\t\tnumeric_scale\n\t\tFROM information_schema.columns\n\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\tORDER BY ordinal_position\n\t`;\n\tconst { rows: columns } = await pool.query<ColumnInfo>(columnsQuery, [tableName]);\n\n\t// Get constraints (primary keys, foreign keys, unique)\n\tconst constraintsQuery = `\n\t\tSELECT \n\t\t\ttc.constraint_name,\n\t\t\ttc.constraint_type,\n\t\t\tkcu.column_name,\n\t\t\tccu.table_name AS foreign_table_name,\n\t\t\tccu.column_name AS foreign_column_name\n\t\tFROM information_schema.table_constraints tc\n\t\tJOIN information_schema.key_column_usage kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tLEFT JOIN information_schema.constraint_column_usage ccu\n\t\t\tON tc.constraint_name = ccu.constraint_name\n\t\t\tAND tc.table_schema = ccu.table_schema\n\t\t\tAND tc.constraint_type = 'FOREIGN KEY'\n\t\tWHERE tc.table_schema = 'public' AND tc.table_name = $1\n\t\tORDER BY tc.constraint_type, tc.constraint_name\n\t`;\n\tconst { rows: constraints } = await pool.query<ConstraintInfo>(constraintsQuery, [\n\t\ttableName,\n\t]);\n\n\t// Get indexes (excluding primary key indexes which are auto-created)\n\tconst indexesQuery = `\n\t\tSELECT indexname, indexdef\n\t\tFROM pg_indexes\n\t\tWHERE schemaname = 'public' AND tablename = $1\n\t\tAND indexname NOT IN (\n\t\t\tSELECT constraint_name \n\t\t\tFROM information_schema.table_constraints \n\t\t\tWHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY'\n\t\t)\n\t`;\n\tconst { rows: indexes } = await pool.query<IndexInfo>(indexesQuery, [tableName]);\n\n\t// Build the CREATE TABLE statement\n\tconst schemaLines: string[] = [];\n\tschemaLines.push(`create table public.${tableName} (`);\n\n\t// Add columns\n\tconst columnDefs: string[] = [];\n\tfor (const col of columns) {\n\t\tlet colDef = ` ${col.column_name} ${formatDataType(col)}`;\n\n\t\tif (col.is_nullable === \"NO\") {\n\t\t\tcolDef += \" not null\";\n\t\t}\n\n\t\tif (col.column_default !== null) {\n\t\t\tcolDef += ` default ${col.column_default}`;\n\t\t}\n\n\t\tcolumnDefs.push(colDef);\n\t}\n\n\t// Group constraints by name to handle composite keys\n\tconst constraintMap = new Map<string, ConstraintInfo[]>();\n\tfor (const constraint of constraints) {\n\t\tconst existing = constraintMap.get(constraint.constraint_name) || [];\n\t\texisting.push(constraint);\n\t\tconstraintMap.set(constraint.constraint_name, existing);\n\t}\n\n\t// Add constraints\n\tconst constraintDefs: string[] = [];\n\tfor (const [constraintName, constraintColumns] of constraintMap) {\n\t\tconst firstConstraint = constraintColumns[0];\n\t\tconst columnNames = constraintColumns.map((c) => c.column_name).join(\", \");\n\n\t\tif (firstConstraint.constraint_type === \"PRIMARY KEY\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} primary key (${columnNames})`);\n\t\t} else if (firstConstraint.constraint_type === \"FOREIGN KEY\") {\n\t\t\tconst foreignTable = firstConstraint.foreign_table_name;\n\t\t\tconst foreignColumn = firstConstraint.foreign_column_name;\n\t\t\tconstraintDefs.push(\n\t\t\t\t` constraint ${constraintName} foreign key (${columnNames}) references ${foreignTable} (${foreignColumn})`,\n\t\t\t);\n\t\t} else if (firstConstraint.constraint_type === \"UNIQUE\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} unique (${columnNames})`);\n\t\t}\n\t}\n\n\t// Combine column and constraint definitions\n\tconst allDefs = [...columnDefs, ...constraintDefs];\n\tschemaLines.push(allDefs.join(\",\\n\"));\n\n\tschemaLines.push(\") tablespace pg_default;\");\n\n\t// Add indexes as separate statements\n\tfor (const index of indexes) {\n\t\t// Skip unique indexes that are already covered by unique constraints\n\t\tconst isUniqueConstraint = Array.from(constraintMap.values()).some(\n\t\t\t(c) => c[0].constraint_type === \"UNIQUE\" && c[0].constraint_name === index.indexname,\n\t\t);\n\t\tif (!isUniqueConstraint) {\n\t\t\tschemaLines.push(\"\");\n\t\t\tschemaLines.push(`${index.indexdef};`);\n\t\t}\n\t}\n\n\treturn schemaLines.join(\"\\n\");\n}\n\nfunction formatDataType(col: ColumnInfo): string {\n\tconst { data_type, udt_name, character_maximum_length, numeric_precision, numeric_scale } =\n\t\tcol;\n\n\t// Handle user-defined types (enums)\n\tif (data_type === \"USER-DEFINED\") {\n\t\treturn udt_name;\n\t}\n\n\t// Handle array types\n\tif (data_type === \"ARRAY\") {\n\t\treturn `${udt_name.replace(/^_/, \"\")}[]`;\n\t}\n\n\t// Handle character types with length\n\tif (\n\t\t(data_type === \"character varying\" || data_type === \"varchar\") &&\n\t\tcharacter_maximum_length\n\t) {\n\t\treturn `varchar(${character_maximum_length})`;\n\t}\n\n\tif (data_type === \"character\" && character_maximum_length) {\n\t\treturn `char(${character_maximum_length})`;\n\t}\n\n\t// Handle numeric with precision and scale\n\tif (data_type === \"numeric\" && numeric_precision !== null) {\n\t\tif (numeric_scale !== null && numeric_scale > 0) {\n\t\t\treturn `numeric(${numeric_precision}, ${numeric_scale})`;\n\t\t}\n\t\treturn `numeric(${numeric_precision})`;\n\t}\n\n\t// Handle timestamp types\n\tif (data_type === \"timestamp with time zone\") {\n\t\treturn \"timestamp with time zone\";\n\t}\n\n\tif (data_type === \"timestamp without time zone\") {\n\t\treturn \"timestamp\";\n\t}\n\n\t// Map common data types\n\tconst typeMap: Record<string, string> = {\n\t\t\"character varying\": \"varchar\",\n\t\tcharacter: \"char\",\n\t\t\"double precision\": \"float8\",\n\t\tinteger: \"integer\",\n\t\tbigint: \"bigint\",\n\t\tsmallint: \"smallint\",\n\t\tboolean: \"boolean\",\n\t\ttext: \"text\",\n\t\tuuid: \"uuid\",\n\t\tjson: \"json\",\n\t\tjsonb: \"jsonb\",\n\t\tdate: \"date\",\n\t\ttime: \"time\",\n\t\tbytea: \"bytea\",\n\t};\n\n\treturn typeMap[data_type] || data_type;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\nexport function buildWhereClause(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst paramIndex = values.length + 1;\n\t\tconst columnName = `\"${filter.columnName}\"`;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\t// Handle NULL values\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tconditions.push(`${columnName}::text LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tconditions.push(`${columnName}::text NOT LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tconditions.push(`${columnName}::text ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName}::text NOT ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Unknown operator, skip\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\nexport function buildSortClause(sorts: SortType[] | string, order: SortDirection): string {\n\t// Handle array of Sort objects (new format for referenced tables)\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\"${sort.columnName}\" ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\t// Handle legacy format (string column name + order)\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \"${sorts}\" ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\nexport function buildCursorWhereClause(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n\tstartParamIndex: number,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\t// Determine comparison operator based on direction and sort order\n\t// Forward + ASC = >, Forward + DESC = <\n\t// Backward + ASC = <, Backward + DESC = >\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\t// Build row comparison for multi-column cursor\n\t// Uses tuple comparison: (col1, col2, ...) > (val1, val2, ...)\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\"${col}\"`).join(\", \");\n\t\tconst placeholders = sortColumns.map((_, i) => `$${startParamIndex + i}`).join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClause,\n\tbuildSortClause,\n\tbuildWhereClause,\n} from \"@/utils/build-clauses.js\";\n\n// Encode cursor data to base64 string\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\n// Decode base64 cursor string to cursor data\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// Get primary key column(s) for a table\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getDbPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\t// Quote the table name to preserve case sensitivity in PostgreSQL\n\tconst quotedTableName = `\"${tableName}\"`;\n\tconst result = await pool.query(\n\t\t`SELECT a.attname as column_name\n\t\t FROM pg_index i\n\t\t JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n\t\t WHERE i.indrelid = $1::regclass AND i.indisprimary\n\t\t ORDER BY array_position(i.indkey, a.attnum)`,\n\t\t[quotedTableName],\n\t);\n\treturn result.rows.map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getDbPool(db);\n\n\t// Get primary key columns for stable cursor pagination\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\t// Determine sort columns - use provided sort or fall back to primary key\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\t// Always include primary key columns for stable pagination\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// If no sort columns and no primary key, fall back to ctid (PostgreSQL internal row id)\n\tif (cursorColumns.length === 0) {\n\t\tcursorColumns.push(\"ctid\");\n\t}\n\t// Build filter WHERE clause\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClause(filters);\n\t// Build cursor WHERE clause if cursor is provided\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClause(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t\tfilterValues.length + 1,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\t// Combine WHERE clauses\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\t// Remove \"WHERE \" prefix from filterWhereClause and combine\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\t// Build sort clause\n\tconst sortClause = buildSortClause(Array.isArray(sort) ? sort : sort, order);\n\n\t// For backward pagination, reverse the sort order\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else {\n\t\t\t// Default sort by cursor columns in reverse\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\"${col}\" ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\t// Default sort by cursor columns\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\"${col}\" ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\t// Get total count (with filters only, not cursor)\n\tconst countRes = await pool.query(\n\t\t`SELECT COUNT(*) as total FROM \"${tableName}\" ${filterWhereClause}`,\n\t\tfilterValues,\n\t);\n\tconst totalRows = Number(countRes.rows[0].total);\n\t// Fetch one extra row to determine if there are more results\n\tconst limitParamIndex = filterValues.length + cursorValues.length + 1;\n\tconst dataRes = await pool.query(\n\t\t`SELECT * FROM \"${tableName}\" ${combinedWhereClause} ${effectiveSortClause} LIMIT $${limitParamIndex}`,\n\t\t[...filterValues, ...cursorValues, limit + 1],\n\t);\n\t// Check if table has columns\n\tconst hasColumns = dataRes.fields && dataRes.fields.length > 0;\n\t// Filter out empty objects\n\tlet rows = hasColumns\n\t\t? dataRes.rows.filter((row) => Object.keys(row).length > 0)\n\t\t: dataRes.rows;\n\t// Determine if there are more results\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\t// For backward pagination, reverse the results to maintain correct order\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\t// Build cursors for next/previous pages\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\tif (rows.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\t\t// Create cursor from row values\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\t\t// For forward pagination\n\t\tif (direction === \"asc\") {\n\t\t\t// Next cursor: if there are more results, encode the last row\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if we used a cursor to get here, encode the first row\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\t// For backward pagination\n\t\t\t// Next cursor: if we used a cursor, encode the last row (to go forward again)\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if there are more results going backward, encode the first row\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Updates multiple cells in a table. Can update multiple rows or multiple cells in the same row.\n * Groups updates by row and executes them efficiently.\n */\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getDbPool(db);\n\n\t// Group updates by row (using the primary key value)\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data. Please ensure the row has a \"${primaryKey}\" column.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\t// Use transaction for multiple updates\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\t// Execute updates for each row\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, index) => `\"${u.columnName}\" = $${index + 1}`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\t// If the value is an object or array, stringify it for JSON/JSONB columns\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\t// Add the primary key value as the last parameter\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \"${tableName}\"\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \"${primaryKey}\" = $${values.length}\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\tconst result = await pool.query(query, values);\n\t\t\tif (result.rowCount === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowCount ?? 0;\n\t\t}\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import type { DatabaseTypeSchema } from \"shared/types/database.types.js\";\n\n// PostgreSQL DAOs\nimport * as pgAddRecord from \"./add-record.dao.js\";\nimport * as pgBulkInsertRecords from \"./bulk-insert-records.dao.js\";\nimport * as pgCreateTable from \"./create-table.dao.js\";\nimport * as pgDatabaseList from \"./database-list.dao.js\";\nimport * as pgDeleteColumn from \"./delete-column.dao.js\";\nimport * as pgDeleteRecords from \"./delete-records.dao.js\";\nimport * as pgDeleteTable from \"./delete-table.dao.js\";\nimport * as pgExportTable from \"./export-table.dao.js\";\n// MongoDB DAOs\nimport * as mongoAddRecord from \"./mongo/add-record.mongo.dao.js\";\nimport * as mongoBulkInsertRecords from \"./mongo/bulk-insert-records.mongo.dao.js\";\nimport * as mongoCreateTable from \"./mongo/create-table.mongo.dao.js\";\nimport * as mongoDatabaseList from \"./mongo/database-list.mongo.dao.js\";\nimport * as mongoDeleteColumn from \"./mongo/delete-column.mongo.dao.js\";\nimport * as mongoDeleteRecords from \"./mongo/delete-records.mongo.dao.js\";\nimport * as mongoDeleteTable from \"./mongo/delete-table.mongo.dao.js\";\nimport * as mongoExportTable from \"./mongo/export-table.mongo.dao.js\";\nimport * as mongoQuery from \"./mongo/query.mongo.dao.js\";\nimport * as mongoTableColumns from \"./mongo/table-columns.mongo.dao.js\";\nimport * as mongoTableList from \"./mongo/table-list.mongo.dao.js\";\nimport * as mongoTableSchema from \"./mongo/table-schema.mongo.dao.js\";\nimport * as mongoTablesData from \"./mongo/tables-data.mongo.dao.js\";\nimport * as mongoUpdateRecords from \"./mongo/update-records.mongo.dao.js\";\n// MSSQL DAOs\nimport * as mssqlAddRecord from \"./mssql/add-record.mssql.dao.js\";\nimport * as mssqlBulkInsertRecords from \"./mssql/bulk-insert-records.mssql.dao.js\";\nimport * as mssqlCreateTable from \"./mssql/create-table.mssql.dao.js\";\nimport * as mssqlDatabaseList from \"./mssql/database-list.mssql.dao.js\";\nimport * as mssqlDeleteColumn from \"./mssql/delete-column.mssql.dao.js\";\nimport * as mssqlDeleteRecords from \"./mssql/delete-records.mssql.dao.js\";\nimport * as mssqlDeleteTable from \"./mssql/delete-table.mssql.dao.js\";\nimport * as mssqlExportTable from \"./mssql/export-table.mssql.dao.js\";\nimport * as mssqlQuery from \"./mssql/query.mssql.dao.js\";\nimport * as mssqlTableColumns from \"./mssql/table-columns.mssql.dao.js\";\nimport * as mssqlTableList from \"./mssql/table-list.mssql.dao.js\";\nimport * as mssqlTableSchema from \"./mssql/table-schema.mssql.dao.js\";\nimport * as mssqlTablesData from \"./mssql/tables-data.mssql.dao.js\";\nimport * as mssqlUpdateRecords from \"./mssql/update-records.mssql.dao.js\";\n// MySQL DAOs\nimport * as mysqlAddRecord from \"./mysql/add-record.mysql.dao.js\";\nimport * as mysqlBulkInsertRecords from \"./mysql/bulk-insert-records.mysql.dao.js\";\nimport * as mysqlCreateTable from \"./mysql/create-table.mysql.dao.js\";\nimport * as mysqlDatabaseList from \"./mysql/database-list.mysql.dao.js\";\nimport * as mysqlDeleteColumn from \"./mysql/delete-column.mysql.dao.js\";\nimport * as mysqlDeleteRecords from \"./mysql/delete-records.mysql.dao.js\";\nimport * as mysqlDeleteTable from \"./mysql/delete-table.mysql.dao.js\";\nimport * as mysqlExportTable from \"./mysql/export-table.mysql.dao.js\";\nimport * as mysqlQuery from \"./mysql/query.mysql.dao.js\";\nimport * as mysqlTableColumns from \"./mysql/table-columns.mysql.dao.js\";\nimport * as mysqlTableList from \"./mysql/table-list.mysql.dao.js\";\nimport * as mysqlTableSchema from \"./mysql/table-schema.mysql.dao.js\";\nimport * as mysqlTablesData from \"./mysql/tables-data.mysql.dao.js\";\nimport * as mysqlUpdateRecords from \"./mysql/update-records.mysql.dao.js\";\nimport * as pgQuery from \"./query.dao.js\";\nimport * as pgTableColumns from \"./table-columns.dao.js\";\nimport * as pgTableList from \"./table-list.dao.js\";\nimport * as pgTableSchema from \"./table-schema.dao.js\";\nimport * as pgTablesData from \"./tables-data.dao.js\";\nimport * as pgUpdateRecords from \"./update-records.dao.js\";\n\n/**\n * DAO Factory - Automatically routes to the correct database implementation\n *\n * Usage:\n * ```typescript\n * const dao = getDaoFactory(dbType);\n * const tables = await dao.getTablesList(db);\n * ```\n */\n\nconst daoRegistry = {\n\tpg: {\n\t\taddRecord: pgAddRecord.addRecord,\n\t\tbulkInsertRecords: pgBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: pgCreateTable.createTable,\n\t\tgetDatabasesList: pgDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: pgDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: pgDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: pgDeleteColumn.deleteColumn,\n\t\tdeleteRecords: pgDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: pgDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: pgDeleteTable.deleteTable,\n\t\texportTableData: pgExportTable.exportTableData,\n\t\texecuteQuery: pgQuery.executeQuery,\n\t\tgetTableColumns: pgTableColumns.getTableColumns,\n\t\tgetTablesList: pgTableList.getTablesList,\n\t\tgetTableSchema: pgTableSchema.getTableSchema,\n\t\tgetTableData: pgTablesData.getTableData,\n\t\tupdateRecords: pgUpdateRecords.updateRecords,\n\t},\n\tmysql: {\n\t\taddRecord: mysqlAddRecord.addRecord,\n\t\tbulkInsertRecords: mysqlBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: mysqlCreateTable.createTable,\n\t\tgetDatabasesList: mysqlDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: mysqlDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: mysqlDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: mysqlDeleteColumn.deleteColumn,\n\t\tdeleteRecords: mysqlDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: mysqlDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: mysqlDeleteTable.deleteTable,\n\t\texportTableData: mysqlExportTable.exportTableData,\n\t\texecuteQuery: mysqlQuery.executeQuery,\n\t\tgetTableColumns: mysqlTableColumns.getTableColumns,\n\t\tgetTablesList: mysqlTableList.getTablesList,\n\t\tgetTableSchema: mysqlTableSchema.getTableSchema,\n\t\tgetTableData: mysqlTablesData.getTableData,\n\t\tupdateRecords: mysqlUpdateRecords.updateRecords,\n\t},\n\tmongodb: {\n\t\taddRecord: mongoAddRecord.addRecord,\n\t\tbulkInsertRecords: mongoBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: mongoCreateTable.createTable,\n\t\tgetDatabasesList: mongoDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: mongoDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: mongoDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: mongoDeleteColumn.deleteColumn,\n\t\tdeleteRecords: mongoDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: mongoDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: mongoDeleteTable.deleteTable,\n\t\texportTableData: mongoExportTable.exportTableData,\n\t\texecuteQuery: mongoQuery.executeQuery,\n\t\tgetTableColumns: mongoTableColumns.getTableColumns,\n\t\tgetTablesList: mongoTableList.getTablesList,\n\t\tgetTableSchema: mongoTableSchema.getTableSchema,\n\t\tgetTableData: mongoTablesData.getTableData,\n\t\tupdateRecords: mongoUpdateRecords.updateRecords,\n\t},\n\tmssql: {\n\t\taddRecord: mssqlAddRecord.addRecord,\n\t\tbulkInsertRecords: mssqlBulkInsertRecords.bulkInsertRecords,\n\t\tcreateTable: mssqlCreateTable.createTable,\n\t\tgetDatabasesList: mssqlDatabaseList.getDatabasesList,\n\t\tgetCurrentDatabase: mssqlDatabaseList.getCurrentDatabase,\n\t\tgetDatabaseConnectionInfo: mssqlDatabaseList.getDatabaseConnectionInfo,\n\t\tdeleteColumn: mssqlDeleteColumn.deleteColumn,\n\t\tdeleteRecords: mssqlDeleteRecords.deleteRecords,\n\t\tforceDeleteRecords: mssqlDeleteRecords.forceDeleteRecords,\n\t\tdeleteTable: mssqlDeleteTable.deleteTable,\n\t\texportTableData: mssqlExportTable.exportTableData,\n\t\texecuteQuery: mssqlQuery.executeQuery,\n\t\tgetTableColumns: mssqlTableColumns.getTableColumns,\n\t\tgetTablesList: mssqlTableList.getTablesList,\n\t\tgetTableSchema: mssqlTableSchema.getTableSchema,\n\t\tgetTableData: mssqlTablesData.getTableData,\n\t\tupdateRecords: mssqlUpdateRecords.updateRecords,\n\t},\n} as const;\n\nexport type DaoMethods = typeof daoRegistry.pg;\n\n/**\n * Get the DAO implementation for the specified database type\n * @param dbType - The database type (pg, mysql, mssql)\n * @returns DAO methods for the specified database type\n */\nexport function getDaoFactory(dbType: DatabaseTypeSchema): DaoMethods {\n\tif (dbType === \"mongodb\") {\n\t\treturn daoRegistry.mongodb as unknown as DaoMethods;\n\t}\n\treturn daoRegistry[dbType];\n}\n\n/**\n * Execute a DAO method with automatic database type routing\n * @param dbType - The database type\n * @param method - The DAO method name\n * @param args - Arguments to pass to the DAO method\n */\nexport async function executeDaoMethod<K extends keyof DaoMethods>(\n\tdbType: DatabaseTypeSchema,\n\tmethod: K,\n\t...args: Parameters<DaoMethods[K]>\n): Promise<ReturnType<DaoMethods[K]>> {\n\tconst dao = getDaoFactory(dbType);\n\t// @ts-expect-error - Complex type inference, but runtime safe\n\treturn dao[method](...args);\n}\n","import { Hono } from \"hono\";\nimport type {\n\tConnectionInfoSchemaType,\n\tCurrentDatabaseSchemaType,\n\tDatabaseListSchemaType,\n} from \"shared/types\";\nimport type { ApiHandler } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\nimport { getDbType } from \"@/db-manager.js\";\n\n/**\n * /databases routes (at root level, no dbType required)\n * GET /databases - Get list of all databases on the server (name, size, owner, encoding)\n * GET /databases/current - Get the name of the database we are currently connected to\n * GET /databases/connection - Get connection details and server information\n */\nexport const databasesRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /databases/...\n\t */\n\t.basePath(\"/databases\")\n\n\t/**\n\t * GET /databases\n\t * Returns list of all databases on the server (name, size, owner, encoding) and the database type\n\t */\n\t.get(\"/\", async (c): ApiHandler<DatabaseListSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst databases = await dao.getDatabasesList();\n\t\treturn c.json({ data: { databases, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/current\n\t * Returns the name of the database we are currently connected to and the database type\n\t */\n\t.get(\"/current\", async (c): ApiHandler<CurrentDatabaseSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst current = await dao.getCurrentDatabase();\n\t\treturn c.json({ data: { db: current.db, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/connection\n\t * Returns connection details and server information\n\t */\n\t.get(\"/connection\", async (c): ApiHandler<ConnectionInfoSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst dao = getDaoFactory(dbType);\n\t\tconst info = await dao.getDatabaseConnectionInfo();\n\t\treturn c.json({ data: info }, 200);\n\t});\n\nexport type DatabasesRoutes = typeof databasesRoutes.routes;\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { databaseSchema, type ExecuteQueryResult, executeQuerySchema } from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\n\nexport const queryRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/query/...\n\t */\n\t.basePath(\"/query\")\n\n\t/**\n\t * POST /query\n\t * Executes a SQL query on the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", executeQuerySchema),\n\t\tasync (c): ApiHandler<ExecuteQueryResult> => {\n\t\t\tconst { query } = c.req.valid(\"json\");\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst data = await dao.executeQuery({ query, db });\n\t\t\treturn c.json({ data }, 200);\n\t\t},\n\t);\n\nexport type QueryRoutes = typeof queryRoutes;\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddRecordSchema,\n\tbulkInsertRecordsSchema,\n\ttype DeleteRecordResult,\n\tdatabaseSchema,\n\tdeleteRecordSchema,\n\tupdateRecordsSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\n\nexport const recordsRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/records/...\n\t */\n\t.basePath(\"/records\")\n\n\t/**\n\t * POST /records\n\t * Adds a new record into a table\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", addRecordSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, data } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { insertedCount } = await dao.addRecord({ db, params: { tableName, data } });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Record inserted into \"${tableName}\" with ${insertedCount} rows inserted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /records\n\t * Updates one or more cells in a table\n\t */\n\t.patch(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", updateRecordsSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKey, updates } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { updatedCount } = await dao.updateRecords({\n\t\t\t\tparams: { tableName, primaryKey, updates },\n\t\t\t\tdb,\n\t\t\t});\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Updated ${updatedCount} records in \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records\n\t * Deletes records from a table\n\t */\n\t.delete(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<DeleteRecordResult, 409 | 200> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { deletedCount, fkViolation, relatedRecords } = await dao.deleteRecords({\n\t\t\t\ttableName,\n\t\t\t\tprimaryKeys,\n\t\t\t\tdb,\n\t\t\t});\n\t\t\tif (fkViolation) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdeletedCount: 0,\n\t\t\t\t\t\t\tfkViolation: true,\n\t\t\t\t\t\t\trelatedRecords,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t409,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdeletedCount,\n\t\t\t\t\t\tfkViolation: false,\n\t\t\t\t\t\trelatedRecords: [],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records/force\n\t * Force deletes records and all related FK records\n\t */\n\t.delete(\n\t\t\"/force\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<{ deletedCount: number }> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst deletedCount = await dao.forceDeleteRecords({ tableName, primaryKeys, db });\n\t\t\treturn c.json({ data: deletedCount }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /records/bulk\n\t * Bulk inserts multiple records into a table\n\t */\n\t.post(\n\t\t\"/bulk\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", bulkInsertRecordsSchema),\n\t\tasync (c): ApiHandler<object> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, records } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst result = await dao.bulkInsertRecords({ tableName, records, db });\n\t\t\tconsole.log(\"result\", result);\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t);\n\nexport type RecordsRoutes = typeof recordsRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Adds a column to a PostgreSQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (columnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tlet columnDefinition = `\"${columnName}\" ${columnType}`;\n\n\tif (isArray) {\n\t\tcolumnDefinition += \"[]\";\n\t}\n\n\tif (isPrimaryKey) {\n\t\tcolumnDefinition += \" PRIMARY KEY\";\n\t}\n\n\tif (isUnique && !isPrimaryKey) {\n\t\tcolumnDefinition += \" UNIQUE\";\n\t}\n\n\tif (!isNullable) {\n\t\tcolumnDefinition += \" NOT NULL\";\n\t}\n\n\tif (isIdentity) {\n\t\tcolumnDefinition += \" GENERATED ALWAYS AS IDENTITY\";\n\t}\n\n\tif (defaultValue?.trim() && !isIdentity) {\n\t\tcolumnDefinition += ` DEFAULT ${defaultValue.trim()}`;\n\t}\n\n\tawait pool.query(`ALTER TABLE \"${tableName}\" ADD COLUMN ${columnDefinition}`);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Alters a PostgreSQL column's type, nullability, and default value.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst client = await pool.connect();\n\n\ttry {\n\t\tawait client.query(\"BEGIN\");\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" TYPE ${columnType}`,\n\t\t);\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" ${isNullable ? \"DROP\" : \"SET\"} NOT NULL`,\n\t\t);\n\n\t\tif (defaultValue?.trim()) {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" SET DEFAULT ${defaultValue.trim()}`,\n\t\t\t);\n\t\t} else {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" DROP DEFAULT`,\n\t\t\t);\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tthrow error;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\n/**\n * Adds a field to all documents in a MongoDB collection.\n * Sets a typed default value and updates the collection's JSON Schema validator.\n */\nexport async function addColumn({\n\ttableName,\n\tcolumnName,\n\tcolumnType,\n\tdefaultValue,\n\tisNullable,\n\tdb,\n}: AddColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\t// Check field doesn't already exist\n\tconst conflict = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [columnName]: { $exists: true } });\n\tif (conflict) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Field \"${columnName}\" already exists in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Resolve a typed default value\n\tconst resolvedDefault = resolveDefault(defaultValue, columnType);\n\n\t// Set the field on all existing documents\n\tawait mongoDb\n\t\t.collection(tableName)\n\t\t.updateMany({}, { $set: { [columnName]: resolvedDefault } });\n\n\t// Update the JSON Schema validator\n\tconst collInfo = collections[0] as {\n\t\toptions?: {\n\t\t\tvalidator?: {\n\t\t\t\t$jsonSchema?: { properties?: Record<string, unknown>; required?: string[] };\n\t\t\t};\n\t\t};\n\t};\n\tconst existingSchema = collInfo.options?.validator?.$jsonSchema ?? {};\n\tconst properties: Record<string, unknown> = {\n\t\t...((existingSchema.properties as Record<string, unknown>) ?? {}),\n\t\t[columnName]: { bsonType: isNullable ? [columnType, \"null\"] : columnType },\n\t};\n\tconst required: string[] = [...(existingSchema.required ?? [])];\n\tif (!isNullable && !required.includes(columnName)) {\n\t\trequired.push(columnName);\n\t}\n\n\tawait mongoDb.command({\n\t\tcollMod: tableName,\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\t...existingSchema,\n\t\t\t\tbsonType: \"object\",\n\t\t\t\tproperties,\n\t\t\t\t...(required.length > 0 ? { required } : {}),\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"warn\",\n\t});\n}\n\nexport { addColumn as addMongoField };\n\nconst resolveDefault = (\n\tdefaultValue: string | null | undefined,\n\tcolumnType: string,\n): unknown => {\n\tif (defaultValue !== undefined && defaultValue !== null && defaultValue.trim() !== \"\") {\n\t\ttry {\n\t\t\treturn JSON.parse(defaultValue);\n\t\t} catch {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\tswitch (columnType) {\n\t\tcase \"string\":\n\t\t\treturn \"\";\n\t\tcase \"int\":\n\t\tcase \"long\":\n\t\tcase \"double\":\n\t\tcase \"decimal\":\n\t\t\treturn 0;\n\t\tcase \"bool\":\n\t\t\treturn false;\n\t\tcase \"array\":\n\t\t\treturn [];\n\t\tcase \"object\":\n\t\t\treturn {};\n\t\tcase \"date\":\n\t\t\treturn new Date();\n\t\tdefault:\n\t\t\treturn null;\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AlterColumnParamsSchemaType, RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getMongoDb } from \"@/db-manager.js\";\n\n/**\n * Renames a field across all documents in a collection using $rename.\n */\nexport async function renameColumn({\n\ttableName,\n\tcolumnName,\n\tnewColumnName,\n\tdb,\n}: RenameColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tif (columnName === \"_id\") {\n\t\tthrow new HTTPException(400, { message: 'Cannot rename the \"_id\" field' });\n\t}\n\n\t// Check if the field exists in at least one document\n\tconst sample = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [columnName]: { $exists: true } });\n\tif (!sample) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Field \"${columnName}\" does not exist in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Check target field doesn't already exist\n\tconst conflict = await mongoDb\n\t\t.collection(tableName)\n\t\t.findOne({ [newColumnName]: { $exists: true } });\n\tif (conflict) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Field \"${newColumnName}\" already exists in collection \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait mongoDb\n\t\t.collection(tableName)\n\t\t.updateMany(\n\t\t\t{ [columnName]: { $exists: true } },\n\t\t\t{ $rename: { [columnName]: newColumnName } },\n\t\t);\n}\n\n/**\n * Alters a field across all documents in a collection.\n * MongoDB is schemaless so this updates the collection's JSON Schema validator\n * and optionally converts existing field values to the new type.\n */\nexport async function alterColumn({\n\ttableName,\n\tcolumnName,\n\tcolumnType,\n\tisNullable,\n\tdb,\n}: AlterColumnParamsSchemaType): Promise<void> {\n\tconst mongoDb = await getMongoDb(db);\n\tconst collections = await mongoDb.listCollections({ name: tableName }).toArray();\n\tif (collections.length === 0) {\n\t\tthrow new HTTPException(404, { message: `Collection \"${tableName}\" does not exist` });\n\t}\n\n\tif (columnName === \"_id\") {\n\t\tthrow new HTTPException(400, { message: 'Cannot alter the \"_id\" field' });\n\t}\n\n\t// Fetch existing validator if any\n\tconst collInfo = collections[0] as {\n\t\toptions?: {\n\t\t\tvalidator?: {\n\t\t\t\t$jsonSchema?: { properties?: Record<string, unknown>; required?: string[] };\n\t\t\t};\n\t\t};\n\t};\n\tconst existingSchema = collInfo.options?.validator?.$jsonSchema ?? {};\n\tconst properties: Record<string, unknown> = {\n\t\t...((existingSchema.properties as Record<string, unknown>) ?? {}),\n\t};\n\tconst required: string[] = [...(existingSchema.required ?? [])];\n\n\t// Update the field's bsonType in the validator\n\tconst bsonType = isNullable ? [columnType, \"null\"] : columnType;\n\tproperties[columnName] = { bsonType };\n\n\t// Update required list\n\tconst reqIndex = required.indexOf(columnName);\n\tif (!isNullable && reqIndex === -1) {\n\t\trequired.push(columnName);\n\t} else if (isNullable && reqIndex !== -1) {\n\t\trequired.splice(reqIndex, 1);\n\t}\n\n\tawait mongoDb.command({\n\t\tcollMod: tableName,\n\t\tvalidator: {\n\t\t\t$jsonSchema: {\n\t\t\t\t...existingSchema,\n\t\t\t\tbsonType: \"object\",\n\t\t\t\tproperties,\n\t\t\t\t...(required.length > 0 ? { required } : {}),\n\t\t\t},\n\t\t},\n\t\tvalidationAction: \"warn\",\n\t});\n}\n\nexport { alterColumn as mongoAlterColumn, renameColumn as mongoRenameColumn };\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Adds a column to a MySQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (columnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisPrimaryKey,\n\t\t\tisNullable,\n\t\t\tisUnique,\n\t\t\tisIdentity,\n\t\t\tisArray,\n\t\t},\n\t\t{\n\t\t\tincludePrimaryKey: true,\n\t\t\tincludeUnique: true,\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` ADD COLUMN ${columnDefinition}`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Alters a MySQL column's type, nullability, and default value using MODIFY COLUMN.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT EXTRA\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?\n\t\t LIMIT 1`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnRow = (columnRows as Array<{ EXTRA?: string | null }>)[0];\n\tif (!columnRow) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisNullable,\n\t\t},\n\t\t{\n\t\t\tpreserveAutoIncrement: columnRow.EXTRA?.toLowerCase().includes(\"auto_increment\"),\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` MODIFY COLUMN ${columnDefinition}`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Renames a MySQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [currentColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst currentColumnExists =\n\t\tNumber((currentColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!currentColumnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [nextColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, newColumnName],\n\t);\n\tconst nextColumnExists = Number((nextColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (nextColumnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` RENAME COLUMN \\`${columnName}\\` TO \\`${newColumnName}\\``,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Renames a PostgreSQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: currentColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tcolumnName,\n\t]);\n\tif (!currentColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst { rows: nextColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tnewColumnName,\n\t]);\n\tif (nextColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.query(\n\t\t`ALTER TABLE \"${tableName}\" RENAME COLUMN \"${columnName}\" TO \"${newColumnName}\"`,\n\t);\n}\n","import type { CellValue, FormatType } from \"shared/types\";\nimport { utils, write } from \"xlsx\";\n\ninterface ExportFileOptions {\n\tcols: string[];\n\trows: Record<string, CellValue>[];\n\tformat: FormatType;\n\ttableName: string;\n}\n\n/**\n * Converts table data to the specified export format (CSV, XLSX, or JSON)\n *\n * @param options - The export options\n * @param options.cols - Array of column names\n * @param options.rows - Array of row data objects\n * @param options.format - The export format ('csv', 'xlsx', or 'json')\n * @param options.tableName - The name of the table being exported\n * @returns The file content as a Uint8Array\n */\nexport function getExportFile({ cols, rows, format, tableName }: ExportFileOptions): BodyInit {\n\tswitch (format) {\n\t\tcase \"json\": {\n\t\t\tconst jsonContent = JSON.stringify(rows ?? [], null, 2);\n\t\t\treturn new Uint8Array(Buffer.from(jsonContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"csv\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst csvContent = utils.sheet_to_csv(worksheet);\n\t\t\treturn new Uint8Array(Buffer.from(csvContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"xlsx\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst workbook = utils.book_new();\n\t\t\tutils.book_append_sheet(workbook, worksheet, tableName.slice(0, 31));\n\t\t\tconst buffer = write(workbook, {\n\t\t\t\tbookType: \"xlsx\",\n\t\t\t\ttype: \"buffer\",\n\t\t\t}) as Buffer;\n\t\t\treturn new Uint8Array(buffer);\n\t\t}\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddColumnSchema,\n\talterColumnSchema,\n\ttype ColumnInfoSchemaType,\n\tcreateTableSchema,\n\ttype DeleteTableResult,\n\tdatabaseSchema,\n\tdeleteColumnParamSchema,\n\tdeleteColumnQuerySchema,\n\tdeleteTableQuerySchema,\n\texportTableSchema,\n\trenameColumnSchema,\n\ttype TableDataResultSchemaType,\n\ttype TableInfoSchemaType,\n\ttype TableSchemaResult,\n\ttableDataQuerySchema,\n\ttableNameSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { addColumn as pgAddColumn } from \"@/dao/add-column.dao.js\";\nimport { alterColumn as pgAlterColumn } from \"@/dao/alter-column.dao.js\";\nimport { getDaoFactory } from \"@/dao/dao-factory.js\";\nimport { addColumn as mongoAddColumn } from \"@/dao/mongo/add-column.mongo.dao.js\";\nimport {\n\talterColumn as mongoAlterColumn,\n\trenameColumn as mongoRenameColumn,\n} from \"@/dao/mongo/alter-column.mongo.dao.js\";\nimport { addColumn as mysqlAddColumn } from \"@/dao/mysql/add-column.mysql.dao.js\";\nimport { alterColumn as mysqlAlterColumn } from \"@/dao/mysql/alter-column.mysql.dao.js\";\nimport { renameColumn as mysqlRenameColumn } from \"@/dao/mysql/rename-column.mysql.dao.js\";\nimport { renameColumn as pgRenameColumn } from \"@/dao/rename-column.dao.js\";\nimport { getExportFile } from \"@/utils/get-export-file.js\";\n\nexport const tablesRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/tables/...\n\t */\n\t.basePath(\"/tables\")\n\n\t/**\n\t * GET /tables\n\t * Returns list of all tables in the currently connected database\n\t */\n\t.get(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tasync (c): ApiHandler<TableInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst tablesList = await dao.getTablesList(db);\n\t\t\treturn c.json({ data: tablesList }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables\n\t * Creates a new table in the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", createTableSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tawait dao.createTable({ tableData: body, db });\n\t\t\treturn c.json({ data: `Table ${body.tableName} created successfully` }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName\n\t * Deletes a table from the database\n\t */\n\t.delete(\n\t\t\"/:tableName\",\n\t\tzValidator(\"query\", deleteTableQuerySchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<DeleteTableResult> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst result = await dao.deleteTable({ tableName, db, cascade });\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName/columns/:columnName\n\t * Deletes a column from a table\n\t */\n\t.delete(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", deleteColumnQuerySchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst { deletedCount } = await dao.deleteColumn({ tableName, columnName, cascade, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" deleted successfully from table \"${tableName}\" with ${deletedCount} rows deleted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables/:tableName/columns\n\t * Adds a column to a table\n\t */\n\t.post(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"json\", addColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAddColumn({ tableName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait mongoAddColumn({ tableName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAddColumn({ tableName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${body.columnName}\" added successfully to table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName/rename\n\t * Renames a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName/rename\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", renameColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait mongoRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" renamed to \"${body.newColumnName}\" in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName\n\t * Alters a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", alterColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t} else if (dbType === \"mongodb\") {\n\t\t\t\tawait mongoAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" updated successfully in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/columns\n\t * Returns list of all columns in a table\n\t */\n\t.get(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<ColumnInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst columns = await dao.getTableColumns({ tableName, db });\n\t\t\treturn c.json({ data: columns }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/schema\n\t * Returns the CREATE TABLE schema for a table\n\t */\n\t.get(\n\t\t\"/:tableName/schema\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<TableSchemaResult> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst schema = await dao.getTableSchema({ tableName, db });\n\t\t\treturn c.json({ data: { schema } }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/data\n\t * Get cursor-paginated data for a table\n\t */\n\t.get(\n\t\t\"/:tableName/data\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", tableDataQuerySchema),\n\t\tasync (c): ApiHandler<TableDataResultSchemaType> => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { cursor, limit, direction, sort, order, filters, db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\t\t\tconst tableData = await dao.getTableData({\n\t\t\t\ttableName,\n\t\t\t\tcursor,\n\t\t\t\tlimit,\n\t\t\t\tdirection,\n\t\t\t\tsort,\n\t\t\t\torder,\n\t\t\t\tfilters,\n\t\t\t\tdb,\n\t\t\t});\n\t\t\treturn c.json({ data: tableData }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/export\n\t * Export table data to CSV or XLSX format\n\t */\n\t.get(\n\t\t\"/:tableName/export\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", exportTableSchema),\n\t\tasync (c) => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { db, format } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst dao = getDaoFactory(dbType);\n\n\t\t\tconst { cols, rows } = await dao.exportTableData({ tableName, db });\n\t\t\tconst fileContent = getExportFile({ cols, rows, format, tableName });\n\t\t\tlet contentType: string | undefined;\n\n\t\t\tswitch (format) {\n\t\t\t\tcase \"csv\":\n\t\t\t\t\tcontentType = \"text/csv\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"xlsx\":\n\t\t\t\t\tcontentType = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"json\":\n\t\t\t\t\tcontentType = \"application/json\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn new Response(fileContent, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": contentType ?? \"\",\n\t\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${tableName}_export.${format}\"`,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t);\n\nexport type TablesRoutes = typeof tablesRoutes.routes;\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { prettyJSON } from \"hono/pretty-json\";\nimport { type DatabaseTypeSchema, databaseTypeParamSchema } from \"shared/types\";\nimport type { AppType } from \"@/app.types.js\";\nimport { handleError, validationHook } from \"@/middlewares/error-handler.js\";\nimport { chatRoutes } from \"@/routes/chat.routes.js\";\nimport { databasesRoutes } from \"@/routes/databases.routes.js\";\nimport { queryRoutes } from \"@/routes/query.routes.js\";\nimport { recordsRoutes } from \"@/routes/records.routes.js\";\nimport { tablesRoutes } from \"@/routes/tables.routes.js\";\n\n/**\n * Get the path to the core distribution directory.\n */\nconst getCoreDistPath = () => {\n\tif (process.env.NODE_ENV === \"development\") {\n\t\treturn path.resolve(process.cwd(), \"../core/dist\");\n\t}\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\treturn path.resolve(__dirname, \"./core-dist\");\n};\n\nexport const createServer = () => {\n\tconst app = new Hono<AppType>({ strict: false })\n\t\t/**\n\t\t * Enable CORS\n\t\t */\n\t\t.use(\"/*\", cors())\n\n\t\t/**\n\t\t * Pretty print the JSON response\n\t\t */\n\t\t.use(prettyJSON({ space: 2 }))\n\n\t\t/**\n\t\t * Enable logger in development mode\n\t\t */\n\t\t.use(process.env.NODE_ENV === \"development\" ? logger() : (_, next) => next())\n\n\t\t/**\n\t\t * Serve the favicon.ico file\n\t\t */\n\t\t.use(\n\t\t\t\"/favicon.ico\",\n\t\t\tserveStatic({\n\t\t\t\tpath: path.resolve(getCoreDistPath(), \"favicon.ico\"),\n\t\t\t}),\n\t\t)\n\n\t\t/**\n\t\t * Handle CORS requests\n\t\t */\n\t\t.use(\"*\", async (c, next) => {\n\t\t\tc.header(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\tc.header(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n\t\t\tc.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\t\t\tawait next();\n\t\t})\n\n\t\t/**\n\t\t * Handle errors\n\t\t */\n\t\t.onError(handleError)\n\n\t\t/**\n\t\t * Database routes - available at root level (no dbType required)\n\t\t */\n\t\t.route(\"/\", databasesRoutes)\n\t\t.route(\"/\", chatRoutes)\n\n\t\t/**\n\t\t * Serve static assets (before dbType validation to avoid conflicts)\n\t\t */\n\t\t.use(\"/assets/*\", serveStatic({ root: getCoreDistPath() }))\n\t\t.use(\"/image.png\", serveStatic({ root: getCoreDistPath() }))\n\n\t\t/**\n\t\t * Routes that require dbType validation - under /:dbType/...\n\t\t */\n\t\t.use(\"/:dbType/*\", zValidator(\"param\", databaseTypeParamSchema, validationHook))\n\t\t.use(\"/:dbType/*\", async (c, next) => {\n\t\t\tconst dbType = c.req.param(\"dbType\") as DatabaseTypeSchema;\n\t\t\tc.set(\"dbType\", dbType);\n\t\t\tawait next();\n\t\t})\n\t\t.route(\"/:dbType\", tablesRoutes)\n\t\t.route(\"/:dbType\", recordsRoutes)\n\t\t.route(\"/:dbType\", queryRoutes)\n\n\t\t/**\n\t\t * Serve all other static files as fallback (for SPA)\n\t\t */\n\t\t.use(\"/*\", serveStatic({ root: getCoreDistPath() }));\n\n\treturn { app };\n};\n\nexport type { AppType };\n\n// Export the app type for hc client\nexport type AppRoutes = ReturnType<typeof createServer>[\"app\"];\n","import { intro, outro } from \"@clack/prompts\";\nimport { serve } from \"@hono/node-server\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { args } from \"@/cmd/args.js\";\nimport { getDatabaseUrl } from \"@/cmd/get-db-url.js\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\nimport { showHelp } from \"@/cmd/show-help.js\";\nimport { showStatus } from \"@/cmd/show-status.js\";\nimport { showVersion } from \"@/cmd/show-version.js\";\n\nexport const main = async () => {\n\tconst { env, port, databaseUrl, varName, status, help, version } = args();\n\n\t// Handle help flag\n\tif (help) {\n\t\tshowHelp();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle version flag\n\tif (version) {\n\t\tshowVersion();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle status flag\n\tif (status) {\n\t\tawait showStatus(env, databaseUrl, varName);\n\t\tprocess.exit(0);\n\t}\n\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst PORT = port ? parseInt(port, 10) : DEFAULTS.PORT;\n\tconst VAR_NAME = varName || DEFAULTS.VAR_NAME;\n\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\tconst DATABASE_URL = databaseUrl ? databaseUrl : await getDatabaseUrl(ENV, VAR_NAME);\n\n\t// Set DATABASE_URL in process.env before importing createServer\n\t// This ensures the db pool is initialized with the correct connection string\n\tprocess.env.DATABASE_URL = DATABASE_URL;\n\n\t// Import createServer dynamically after setting DATABASE_URL\n\tconst { createServer } = await import(\"./utils/create-server.js\");\n\tconst { app } = createServer();\n\tserve({\n\t\tfetch: app.fetch,\n\t\tport: PORT,\n\t});\n\n\toutro(color.green(`Server running at ${color.cyan(`http://localhost:${PORT}`)}`));\n};\n\nmain().catch((err) => {\n\tconsole.error(color.red(`❌ Unexpected error: ${err.message}`));\n\tprocess.exit(1);\n});\n","import { program } from \"commander\";\nimport type { Args } from \"shared/types\";\n\n/**\n * Get the arguments from the command line\n */\nexport const args = () => {\n\tprogram\n\t\t.name(\"db-studio\")\n\t\t.option(\"-e, --env <path>\", \"Path to custom .env file\")\n\t\t.option(\"-p, --port <port>\", \"Port to run the server on\")\n\t\t.option(\"-d, --database-url <url>\", \"Database URL to use\")\n\t\t.option(\n\t\t\t\"-n, --var-name <name>\",\n\t\t\t\"Custom environment variable name (default: DATABASE_URL)\",\n\t\t)\n\t\t.option(\"-s, --status\", \"Show status of the server\")\n\t\t.option(\"-h, --help\", \"Show help\")\n\t\t.option(\"-v, --version\", \"Show version\")\n\t\t.parse(process.argv);\n\n\treturn program.opts<Args>();\n};\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { cancel, isCancel, note, select, spinner, text } from \"@clack/prompts\";\nimport { type DotenvParseOutput, parse as parseDotenv } from \"dotenv\";\nimport color from \"picocolors\";\n\n/**\n * Get the database URL from .env file, then process.env\n */\nexport const getDatabaseUrl = async (env?: DotenvParseOutput | null, varName?: string) => {\n\tconst envVarName = varName || \"DATABASE_URL\";\n\n\tif (env?.[envVarName]) {\n\t\treturn env[envVarName];\n\t}\n\n\t// Fall back to process.env (e.g. from shell or package.json script)\n\tif (process.env[envVarName]) {\n\t\treturn process.env[envVarName];\n\t}\n\n\tconst s = spinner();\n\ts.start(\"Looking for database connection...\");\n\n\tif (!env) {\n\t\tnote(color.red(`No .env file found and ${envVarName} not set in process.env`));\n\t} else {\n\t\tnote(color.red(`${envVarName} not found in .env or process.env`));\n\t}\n\n\tconst choice = await select({\n\t\tmessage: `How do you want to provide ${envVarName}?`,\n\t\toptions: [\n\t\t\t{ value: \"manual\", label: \"Enter connection string manually\" },\n\t\t\t{ value: \"other-env\", label: \"Use different .env file\" },\n\t\t\t// todo: add multiple db connections support\n\t\t\t{ value: \"cancel\", label: \"Cancel / Exit\" },\n\t\t],\n\t\tinitialValue: \"manual\",\n\t});\n\tif (isCancel(choice) || choice === \"cancel\") {\n\t\tcancel(\"No database connection provided. Exiting...\");\n\t\tprocess.exit(0);\n\t}\n\n\tif (choice === \"other-env\") {\n\t\ts.start(\"Waiting for path...\");\n\t\tconst customPath = await text({\n\t\t\tmessage: \"Enter path to .env file\",\n\t\t\tplaceholder: \"~/projects/myapp/.env.local or ./special.env\",\n\t\t\tvalidate(value?: string) {\n\t\t\t\tif (!value?.trim()) return \"Path is required\";\n\t\t\t},\n\t\t});\n\n\t\tif (isCancel(customPath)) {\n\t\t\tcancel(\"Cancelled.\");\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ts.stop(\"Trying custom .env...\");\n\n\t\tconst customEnvPath = resolve(customPath);\n\t\ttry {\n\t\t\tconst content = await readFile(customEnvPath, \"utf-8\");\n\t\t\tconst parsed = parseDotenv(content);\n\t\t\tif (parsed[envVarName]) {\n\t\t\t\treturn parsed[envVarName];\n\t\t\t}\n\t\t\tthrow new Error(`${envVarName} still missing in custom file`);\n\t\t} catch (e: unknown) {\n\t\t\tconst error = e as Error;\n\t\t\tcancel(`Cannot read or parse file: ${color.dim(error.message)}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// 3. Manual input\n\ts.stop(\"Manual input...\");\n\n\tconst dbUrl = await text({\n\t\tmessage: `Paste your ${envVarName}`,\n\t\tplaceholder: \"postgresql://user:password@localhost:5432/mydb\",\n\t\tvalidate(value?: string) {\n\t\t\tif (!value?.trim()) return \"Connection string is required!\";\n\t\t\ttry {\n\t\t\t\tnew URL(value); // very basic check\n\t\t\t\treturn undefined;\n\t\t\t} catch {\n\t\t\t\treturn \"Must be a valid URL format\";\n\t\t\t}\n\t\t},\n\t});\n\n\tif (isCancel(dbUrl)) {\n\t\tcancel(\"Cancelled.\");\n\t\tprocess.exit(0);\n\t}\n\n\treturn dbUrl.trim();\n};\n","import { access, readFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { parse as parseDotenv } from \"dotenv\";\n\n/**\n * Find .env path: try cwd, then walk up parent directories until root.\n */\nconst findEnvPath = async (startDir: string): Promise<string | null> => {\n\tlet dir = resolve(startDir);\n\tfor (;;) {\n\t\tconst envPath = resolve(dir, \".env\");\n\t\ttry {\n\t\t\tawait access(envPath);\n\t\t\treturn envPath;\n\t\t} catch {\n\t\t\t// ENOENT or other: try parent\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n};\n\n/**\n * Load the environment variables from the file.\n * When no path is given: tries current directory, then parent directories until a .env is found.\n * When --env path is given: uses that path only (no walk).\n */\nexport const loadEnv = async (env?: string) => {\n\tlet envPath: string | null;\n\n\tif (env) {\n\t\tenvPath = resolve(env);\n\t} else {\n\t\tenvPath = await findEnvPath(process.cwd());\n\t}\n\n\tif (!envPath) return null;\n\n\ttry {\n\t\tconst content = await readFile(envPath, \"utf-8\");\n\t\treturn parseDotenv(content);\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message.includes(\"ENOENT\")) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { META } from \"shared/constants/meta.js\";\n\n/**\n * Display help information\n */\nexport const showHelp = () => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconsole.log(color.bold(\"\\nUsage:\"));\n\tconsole.log(\" db-studio [options]\\n\");\n\n\tconsole.log(color.bold(\"Supported Databases:\"));\n\tconsole.log(\" MySQL, PostgreSQL\\n\");\n\n\tconsole.log(color.bold(\"Options:\"));\n\tconsole.log(\" -e, --env <path> Path to custom .env file\");\n\tconsole.log(\" -p, --port <port> Port to run the server on (default: 3333)\");\n\tconsole.log(\" -d, --database-url <url> Database URL to use\");\n\tconsole.log(\n\t\t\" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)\",\n\t);\n\tconsole.log(\" -s, --status Show status of the database connection\");\n\tconsole.log(\" -h, --help Show this help message\");\n\tconsole.log(\" -v, --version Show version number\\n\");\n\n\tconsole.log(color.bold(\"Examples:\"));\n\tconsole.log(\" db-studio\");\n\tconsole.log(\" db-studio -e .env.local\");\n\tconsole.log(\" db-studio -p 4000\");\n\tconsole.log(\" db-studio -d postgresql://user:pass@localhost:5432/mydb\");\n\tconsole.log(\" db-studio -n MY_DATABASE_URL\");\n\tconsole.log(\" db-studio -e .env.production -n PROD_DB_URL\");\n\tconsole.log(\" db-studio --status\\n\");\n\n\toutro(color.green(`For more information, visit: ${META.SITE_DOCS_LINK}`));\n};\n","import { intro, note, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\n\n/**\n * Show connection status\n */\nexport const showStatus = async (env?: string, databaseUrl?: string, varName?: string) => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst envVarName = varName || DEFAULTS.VAR_NAME;\n\tlet foundUrl: string | null = null;\n\n\t// Check if DATABASE_URL is provided via CLI\n\tif (databaseUrl) {\n\t\tfoundUrl = databaseUrl;\n\t} else {\n\t\t// Try .env file, then process.env\n\t\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\t\tif (ENV?.[envVarName]) {\n\t\t\tfoundUrl = ENV[envVarName];\n\t\t} else if (process.env[envVarName]) {\n\t\t\tfoundUrl = process.env[envVarName] ?? null;\n\t\t}\n\t}\n\n\tif (foundUrl) {\n\t\toutro(color.green(`✓ Database connection configured (using ${envVarName})`));\n\t} else {\n\t\tnote(color.red(`✗ ${envVarName} not found`), \"Status\");\n\t\tconsole.log(color.yellow(\"\\n To configure database connection:\"));\n\t\tconsole.log(color.dim(\" • Supported databases: MySQL, PostgreSQL\"));\n\t\tconsole.log(color.dim(` • Add ${envVarName} to your .env file or set it in process.env`));\n\t\tconsole.log(color.dim(\" • Use -d flag: db-studio -d <url>\"));\n\t\tconsole.log(color.dim(\" • Use -e flag: db-studio -e <path-to-env>\"));\n\t\tconsole.log(color.dim(\" • Use -n flag: db-studio -n <var-name>\\n\"));\n\n\t\toutro(color.yellow(\"⚠ No database connection configured\"));\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\n/**\n * Display version information\n */\nexport const showVersion = () => {\n\tintro(color.inverse(\" db-studio \"));\n\toutro(color.green(`🚀 db-studio v${packageJson.version}`));\n};\n","{\n \"name\": \"db-studio\",\n \"type\": \"module\",\n \"version\": \"1.7.10\",\n \"description\": \"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.\",\n \"keywords\": [\n \"database client\",\n \"database gui\",\n \"database browser\",\n \"sql client\",\n \"sql editor\",\n \"query tool\",\n \"table editor\",\n \"data editor\",\n \"postgres\",\n \"postgresql\",\n \"postgresql client\",\n \"postgresql gui\",\n \"pgadmin alternative\",\n \"mysql\",\n \"mysql client\",\n \"ai sql\",\n \"er diagram\",\n \"database management\",\n \"database studio\"\n ],\n \"author\": \"Hüsam 🥑 <devhsmq@gmail.com>\",\n \"homepage\": \"https://dbstudio.sh\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/husamql3/db-studio.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/husamql3/db-studio/issues\"\n },\n \"license\": \"MIT\",\n \"bin\": {\n \"db-studio\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"NODE_ENV=development tsx watch src/index.ts\",\n \"build\": \"tsup --minify --sourcemap\",\n \"prepack\": \"cd ../core && bun run build && cd ../server && bun run build\",\n \"start\": \"node dist/index.js\",\n \"check\": \"biome check --write --unsafe\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.0.1\",\n \"@hono/node-server\": \"^1.19.7\",\n \"@hono/zod-validator\": \"^0.7.6\",\n \"commander\": \"^14.0.3\",\n \"dotenv\": \"^17.3.1\",\n \"hono\": \"^4.10.4\",\n \"mongodb\": \"^7.1.1\",\n \"mssql\": \"^12.2.0\",\n \"mysql2\": \"^3.18.2\",\n \"pg\": \"^8.13.1\",\n \"picocolors\": \"^1.1.1\",\n \"xlsx\": \"^0.18.5\",\n \"zod\": \"^4.2.1\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.2.6\",\n \"@types/node\": \"^25.6.0\",\n \"@types/pg\": \"^8.16.0\",\n \"@types/mssql\": \"^12.3.0\",\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"shared\": \"workspace:*\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.7.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.0.17\"\n }\n}\n"],"mappings":"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","names":["init_chat","__esmMin","init_column_types_mysql","__esmMin","init_column_types_pgsql","__esmMin","nodeEnv","DEFAULTS","init_defaults","__esmMin","init_links","__esmMin","META","init_meta","__esmMin","init_proxy_limits","__esmMin","init_constants","__esmMin","init_chat","init_column_types_mysql","init_column_types_pgsql","init_defaults","init_links","init_meta","init_proxy_limits","z","databaseSchema","DATABASE_TYPES","databaseTypeSchema","currentDatabaseSchema","databaseTypeParamSchema","tableNameSchema","init_database_types","__esmMin","z","addColumnSchema","addColumnParamsSchema","init_add_column_types","__esmMin","init_database_types","databaseSchema","tableNameSchema","z","addRecordSchema","init_add_record_types","__esmMin","z","deleteColumnQuerySchema","deleteColumnParamSchema","deleteColumnParamsSchema","deleteColumnSuccessResponseSchema","init_delete_column_types","__esmMin","init_database_types","databaseSchema","val","z","alterColumnSchema","alterColumnParamsSchema","init_alter_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","init_api_response_types","__esmMin","z","bulkInsertRecordsSchema","init_bulk_insert_records_type","__esmMin","messagePart","chatSchema","init_chat_types","__esmMin","init_database_types","databaseSchema","init_cmd_args_types","__esmMin","z","dataTypes","dataTypesSchema","DataTypes","standardizedDataTypes","standardizedDataTypeSchema","columnInfoSchema","init_column_info_types","__esmMin","mapPostgresToDataType","pgType","normalized","DataTypes","standardizeDataTypeLabel","StandardizedDataType","mapMysqlToDataType","mysqlDataType","columnType","fullType","standardizeMysqlDataTypeLabel","mapMssqlToDataType","mssqlDataType","standardizeMssqlDataTypeLabel","init_column_type","__esmMin","init_column_info_types","z","FOREIGN_KEY_ACTIONS","foreignKeyActionSchema","fieldDataSchema","foreignKeyDataSchema","createTableSchema","init_create_table_types","__esmMin","z","databaseInfoSchema","databaseListSchema","connectionInfoSchema","init_database_list_types","__esmMin","init_database_types","databaseTypeSchema","init_database_schema_type","__esmMin","z","deleteRecordSchema","init_delete_record_types","__esmMin","z","deleteTableQuerySchema","init_delete_table_types","__esmMin","init_database_types","databaseSchema","val","z","executeQuerySchema","init_execute_query_types","__esmMin","z","FORMAT_TYPES","exportTableSchema","init_export_table_types","__esmMin","init_database_types","databaseSchema","init_rate_limit_response_type","__esmMin","z","renameColumnSchema","renameColumnParamsSchema","init_rename_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","z","filterSchema","sortDirections","sortSchema","tableDataMetaSchema","tableDataResultSchema","tableDataQuerySchema","init_table_data_types","__esmMin","init_database_types","databaseSchema","val","parsed","z","tableInfoSchema","init_table_info_type","__esmMin","z","tableSchemaResultSchema","init_table_schema_types","__esmMin","z","updateRecordsSchema","init_update_recors_types","__esmMin","init_types","__esmMin","init_add_column_types","init_add_record_types","init_alter_column_types","init_api_response_types","init_bulk_insert_records_type","init_chat_types","init_cmd_args_types","init_column_type","init_column_info_types","init_create_table_types","init_database_types","init_database_list_types","init_database_schema_type","init_delete_column_types","init_delete_record_types","init_delete_table_types","init_execute_query_types","init_export_table_types","init_rate_limit_response_type","init_rename_column_types","init_table_data_types","init_table_info_type","init_table_schema_types","init_update_recors_types","HTTPException","DatabaseError","ZodError","handleError","e","c","issue","mysqlError","validationHook","init_error_handler","__esmMin","result","MongoClient","ObjectId","mssql","createMysqlPool","Pool","DatabaseManager","databaseManager","getDbPool","getMysqlPool","getMssqlPool","getDbType","getMongoClient","getMongoDbName","getMongoDb","isValidObjectId","coerceObjectId","init_db_manager","__esmMin","url","protocol","databaseUrl","error","database","connectionString","poolConfig","pool","err","dbName","config","nextClient","pgClosePromises","mysqlClosePromises","mssqlClosePromises","value","canCoerceObjectId","value","isValidObjectId","normalizeValue","inferDataType","mapDataTypeLabel","buildMongoFilters","buildMongoSort","init_mongo_utils","__esmMin","init_db_manager","item","entries","k","v","dataType","filters","andConditions","escapeRegex","parseValue","raw","trimmed","asNumber","coerceObjectId","filter","field","op","sort","order","sortEntries","s","getTableColumns","tableName","db","documents","getMongoDb","SAMPLE_LIMIT","totalDocs","columnMap","ensureColumn","columnName","value","dataType","inferDataType","entry","doc","key","meta","mapDataTypeLabel","init_table_columns_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","getMongoDatabaseSchema","db","options","includeSampleData","maxTables","mongoDb","getMongoDb","collections","tablePromises","collection","name","columns","getTableColumns","table","convertColumn","normalized","row","normalizeValue","key","value","init_schema_dao","__esmMin","init_db_manager","init_mongo_utils","init_table_columns_mongo_dao","col","Pool","dbInstance","getPool","db","init_db","__esmMin","err","error","_target","prop","HTTPException","getTableColumns","tableName","db","pool","getDbPool","query","rows","parsedEnumValues","mapPostgresToDataType","standardizeDataTypeLabel","init_table_columns_dao","__esmMin","init_types","init_db_manager","getTableNames","db","pool","getDbPool","query","rows","r","getTableDescription","tableName","client","getSampleData","convertColumnInfo","col","column","extractRelationships","tables","relationships","table","toTable","toColumn","getDatabaseSchema","options","getDbType","getMongoDatabaseSchema","includeSampleData","includeDescriptions","tablePromises","columns","description","sampleData","getTableColumns","row","key","value","error","getDetailedSchema","init_table_details_schema","__esmMin","init_schema_dao","init_db","init_db_manager","init_table_columns_dao","generateSystemPrompt","schema","dbTypeLower","dbTypeLabel","formatSchemaForPrompt","output","table","col","pkIndicator","fkIndicator","nullable","rel","init_system_prompt_generator","__esmMin","zValidator","Hono","chatRoutes","init_chat_routes","__esmMin","init_constants","init_types","init_table_details_schema","init_system_prompt_generator","c","proxyResponse","DEFAULTS","data","chatSchema","messages","db","conversationId","schema","getDetailedSchema","systemPrompt","generateSystemPrompt","payload","errorData","readable","writable","HTTPException","addRecord","db","params","tableName","data","pool","getDbPool","columns","values","placeholders","_","index","columnNames","col","query","result","init_add_record_dao","__esmMin","init_db_manager","HTTPException","bulkInsertRecords","init_bulk_insert_records_dao","__esmMin","init_db_manager","tableName","records","db","client","getDbPool","columns","columnNames","col","successCount","failureCount","errors","i","record","values","placeholders","_","index","insertSQL","error","createTable","tableData","db","tableName","fields","foreignKeys","pool","getDbPool","columnDefinitions","field","columnDef","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_dao","__esmMin","init_db_manager","parseDatabaseUrl","databaseUrl","url","protocol","defaultPort","init_parse_database_url","__esmMin","HTTPException","getDatabasesList","pool","getDbPool","query","rows","getCurrentDatabase","getDatabaseConnectionInfo","result","connectionInfoSchema","urlDefaults","parseDatabaseUrl","init_database_list_dao","__esmMin","init_types","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","cascade","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","dropColumnSQL","rowCount","init_delete_column_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","constraintsByTable","constraint","key","pkValues","pk","_tableColumn","constraints","placeholders","_","i","relatedQuery","relatedResult","deleteRecords","pkColumn","query","result","error","forceDeleteRecords","totalRelatedDeleted","deletedTables","deleteRelatedRecursively","targetTable","targetColumn","values","nestedFks","nestedFk","nestedPlaceholders","selectQuery","nestedValues","deletePlaceholders","deleteQuery","deleteResult","init_delete_records_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedQuery","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableExistsQuery","tableRows","rowCount","dropTableSQL","error","init_delete_table_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getDbPool","rows","init_export_table_dao","__esmMin","init_db_manager","HTTPException","addRecord","db","params","tableName","data","collection","getMongoDb","payload","normalizeValue","init_add_record_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","HTTPException","bulkInsertRecords","init_bulk_insert_records_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","tableName","records","db","collection","getMongoDb","docs","record","normalized","normalizeValue","result","error","HTTPException","createTable","tableData","db","tableName","mongoDb","getMongoDb","fields","properties","required","field","bsonType","mapMongoBsonType","MONGO_BSON_TYPES","init_create_table_mongo_dao","__esmMin","init_db_manager","rawType","normalized","HTTPException","getMongoDatabasesList","databases","getMongoClient","db","formatBytes","getMongoCurrentDatabase","getMongoDbName","getMongoConnectionInfo","admin","urlDefaults","parseDatabaseUrl","serverStatus","init_database_list_dao","__esmMin","init_db_manager","init_parse_database_url","bytes","units","value","unitIndex","init_database_list_mongo_dao","__esmMin","init_database_list_dao","deleteColumn","tableName","columnName","db","getMongoDb","init_delete_column_mongo_dao","__esmMin","init_db_manager","deleteRecords","tableName","primaryKeys","db","collection","getMongoDb","pkColumn","pkValues","pk","canCoerceObjectId","coerceObjectId","forceDeleteRecords","init_delete_records_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","HTTPException","deleteTable","tableName","db","collection","getMongoDb","rowCount","error","init_delete_table_mongo_dao","__esmMin","init_db_manager","exportTableData","tableName","db","normalized","getMongoDb","row","normalizeValue","init_export_table_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","HTTPException","normalizeIdFilter","executeMongoQuery","init_query_dao","__esmMin","init_db_manager","init_mongo_utils","filter","coerceObjectId","obj","val","query","db","payload","collection","getMongoDb","startTime","rows","rowCount","message","cursor","sort","buildMongoSort","pipeline","doc","docs","result","duration","normalizedRows","row","normalizeValue","init_query_mongo_dao","__esmMin","init_query_dao","getTablesList","db","mongoDb","getMongoDb","collections","results","collection","name","rowCount","init_table_list_mongo_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","mongoDb","getMongoDb","collection","docs","SAMPLE_LIMIT","totalDocs","fieldTypes","fieldPresence","doc","key","value","bsonType","inferBsonType","properties","required","field","types","presence","isRequired","typeList","t","isNullable","schema","init_table_schema_mongo_dao","__esmMin","init_db_manager","bson","getTableData","tableName","cursor","limit","direction","sort","order","filters","db","collection","getMongoDb","filterObject","buildMongoFilters","sortObject","buildMongoSort","safeLimit","decodedCursor","decodeCursor","offset","skip","total","rows","normalizedRows","row","normalizeValue","nextOffset","prevOffset","encodeCursor","init_tables_data_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","parsed","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","collection","getMongoDb","totalUpdated","pkField","updatesByRow","update","pkValue","updateSet","queryValue","canCoerceObjectId","coerceObjectId","result","init_update_records_mongo_dao","__esmMin","init_db_manager","init_mongo_utils","HTTPException","parseCheckConstraintValues","checkClause","matches","m","getTableColumns","tableName","db","pool","getMssqlPool","result","checkResult","checkEnumMap","row","values","r","dataType","enumValues","mapMssqlToDataType","standardizeMssqlDataTypeLabel","init_table_columns_mssql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMssqlPool","tableColumns","getTableColumns","booleanColumns","col","identityResult","identityColumns","r","columns","values","value","columnNames","paramNames","_col","idx","query","request","result","init_add_record_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","tableName","records","db","transaction","getMssqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","request","values","value","paramNames","_","idx","_col","insertSQL","error","formatMssqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMssql","isArray","normalized","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMssqlPool","columnDefinitions","field","mappedType","columnDef","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mssql_dao","__esmMin","init_db_manager","HTTPException","getDatabasesList","result","getMssqlPool","getCurrentDatabase","getDatabaseConnectionInfo","info","urlDefaults","parseDatabaseUrl","init_database_list_mssql_dao","__esmMin","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMssqlPool","tableCheckResult","columnCheckResult","init_delete_column_mssql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getMssqlPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","request","value","idx","paramList","_","relatedResult","deleteRecords","pkColumn","transaction","result","error","MSSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","selectRequest","val","selectParamList","nestedValues","deleteRequest","deleteParamList","deleteResult","mainRequest","mainParamList","init_delete_records_mssql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getMssqlPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableCheckResult","rowCount","fk","error","MSSQL_FK_DEPENDENCY","init_delete_table_mssql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","result","getMssqlPool","init_export_table_mssql_dao","__esmMin","init_db_manager","HTTPException","executeQuery","init_query_mssql_dao","__esmMin","init_db_manager","query","db","pool","getMssqlPool","cleanedQuery","startTime","result","duration","rows","getTablesList","db","pool","getMssqlPool","result","table","countRow","init_table_list_mssql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMssqlPool","tableCheckResult","schemaResult","columns","col","columnDef","init_table_schema_mssql_dao","__esmMin","init_db_manager","getTableData","init_tables_data_mssql_dao","__esmMin","init_db_manager","tableName","cursor","limit","direction","sort","order","filters","db","pool","getMssqlPool","page","offset","sortClause","s","countResult","totalRows","rows","hasMore","nextCursor","prevCursor","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMssqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","transaction","totalUpdated","rowUpdates","setClauses","u","idx","request","value","query","result","error","init_update_records_mssql_dao","__esmMin","init_db_manager","init_table_columns_mssql_dao","HTTPException","parseMysqlEnumValues","columnType","match","v","getTableColumns","tableName","db","pool","getMysqlPool","query","rows","dataType","enumValues","mapMysqlToDataType","standardizeMysqlDataTypeLabel","init_table_columns_mysql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","columns","values","value","index","columnName","placeholders","columnNames","query","result","init_add_record_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","tableName","records","db","connection","getMysqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","values","value","placeholders","insertSQL","error","formatMysqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMysql","isArray","normalized","buildMysqlColumnDefinition","field","options","mappedType","columnDef","init_mysql_column_utils","__esmMin","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMysqlPool","columnDefinitions","field","buildMysqlColumnDefinition","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","getDatabasesList","pool","getMysqlPool","rows","getCurrentDatabase","getDatabaseConnectionInfo","infoRows","connRows","info","activeConnections","urlDefaults","parseDatabaseUrl","init_database_list_mysql_dao","__esmMin","init_db_manager","init_parse_database_url","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMysqlPool","tableRows","columnRows","result","init_delete_column_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","placeholders","relatedRows","deleteRecords","pkColumn","connection","result","error","MYSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","nestedPlaceholders","selectRows","nestedValues","deletePlaceholders","deleteResult","mainPlaceholders","init_delete_records_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","constraint","relatedRows","getTableRowCount","deleteTable","params","cascade","tableRows","rowCount","connection","error","mysqlError","MYSQL_FK_DEPENDENCY","MYSQL_FK_ROW_REFERENCED","init_delete_table_mysql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getMysqlPool","rows","init_export_table_mysql_dao","__esmMin","init_db_manager","HTTPException","executeQuery","init_query_mysql_dao","__esmMin","init_db_manager","query","db","pool","getMysqlPool","cleanedQuery","startTime","result","fields","duration","rows","f","dmlResult","getTablesList","db","pool","getMysqlPool","tablesQuery","tables","table","countRows","countRow","init_table_list_mysql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMysqlPool","tableRows","rows","row","createTableSql","init_table_schema_mysql_dao","__esmMin","init_db_manager","buildWhereClauseMysql","filters","conditions","values","filter","columnName","buildSortClauseMysql","sorts","order","sort","buildCursorWhereClauseMysql","cursorData","direction","sortDirection","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","operator","init_build_clauses_mysql","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_mysql_dao","__esmMin","init_db_manager","init_build_clauses_mysql","data","cursor","pool","tableName","rows","row","limit","direction","sort","order","filters","db","getMysqlPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClauseMysql","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClauseMysql","combinedWhereClause","sortClause","buildSortClauseMysql","effectiveSortClause","col","countRows","totalRows","fetchLimit","dataRows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","connection","totalUpdated","rowUpdates","setClauses","u","values","query","result","error","init_update_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","executeQuery","init_query_dao","__esmMin","init_db_manager","query","db","pool","getDbPool","cleanedQuery","startTime","result","duration","field","getTablesList","db","pool","getDbPool","tablesQuery","tables","table","safeSchemaName","quoteIdentifier","safeTableName","countQuery","rows","init_table_list_dao","__esmMin","init_db_manager","identifier","HTTPException","getTableSchema","tableName","db","pool","getDbPool","tableExistsQuery","tableExistsRows","columnsQuery","columns","constraintsQuery","constraints","indexesQuery","indexes","schemaLines","columnDefs","col","colDef","formatDataType","constraintMap","constraint","existing","constraintDefs","constraintName","constraintColumns","firstConstraint","columnNames","c","foreignTable","foreignColumn","allDefs","index","data_type","udt_name","character_maximum_length","numeric_precision","numeric_scale","init_table_schema_dao","__esmMin","init_db_manager","buildWhereClause","filters","conditions","values","filter","paramIndex","columnName","buildSortClause","sorts","order","sort","buildCursorWhereClause","cursorData","direction","sortDirection","startParamIndex","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","_","i","operator","init_build_clauses","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_dao","__esmMin","init_db_manager","init_build_clauses","data","cursor","pool","tableName","quotedTableName","row","limit","direction","sort","order","filters","db","getDbPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClause","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClause","combinedWhereClause","sortClause","buildSortClause","effectiveSortClause","col","countRes","totalRows","limitParamIndex","dataRes","rows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getDbPool","updatesByRow","update","pkValue","totalUpdated","rowUpdates","setClauses","u","index","values","query","result","error","init_update_records_dao","__esmMin","init_db_manager","getDaoFactory","dbType","daoRegistry","init_dao_factory","__esmMin","init_add_record_dao","init_bulk_insert_records_dao","init_create_table_dao","init_database_list_dao","init_delete_column_dao","init_delete_records_dao","init_delete_table_dao","init_export_table_dao","init_add_record_mongo_dao","init_bulk_insert_records_mongo_dao","init_create_table_mongo_dao","init_database_list_mongo_dao","init_delete_column_mongo_dao","init_delete_records_mongo_dao","init_delete_table_mongo_dao","init_export_table_mongo_dao","init_query_mongo_dao","init_table_columns_mongo_dao","init_table_list_mongo_dao","init_table_schema_mongo_dao","init_tables_data_mongo_dao","init_update_records_mongo_dao","init_add_record_mssql_dao","init_bulk_insert_records_mssql_dao","init_create_table_mssql_dao","init_database_list_mssql_dao","init_delete_column_mssql_dao","init_delete_records_mssql_dao","init_delete_table_mssql_dao","init_export_table_mssql_dao","init_query_mssql_dao","init_table_columns_mssql_dao","init_table_list_mssql_dao","init_table_schema_mssql_dao","init_tables_data_mssql_dao","init_update_records_mssql_dao","init_add_record_mysql_dao","init_bulk_insert_records_mysql_dao","init_create_table_mysql_dao","init_database_list_mysql_dao","init_delete_column_mysql_dao","init_delete_records_mysql_dao","init_delete_table_mysql_dao","init_export_table_mysql_dao","init_query_mysql_dao","init_table_columns_mysql_dao","init_table_list_mysql_dao","init_table_schema_mysql_dao","init_tables_data_mysql_dao","init_update_records_mysql_dao","init_query_dao","init_table_columns_dao","init_table_list_dao","init_table_schema_dao","init_tables_data_dao","init_update_records_dao","addRecord","bulkInsertRecords","createTable","getDatabasesList","getCurrentDatabase","getDatabaseConnectionInfo","deleteColumn","deleteRecords","forceDeleteRecords","deleteTable","exportTableData","executeQuery","getTableColumns","getTablesList","getTableSchema","getTableData","updateRecords","getMongoDatabasesList","getMongoCurrentDatabase","getMongoConnectionInfo","executeMongoQuery","Hono","databasesRoutes","init_databases_routes","__esmMin","init_dao_factory","init_db_manager","c","dbType","getDbType","databases","getDaoFactory","current","info","zValidator","Hono","queryRoutes","init_query_routes","__esmMin","init_types","init_dao_factory","databaseSchema","executeQuerySchema","c","query","db","dbType","data","getDaoFactory","zValidator","Hono","recordsRoutes","init_records_routes","__esmMin","init_types","init_dao_factory","databaseSchema","addRecordSchema","c","db","tableName","data","dbType","dao","getDaoFactory","insertedCount","updateRecordsSchema","primaryKey","updates","updatedCount","deleteRecordSchema","primaryKeys","deletedCount","fkViolation","relatedRecords","bulkInsertRecordsSchema","records","result","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","columnDefinition","init_add_column_dao","__esmMin","init_db_manager","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","client","error","init_alter_column_dao","__esmMin","init_db_manager","HTTPException","addColumn","tableName","columnName","columnType","defaultValue","isNullable","db","mongoDb","getMongoDb","collections","resolvedDefault","resolveDefault","existingSchema","properties","required","init_add_column_mongo_dao","__esmMin","init_db_manager","HTTPException","renameColumn","tableName","columnName","newColumnName","db","mongoDb","getMongoDb","alterColumn","columnType","isNullable","collections","existingSchema","properties","required","bsonType","reqIndex","init_alter_column_mongo_dao","__esmMin","init_db_manager","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getMysqlPool","tableRows","columnRows","columnDefinition","buildMysqlColumnDefinition","init_add_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getMysqlPool","tableRows","columnRows","columnRow","columnDefinition","buildMysqlColumnDefinition","init_alter_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getMysqlPool","tableRows","currentColumnRows","nextColumnRows","init_rename_column_mysql_dao","__esmMin","init_db_manager","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","currentColumnRows","nextColumnRows","init_rename_column_dao","__esmMin","init_db_manager","utils","write","getExportFile","cols","rows","format","tableName","jsonContent","data","row","col","worksheet","csvContent","workbook","buffer","init_get_export_file","__esmMin","zValidator","Hono","tablesRoutes","init_tables_routes","__esmMin","init_types","init_add_column_dao","init_alter_column_dao","init_dao_factory","init_add_column_mongo_dao","init_alter_column_mongo_dao","init_add_column_mysql_dao","init_alter_column_mysql_dao","init_rename_column_mysql_dao","init_rename_column_dao","init_get_export_file","databaseSchema","c","db","dbType","tablesList","getDaoFactory","createTableSchema","body","deleteTableQuerySchema","tableNameSchema","cascade","tableName","result","deleteColumnQuerySchema","deleteColumnParamSchema","columnName","dao","deletedCount","addColumnSchema","addColumn","renameColumnSchema","renameColumn","alterColumnSchema","alterColumn","columns","schema","tableDataQuerySchema","cursor","limit","direction","sort","order","filters","tableData","exportTableSchema","format","cols","rows","fileContent","getExportFile","contentType","create_server_exports","__export","createServer","path","fileURLToPath","serveStatic","zValidator","Hono","cors","logger","prettyJSON","getCoreDistPath","init_create_server","__esmMin","init_types","init_error_handler","init_chat_routes","init_databases_routes","init_query_routes","init_records_routes","init_tables_routes","__dirname","_","next","c","handleError","databasesRoutes","chatRoutes","databaseTypeParamSchema","validationHook","dbType","tablesRoutes","recordsRoutes","queryRoutes","init_constants","intro","outro","serve","color","program","args","readFile","resolve","cancel","isCancel","note","select","spinner","text","parseDotenv","color","getDatabaseUrl","env","varName","envVarName","s","choice","customPath","value","customEnvPath","content","parsed","e","error","dbUrl","access","readFile","dirname","resolve","parseDotenv","findEnvPath","startDir","dir","envPath","parent","loadEnv","env","content","err","init_meta","intro","outro","color","showHelp","META","init_constants","intro","note","outro","color","showStatus","env","databaseUrl","varName","intro","color","envVarName","DEFAULTS","foundUrl","ENV","loadEnv","outro","note","intro","outro","color","package_default","showVersion","intro","color","outro","package_default","main","env","port","databaseUrl","varName","status","help","version","args","showHelp","showVersion","showStatus","intro","color","PORT","DEFAULTS","VAR_NAME","ENV","loadEnv","DATABASE_URL","getDatabaseUrl","createServer","app","serve","outro","err"]}
|