UNPKG

@proddata/node-cratedb

Version:
143 lines 6.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StatementGenerator = void 0; const Serializer_js_1 = require("./Serializer.js"); class StatementGenerator { static createTable(tableName, schema, options) { // Validate column definitions Object.entries(schema).forEach(([col, definition]) => { if ('type' in definition && definition.type !== 'object') { if (definition.defaultValue !== undefined && definition.generatedAlways) { throw new Error(`Column "${col}" cannot have both DEFAULT and GENERATED ALWAYS values`); } } }); // Build column definitions const columns = Object.entries(schema) .map(([col, definition]) => this.buildColumnDefinition(col, definition)) .join(', '); // Build primary key clause if any const primaryKeys = Object.keys(schema) .filter((col) => schema[col].primaryKey) .map((col) => `"${col}"`) .join(', '); const primaryKeyClause = primaryKeys ? `, PRIMARY KEY(${primaryKeys})` : ''; // Start query construction let query = `CREATE TABLE ${this.quoteIdentifier(tableName)} (${columns}${primaryKeyClause})`; // Partition clause if (options?.partitionedBy?.length) { const partitionCols = options.partitionedBy.map((col) => `"${col}"`).join(', '); query += ` PARTITIONED BY (${partitionCols})`; } // Cluster clause if (options?.clusteredBy || options?.numberOfShards) { if (options.clusteredBy && options.numberOfShards) { query += ` CLUSTERED BY ("${options.clusteredBy}") INTO ${options.numberOfShards} SHARDS`; } else if (options.clusteredBy) { query += ` CLUSTERED BY ("${options.clusteredBy}")`; } else if (options.numberOfShards) { query += ` CLUSTERED INTO ${options.numberOfShards} SHARDS`; } } // Replicas clause if (options?.numberOfReplicas !== undefined) { query += ` WITH (number_of_replicas = '${options.numberOfReplicas}')`; } return query + ';'; } static dropTable(tableName) { return `DROP TABLE IF EXISTS ${this.quoteIdentifier(tableName)};`; } static insert(tableName, keys, primaryKeys) { const placeholders = keys.map(() => '?').join(', '); const columns = keys.map((key) => `"${key}"`).join(', '); let query = `INSERT INTO ${this.quoteIdentifier(tableName)} (${columns}) VALUES (${placeholders})`; if (primaryKeys && primaryKeys.length > 0) { const nonPrimaryKeys = keys.filter((key) => !primaryKeys.includes(key)); const updates = nonPrimaryKeys.map((key) => `"${key}" = excluded."${key}"`).join(', '); const pkClause = primaryKeys.map((key) => `"${key}"`).join(', '); query += ` ON CONFLICT (${pkClause}) DO UPDATE SET ${updates}`; } else { query += ' ON CONFLICT DO NOTHING'; } return query + ';'; } static refresh(tableName) { return `REFRESH TABLE ${this.quoteIdentifier(tableName)};`; } static optimize(tableName, options, partitions) { let query = `OPTIMIZE TABLE ${this.quoteIdentifier(tableName)}`; // Build options clause if (options && Object.keys(options).length > 0) { const optionsClauses = Object.entries(options) .map(([key, value]) => `${key}=${Serializer_js_1.Serializer.serialize(value)}`) .join(', '); query += ` WITH (${optionsClauses})`; } // Build partitions clause if (partitions && Object.keys(partitions).length > 0) { const partitionClauses = Object.entries(partitions) .map(([key, value]) => { const val = typeof value === 'string' ? `'${value}'` : value; return `${key}=${val}`; }) .join(', '); query += ` PARTITION (${partitionClauses})`; } return query + ';'; } static getPrimaryKeys() { return ` SELECT column_name FROM information_schema.table_constraints tc JOIN information_schema.key_column_usage kc ON kc.table_catalog = tc.table_catalog AND kc.table_schema = tc.table_schema AND kc.table_name = tc.table_name AND kc.constraint_name = tc.constraint_name WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ? AND tc.table_name = ? ORDER BY kc.ordinal_position;`; } static quoteIdentifier(tableName) { return tableName .split('.') .map((part) => `"${part}"`) .join('.'); } static _prepareOptions(options) { const keys = Object.keys(options).map((key) => `"${key}"`); const values = keys.map(() => '?'); const args = Object.values(options); return { keys, values, args }; } static buildColumnDefinition(colName, definition) { if ('properties' in definition) { // Handle OBJECT type const objectMode = definition.mode ? `(${definition.mode.toUpperCase()})` : ''; const objectProps = Object.entries(definition.properties || {}) .map(([key, prop]) => this.buildColumnDefinition(key, prop)) .join(', '); return `"${colName}" OBJECT${objectMode} AS (${objectProps})`; } const baseDefinition = definition; // Regular column definition let colDef = `"${colName}" ${definition.type.toUpperCase()}`; if (baseDefinition.notNull) colDef += ' NOT NULL'; if (baseDefinition.defaultValue !== undefined) colDef += ` DEFAULT ${baseDefinition.defaultValue}`; if (baseDefinition.generatedAlways) colDef += ` GENERATED ALWAYS AS (${baseDefinition.generatedAlways})`; return colDef; } } exports.StatementGenerator = StatementGenerator; //# sourceMappingURL=StatementGenerator.js.map