aquameta-datum
Version:
Service layer for the Aquameta database API
137 lines (125 loc) • 17.2 kB
JavaScript
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