@fewer/adapter-postgres
Version:
A Fewer database adapter to connect to Postgres
168 lines • 6.4 kB
JavaScript
;
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