Initial import
This commit is contained in:
119
etc/servers/work-server/src/routes/ddl.ts
Executable file
119
etc/servers/work-server/src/routes/ddl.ts
Executable file
@@ -0,0 +1,119 @@
|
||||
import type { FastifyInstance } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
import { db } from '../db/client.js';
|
||||
import { assertIdentifier } from '../lib/identifier.js';
|
||||
|
||||
const columnSchema = z.object({
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
nullable: z.boolean().optional(),
|
||||
primary: z.boolean().optional(),
|
||||
unique: z.boolean().optional(),
|
||||
defaultTo: z.any().optional(),
|
||||
});
|
||||
|
||||
const createTableSchema = z.object({
|
||||
tableName: z.string(),
|
||||
columns: z.array(columnSchema).min(1),
|
||||
});
|
||||
|
||||
const dropTableSchema = z.object({
|
||||
tableName: z.string(),
|
||||
});
|
||||
|
||||
const addColumnSchema = z.object({
|
||||
tableName: z.string(),
|
||||
column: columnSchema,
|
||||
});
|
||||
|
||||
const dropColumnSchema = z.object({
|
||||
tableName: z.string(),
|
||||
columnName: z.string(),
|
||||
});
|
||||
|
||||
const rawDdlSchema = z.object({
|
||||
sql: z.string().min(1),
|
||||
});
|
||||
|
||||
function applyColumn(tableBuilder: any, column: z.infer<typeof columnSchema>) {
|
||||
const name = assertIdentifier(column.name, 'column name');
|
||||
const definition = tableBuilder.specificType(name, column.type);
|
||||
|
||||
if (column.nullable === false) {
|
||||
definition.notNullable();
|
||||
}
|
||||
|
||||
if (column.nullable === true) {
|
||||
definition.nullable();
|
||||
}
|
||||
|
||||
if (column.primary) {
|
||||
definition.primary();
|
||||
}
|
||||
|
||||
if (column.unique) {
|
||||
definition.unique();
|
||||
}
|
||||
|
||||
if (column.defaultTo !== undefined) {
|
||||
definition.defaultTo(column.defaultTo);
|
||||
}
|
||||
}
|
||||
|
||||
export async function registerDdlRoutes(app: FastifyInstance) {
|
||||
app.post('/api/ddl/create-table', async (request) => {
|
||||
const payload = createTableSchema.parse(request.body);
|
||||
const tableName = assertIdentifier(payload.tableName, 'table name');
|
||||
|
||||
await db.schema.createTable(tableName, (table) => {
|
||||
payload.columns.forEach((column) => {
|
||||
applyColumn(table, column);
|
||||
});
|
||||
});
|
||||
|
||||
return { ok: true, action: 'create-table', tableName };
|
||||
});
|
||||
|
||||
app.post('/api/ddl/drop-table', async (request) => {
|
||||
const payload = dropTableSchema.parse(request.body);
|
||||
const tableName = assertIdentifier(payload.tableName, 'table name');
|
||||
|
||||
await db.schema.dropTableIfExists(tableName);
|
||||
|
||||
return { ok: true, action: 'drop-table', tableName };
|
||||
});
|
||||
|
||||
app.post('/api/ddl/add-column', async (request) => {
|
||||
const payload = addColumnSchema.parse(request.body);
|
||||
const tableName = assertIdentifier(payload.tableName, 'table name');
|
||||
|
||||
await db.schema.alterTable(tableName, (table) => {
|
||||
applyColumn(table, payload.column);
|
||||
});
|
||||
|
||||
return { ok: true, action: 'add-column', tableName, column: payload.column.name };
|
||||
});
|
||||
|
||||
app.post('/api/ddl/drop-column', async (request) => {
|
||||
const payload = dropColumnSchema.parse(request.body);
|
||||
const tableName = assertIdentifier(payload.tableName, 'table name');
|
||||
const columnName = assertIdentifier(payload.columnName, 'column name');
|
||||
|
||||
await db.schema.alterTable(tableName, (table) => {
|
||||
table.dropColumn(columnName);
|
||||
});
|
||||
|
||||
return { ok: true, action: 'drop-column', tableName, columnName };
|
||||
});
|
||||
|
||||
app.post('/api/ddl/raw', async (request) => {
|
||||
const payload = rawDdlSchema.parse(request.body);
|
||||
const result = await db.raw(payload.sql);
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
action: 'raw',
|
||||
result,
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user