UNPKG

mongo2crate

Version:

Sync MongoDB to CrateDB and Convert JSON schema to SQL DDL

80 lines (79 loc) 3.32 kB
import _ from 'lodash/fp.js'; import { setDefaults } from '../util.js'; export const maybeShowColTypes = (endpoint, coltypes) => coltypes ? `${endpoint}?types` : endpoint; export const getInsertColsAndPlaceholders = (fields) => { const columns = fields.map((col) => `"${col}"`).join(','); const placeholders = _.repeat(fields.length - 1, '?,') + '?'; return { columns, placeholders }; }; export const quoteColumn = (column) => { const [first, ...rest] = column.split('.'); let quoted = `"${first}"`; if (rest.length) { for (const inner of rest) { quoted += `['${inner}']`; } } return quoted; }; /** * Given an update object return placeholder assignments and update values */ export const getAssignmentsAndUpdates = (record, update) => { const placeholders = []; const updates = []; const columns = Object.keys(update); for (const column of columns) { // Numeric index so replace the entire value from the root of the nested path if (/\.[0-9]+/.test(column)) { const [first] = column.split('.'); placeholders.push(`${quoteColumn(first)} = ?`); updates.push(record[first]); } else { placeholders.push(`${quoteColumn(column)} = ?`); updates.push(update[column]); } } return { assignments: placeholders.join(','), updates }; }; export const getUniqueKeys = (records) => { const keys = new Set(); // Get all the unique top-level keys records.forEach((rec) => Object.keys(rec).forEach((key) => keys.add(key))); // Sort keys so that the order is deterministic return Array.from(keys).sort(); }; export const getInsertSqlAndArgs = (qualifiedName, record) => { const keys = Object.keys(record); const { columns, placeholders } = getInsertColsAndPlaceholders(keys); const sql = `INSERT INTO ${qualifiedName} (${columns}) VALUES (${placeholders})`; const args = Object.values(record); return { sql, args }; }; export const getDeleteByIdSqlAndArgs = (qualifiedName, id) => { const sql = `DELETE FROM ${qualifiedName} WHERE id = ?`; const args = [id]; return { sql, args }; }; export const getBulkInsertSqlAndArgs = (qualifiedName, records) => { // Get the set of unique keys across all the records const keys = getUniqueKeys(records); const defaults = setDefaults(keys, null); const { columns, placeholders } = getInsertColsAndPlaceholders(keys); const sql = `INSERT INTO ${qualifiedName} (${columns}) VALUES (${placeholders})`; const args = records.map(_.flow(_.defaults(defaults), _.toPairs, _.sortBy(_.head), _.map(_.last))); return { sql, args }; }; export const getUpsertSqlAndArgs = (qualifiedName, record, update) => { const keys = Object.keys(record); const { columns, placeholders } = getInsertColsAndPlaceholders(keys); const { assignments, updates } = getAssignmentsAndUpdates(record, update); const sql = `INSERT INTO ${qualifiedName} (${columns}) VALUES (${placeholders}) ON CONFLICT (id) DO UPDATE SET ${assignments}`; const args = [...Object.values(record), ...updates]; return { sql, args }; }; export const getAuthHeader = (auth) => ({ Authorization: 'Basic ' + Buffer.from(auth, 'binary').toString('base64'), });