UNPKG

aquameta-datum

Version:

Service layer for the Aquameta database API

137 lines (125 loc) 17.2 kB
import query from '../query/index.js'; import * as client from '../client.js'; import * as db from '../database/index.js'; import { compose } from 'ramda'; const c = true ? client.connection() : client.endpoint(); const go = query(c); const select = compose(go, db.select); const insert = compose(go, db.insert); const del = compose(go, db.del); // TODO: should query be able to run multiple queries in a single transaction? // TODO: you'd want to be able to do order/limit/include/exlude from these functions too const metaSchema = db.relation('meta.schema'); const metaTable = db.relation('meta.table'); const metaColumn = db.relation('meta.column'); export async function createTable(table, columns) { if (await tableExists(table)) { return; } const rel = db.relation(table); await ensureSchema(rel); await ensureTable(rel); await ensureColumns(rel, columns); } export async function dropTable(table) { const rel = db.relation(table); try { await deleteRows(table); await deleteRows(metaColumn.qualified, { schema_name: rel.schemaName, relation_name: rel.relationName }); await deleteRows(metaTable.qualified, { schema_name: rel.schemaName, name: rel.relationName }); } catch (e) { console.error(e); return false; } return true; } export function getRows(table) { return select(db.relation(table)); } export function insertRows(table, rows) { return insert(db.relation(table), rows); } export async function updateRows(table, fields, equalities) { if (equalities) { const wheres = Object.entries(equalities).map(([key, value]) => { return db.where(key, value); }); await compose(go, ...wheres)(db.update(db.relation(table), fields)); } else { return db.update(db.relation(table), fields); } } export async function deleteRows(table, equalities) { if (equalities) { const wheres = Object.entries(equalities).map(([key, value]) => { return db.where(key, value); }); await compose(del, ...wheres)(db.relation(table)); } else { return del(db.relation(table)); } } export async function tableExists(table) { const rel = db.relation(table); const rows = await compose(select, db.where('schema_name', rel.schemaName), db.where('name', rel.relationName))(metaTable); return rows.length === 1; } async function ensureSchema(rel) { const schemaRows = db.select(metaSchema); const rows = await go(db.where('name', rel.schemaName, schemaRows)); if (rows.length === 0) { return insert(metaSchema, { name: rel.schemaName }); } } async function ensureTable(rel) { const exec = compose(select, db.where('name', rel.relationName), db.where('schema_name', rel.schemaName)); const rows = await exec(metaTable); if (rows.length === 0) { return insert(metaTable, { name: rel.relationName, schema_name: rel.schemaName }); } } async function ensureColumns(rel, columns) { const exec = compose(select, db.include('type_name'), db.include('name'), db.where('relation_name', rel.relationName), db.where('schema_name', rel.schemaName)); const rows = await exec(metaColumn); const columnArray = Object.entries(columns).map(([name, type_name]) => ({ schema_name: rel.schemaName, relation_name: rel.relationName, name, type_name })); if (!rows || !columnsMatch(rows, columnArray)) { // TODO: so many ways to do a full migration return insert(metaColumn, columnArray); } } function columnsMatch(columns = [], targetColumns = []) { // TODO: // So many possibilities here // May need a map of pg types to user types /* const rowMap = rows.reduce( (m, {name, type_name}) => m.set(name, type_name), new Map(), ); return cols.every( ({name, type_name}) => rowMap.has(name) && rowMap.get(name) === type_name, ); */ const colNames = columns.map(({ name }) => name); return targetColumns.every(({ name }) => colNames.includes(name)); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbInF1ZXJ5IiwiY2xpZW50IiwiZGIiLCJjb21wb3NlIiwiYyIsImNvbm5lY3Rpb24iLCJlbmRwb2ludCIsImdvIiwic2VsZWN0IiwiaW5zZXJ0IiwiZGVsIiwibWV0YVNjaGVtYSIsInJlbGF0aW9uIiwibWV0YVRhYmxlIiwibWV0YUNvbHVtbiIsImNyZWF0ZVRhYmxlIiwidGFibGUiLCJjb2x1bW5zIiwidGFibGVFeGlzdHMiLCJyZWwiLCJlbnN1cmVTY2hlbWEiLCJlbnN1cmVUYWJsZSIsImVuc3VyZUNvbHVtbnMiLCJkcm9wVGFibGUiLCJkZWxldGVSb3dzIiwicXVhbGlmaWVkIiwic2NoZW1hX25hbWUiLCJzY2hlbWFOYW1lIiwicmVsYXRpb25fbmFtZSIsInJlbGF0aW9uTmFtZSIsIm5hbWUiLCJlIiwiY29uc29sZSIsImVycm9yIiwiZ2V0Um93cyIsImluc2VydFJvd3MiLCJyb3dzIiwidXBkYXRlUm93cyIsImZpZWxkcyIsImVxdWFsaXRpZXMiLCJ3aGVyZXMiLCJPYmplY3QiLCJlbnRyaWVzIiwibWFwIiwia2V5IiwidmFsdWUiLCJ3aGVyZSIsInVwZGF0ZSIsImxlbmd0aCIsInNjaGVtYVJvd3MiLCJleGVjIiwiaW5jbHVkZSIsImNvbHVtbkFycmF5IiwidHlwZV9uYW1lIiwiY29sdW1uc01hdGNoIiwidGFyZ2V0Q29sdW1ucyIsImNvbE5hbWVzIiwiZXZlcnkiLCJpbmNsdWRlcyJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsS0FBUCxNQUFrQixtQkFBbEI7QUFDQSxPQUFPLEtBQUtDLE1BQVosTUFBd0IsY0FBeEI7QUFDQSxPQUFPLEtBQUtDLEVBQVosTUFBb0Isc0JBQXBCO0FBQ0EsU0FBUUMsT0FBUixRQUFzQixPQUF0QjtBQUVBLE1BQU1DLENBQUMsR0FBRyxPQUFXSCxNQUFNLENBQUNJLFVBQVAsRUFBWCxHQUFpQ0osTUFBTSxDQUFDSyxRQUFQLEVBQTNDO0FBQ0EsTUFBTUMsRUFBRSxHQUFHUCxLQUFL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S0FBZCxDQUFvQixDQUFDO0FBQUMzQixJQUFBQTtBQUFELEdBQUQsS0FBWTBCLFFBQVEsQ0FBQ0UsUUFBVCxDQUFrQjVCLElBQWxCLENBQWhDLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBxdWVyeSBmcm9tICcuLi9xdWVyeS9pbmRleC5qcyc7XG5pbXBvcnQgKiBhcyBjbGllbnQgZnJvbSAnLi4vY2xpZW50LmpzJztcbmltcG9ydCAqIGFzIGRiIGZyb20gJy4uL2RhdGFiYXNlL2luZGV4LmpzJztcbmltcG9ydCB7Y29tcG9zZX0gZnJvbSAncmFtZGEnO1xuXG5jb25zdCBjID0gX19OT0RFX18gPyBjbGllbnQuY29ubmVjdGlvbigpIDogY2xpZW50LmVuZHBvaW50KCk7XG5jb25zdCBnbyA9IHF1ZXJ5KGMpO1xuY29uc3Qgc2VsZWN0ID0gY29tcG9zZShcbiAgZ28sXG4gIGRiLnNlbGVjdCxcbik7XG5jb25zdCBpbnNlcnQgPSBjb21wb3NlKFxuICBnbyxcbiAgZGIuaW5zZXJ0LFxuKTtcbmNvbnN0IGRlbCA9IGNvbXBvc2UoXG4gIGdvLFxuICBkYi5kZWwsXG4pO1xuXG4vLyBUT0RPOiBzaG91bGQgcXVlcnkgYmUgYWJsZSB0byBydW4gbXVsdGlwbGUgcXVlcmllcyBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbj9cbi8vIFRPRE86IHlvdSdkIHdhbnQgdG8gYmUgYWJsZSB0byBkbyBvcmRlci9saW1pdC9pbmNsdWRlL2V4bHVkZSBmcm9tIHRoZXNlIGZ1bmN0aW9ucyB0b29cblxuY29uc3QgbWV0YVNjaGVtYSA9IGRiLnJlbGF0aW9uKCdtZXRhLnNjaGVtYScpO1xuY29uc3QgbWV0YVRhYmxlID0gZGIucmVsYXRpb24oJ21ldGEudGFibGUnKTtcbmNvbnN0IG1ldGFDb2x1bW4gPSBkYi5yZWxhdGlvbignbWV0YS5jb2x1bW4nKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHRhYmxlLCBjb2x1bW5zKSB7XG4gIGlmIChhd2FpdCB0YWJsZUV4aXN0cyh0YWJsZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCByZWwgPSBkYi5yZWxhdGlvbih0YWJsZSk7XG5cbiAgYXdhaXQgZW5zdXJlU2NoZW1hKHJlbCk7XG4gIGF3YWl0IGVuc3VyZVRhYmxlKHJlbCk7XG4gIGF3YWl0IGVuc3VyZUNvbHVtbnMocmVsLCBjb2x1bW5zKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRyb3BUYWJsZSh0YWJsZSkge1xuICBjb25zdCByZWwgPSBkYi5yZWxhdGlvbih0YWJsZSk7XG4gIHRyeSB7XG4gICAgYXdhaXQgZGVsZXRlUm93cyh0YWJsZSk7XG4gICAgYXdhaXQgZGVsZXRlUm93cyhtZXRhQ29sdW1uLnF1YWxpZmllZCwge1xuICAgICAgc2NoZW1hX25hbWU6IHJlbC5zY2hlbWFOYW1lLFxuICAgICAgcmVsYXRpb25fbmFtZTogcmVsLnJlbGF0aW9uTmFtZSxcbiAgICB9KTtcbiAgICBhd2FpdCBkZWxldGVSb3dzKG1ldGFUYWJsZS5xdWFsaWZpZWQsIHtcbiAgICAgIHNjaGVtYV9uYW1lOiByZWwuc2NoZW1hTmFtZSxcbiAgICAgIG5hbWU6IHJlbC5yZWxhdGlvbk5hbWUsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd3ModGFibGUpIHtcbiAgcmV0dXJuIHNlbGVjdChkYi5yZWxhdGlvbih0YWJsZSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0Um93cyh0YWJsZSwgcm93cykge1xuICByZXR1cm4gaW5zZXJ0KGRiLnJlbGF0aW9uKHRhYmxlKSwgcm93cyk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cGRhdGVSb3dzKFxuICB0YWJsZTogc3RyaW5nLFxuICBmaWVsZHM6IHtbc3RyaW5nXTogYW55fSxcbiAgZXF1YWxpdGllcz86IHtbc3RyaW5nXTogYW55fSxcbikge1xuICBpZiAoZXF1YWxpdGllcykge1xuICAgIGNvbnN0IHdoZXJlcyA9IE9iamVjdC5lbnRyaWVzKGVxdWFsaXRpZXMpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICByZXR1cm4gZGIud2hlcmUoa2V5LCB2YWx1ZSk7XG4gICAgfSk7XG4gICAgYXdhaXQgY29tcG9zZShcbiAgICAgIGdvLFxuICAgICAgLi4ud2hlcmVzLFxuICAgICkoZGIudXBkYXRlKGRiLnJlbGF0aW9uKHRhYmxlKSwgZmllbGRzKSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRiLnVwZGF0ZShkYi5yZWxhdGlvbih0YWJsZSksIGZpZWxkcyk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVJvd3ModGFibGU6IHN0cmluZywgZXF1YWxpdGllcz86IHtbc3RyaW5nXTogYW55fSkge1xuICBpZiAoZXF1YWxpdGllcykge1xuICAgIGNvbnN0IHdoZXJlcyA9IE9iamVjdC5lbnRyaWVzKGVxdWFsaXRpZXMpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICByZXR1cm4gZGIud2hlcmUoa2V5LCB2YWx1ZSk7XG4gICAgfSk7XG4gICAgYXdhaXQgY29tcG9zZShcbiAgICAgIGRlbCxcbiAgICAgIC4uLndoZXJlcyxcbiAgICApKGRiLnJlbGF0aW9uKHRhYmxlKSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRlbChkYi5yZWxhdGlvbih0YWJsZSkpO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0YWJsZUV4aXN0cyh0YWJsZSkge1xuICBjb25zdCByZWwgPSBkYi5yZWxhdGlvbih0YWJsZSk7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCBjb21wb3NlKFxuICAgIHNlbGVjdCxcbiAgICBkYi53aGVyZSgnc2NoZW1hX25hbWUnLCByZWwuc2NoZW1hTmFtZSksXG4gICAgZGIud2hlcmUoJ25hbWUnLCByZWwucmVsYXRpb25OYW1lKSxcbiAgKShtZXRhVGFibGUpO1xuICByZXR1cm4gcm93cy5sZW5ndGggPT09IDE7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZVNjaGVtYShyZWwpIHtcbiAgY29uc3Qgc2NoZW1hUm93cyA9IGRiLnNlbGVjdChtZXRhU2NoZW1hKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IGdvKGRiLndoZXJlKCduYW1lJywgcmVsLnNjaGVtYU5hbWUsIHNjaGVtYVJvd3MpKTtcbiAgaWYgKHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGluc2VydChtZXRhU2NoZW1hLCB7bmFtZTogcmVsLnNjaGVtYU5hbWV9KTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVUYWJsZShyZWwpIHtcbiAgY29uc3QgZXhlYyA9IGNvbXBvc2UoXG4gICAgc2VsZWN0LFxuICAgIGRiLndoZXJlKCduYW1lJywgcmVsLnJlbGF0aW9uTmFtZSksXG4gICAgZGIud2hlcmUoJ3NjaGVtYV9uYW1lJywgcmVsLnNjaGVtYU5hbWUpLFxuICApO1xuICBjb25zdCByb3dzID0gYXdhaXQgZXhlYyhtZXRhVGFibGUpO1xuICBpZiAocm93cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gaW5zZXJ0KG1ldGFUYWJsZSwge1xuICAgICAgbmFtZTogcmVsLnJlbGF0aW9uTmFtZSxcbiAgICAgIHNjaGVtYV9uYW1lOiByZWwuc2NoZW1hTmFtZSxcbiAgICB9KTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVDb2x1bW5zKHJlbCwgY29sdW1ucykge1xuICBjb25zdCBleGVjID0gY29tcG9zZShcbiAgICBzZWxlY3QsXG4gICAgZGIuaW5jbHVkZSgndHlwZV9uYW1lJyksXG4gICAgZGIuaW5jbHVkZSgnbmFtZScpLFxuICAgIGRiLndoZXJlKCdyZWxhdGlvbl9uYW1lJywgcmVsLnJlbGF0aW9uTmFtZSksXG4gICAgZGIud2hlcmUoJ3NjaGVtYV9uYW1lJywgcmVsLnNjaGVtYU5hbWUpLFxuICApO1xuICBjb25zdCByb3dzID0gYXdhaXQgZXhlYyhtZXRhQ29sdW1uKTtcbiAgY29uc3QgY29sdW1uQXJyYXkgPSBPYmplY3QuZW50cmllcyhjb2x1bW5zKS5tYXAoKFtuYW1lLCB0eXBlX25hbWVdKSA9PiAoe1xuICAgIHNjaGVtYV9uYW1lOiByZWwuc2NoZW1hTmFtZSxcbiAgICByZWxhdGlvbl9uYW1lOiByZWwucmVsYXRpb25OYW1lLFxuICAgIG5hbWUsXG4gICAgdHlwZV9uYW1lLFxuICB9KSk7XG4gIGlmICghcm93cyB8fCAhY29sdW1uc01hdGNoKHJvd3MsIGNvbHVtbkFycmF5KSkge1xuICAgIC8vIFRPRE86IHNvIG1hbnkgd2F5cyB0byBkbyBhIGZ1bGwgbWlncmF0aW9uXG4gICAgcmV0dXJuIGluc2VydChtZXRhQ29sdW1uLCBjb2x1bW5BcnJheSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29sdW1uc01hdGNoKGNvbHVtbnMgPSBbXSwgdGFyZ2V0Q29sdW1ucyA9IFtdKSB7XG4gIC8vIFRPRE86XG4gIC8vIFNvIG1hbnkgcG9zc2liaWxpdGllcyBoZXJlXG4gIC8vIE1heSBuZWVkIGEgbWFwIG9mIHBnIHR5cGVzIHRvIHVzZXIgdHlwZXNcbiAgLypcbiAgY29uc3Qgcm93TWFwID0gcm93cy5yZWR1Y2UoXG4gICAgKG0sIHtuYW1lLCB0eXBlX25hbWV9KSA9PiBtLnNldChuYW1lLCB0eXBlX25hbWUpLFxuICAgIG5ldyBNYXAoKSxcbiAgKTtcbiAgcmV0dXJuIGNvbHMuZXZlcnkoXG4gICAgKHtuYW1lLCB0eXBlX25hbWV9KSA9PiByb3dNYXAuaGFzKG5hbWUpICYmIHJvd01hcC5nZXQobmFtZSkgPT09IHR5cGVfbmFtZSxcbiAgKTtcbiAgKi9cbiAgY29uc3QgY29sTmFtZXMgPSBjb2x1bW5zLm1hcCgoe25hbWV9KSA9PiBuYW1lKTtcbiAgcmV0dXJuIHRhcmdldENvbHVtbnMuZXZlcnkoKHtuYW1lfSkgPT4gY29sTmFtZXMuaW5jbHVkZXMobmFtZSkpO1xufVxuIl19