UNPKG

@fewer/adapter-postgres

Version:

A Fewer database adapter to connect to Postgres

168 lines 6.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fewer_1 = require("fewer"); const pg_1 = require("pg"); const squel_1 = __importDefault(require("./squel")); const migrate_1 = __importDefault(require("./migrate")); const columnTypes_1 = __importDefault(require("./columnTypes")); // TODO: Allow custom methods to be defined on the adapter rather than having this here: const rawQuery_1 = __importDefault(require("./rawQuery")); exports.rawQuery = rawQuery_1.default; const infos_1 = __importDefault(require("./infos")); async function ensureMigrationTable(db) { await rawQuery_1.default(db, `CREATE TABLE IF NOT EXISTS _fewer_version ( id bigserial PRIMARY KEY, version varchar UNIQUE )`); } function applyJoins(table, prefix, select, joins) { for (const key in joins) { const alias = `${prefix}_${key}`; const join = joins[key]; select.join(join.tableName, alias, `${alias}.${join.keys[1]} = ${table}.${join.keys[0]}`); const subJoins = join.select.context.joins; if (subJoins) { applyJoins(alias, alias, select, subJoins); } } } function applyWheres(table, prefix, select, joins, wheres) { for (const where of wheres) { for (const [fieldName, matcher] of Object.entries(where)) { if (joins && fieldName in joins) { const alias = `${prefix}_${fieldName}`; const nestedJoins = joins[fieldName].select.context.joins; const nestedWhere = [Object.entries(matcher).reduce((result, [k, v]) => { if (nestedJoins && k in nestedJoins) { result[k] = v; } else { result[`${alias}.${k}`] = v; } return result; }, {})]; applyWheres(alias, alias, select, joins[fieldName].select.context.joins, nestedWhere); } else { if (Array.isArray(matcher)) { select.where(`${fieldName} IN ?`, matcher); } else { select.where(`${fieldName} = ?`, matcher); } } } } } exports.Adapter = fewer_1.createAdapter({ columnTypes: columnTypes_1.default, async connect(options) { const client = new pg_1.Client(options); await client.connect(); return client; }, async disconnect(db) { await db.end(); }, async select(db, context) { const select = squel_1.default.select().from(context.table); if (context.limit) { select.limit(context.limit); } if (context.offset) { select.offset(context.offset); } for (const field of context.plucked) { if (Array.isArray(field)) { select.field(...field); } else { select.field(field); } } const joins = context.joins; if (joins) { applyJoins(context.table, '', select, joins); } applyWheres(context.table, '', select, joins, context.wheres); const results = await db.query(select.toString()); const loads = context.loads; if (loads) { const loadPromises = Object.keys(loads).map(async (k) => { const load = loads[k]; const where = {}; where[load.keys[1]] = results.rows.map((r) => r[load.keys[0]]); return { k, load, results: await this.select(db, load.select.where(where).context) }; }); const loaded = await Promise.all(loadPromises); loaded.forEach((load) => { const grouped = load.results.reduce((m, v) => { if (!m[v[load.load.keys[1]]]) { m[v[load.load.keys[1]]] = []; } m[v[load.load.keys[1]]].push(v); return m; }, {}); results.rows.forEach((row) => { row[load.k] = grouped[row[load.load.keys[0]]] ? grouped[row[load.load.keys[0]]] : []; }); }); } return results.rows; }, async insert(db, context) { const insert = squel_1.default .insert() .into(context.table) .setFields(context.columns) .returning(context.primaryKey); const results = await db.query(insert.toString()); return results.rows[0][context.primaryKey]; }, async update(db, context) { const update = squel_1.default .update() .table(context.table) .where(`${context.primaryKey[0]} = ?`, [context.primaryKey[1]]) .setFields(context.columns); const results = await db.query(update.toString()); return results.rows; }, async migrateAddVersion(db, version) { await ensureMigrationTable(db); await rawQuery_1.default(db, 'INSERT INTO _fewer_version (version) VALUES ($1)', [ version, ]); }, async migrateRemoveVersion(db, version) { await ensureMigrationTable(db); await rawQuery_1.default(db, 'DELETE FROM _fewer_version WHERE version=$1', [ version, ]); }, async migrateGetVersions(db) { await ensureMigrationTable(db); const versions = await rawQuery_1.default(db, 'SELECT * FROM _fewer_version ORDER BY id ASC'); return versions.map(({ version }) => version); }, async migrateHasVersion(db, version) { await ensureMigrationTable(db); const versions = await rawQuery_1.default(db, 'SELECT id FROM _fewer_version WHERE version=$1', [version]); return !!versions.length; }, async migrate(db, direction, migration) { const query = migrate_1.default(migration); const results = await db.query(query); return results; }, async getInfos(db) { return await infos_1.default(db); } }); //# sourceMappingURL=index.js.map