UNPKG

@alinex/datastore

Version:

Read, work and write data structures from and to differents locations and formats.

121 lines 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.modified = exports.save = exports.load = void 0; const util_1 = require("util"); const debug_1 = require("debug"); const flat = require("flat"); const moment = require("moment"); const async_1 = require("@alinex/async"); let pg = require('pg'); try { // if pg-native is installed, use it require.resolve('pg-native'); pg = pg.native; console.log('Using native pg!'); } catch (e) { } const debug = debug_1.default('datastore:protocol:psql'); const debugDetails = debug_1.default('datastore:details'); // postgres://user:pass@example.com:5432/dbname/schema.table#WHERE ... // postgres://user:pass@example.com:5432/dbname#SELECT * FROM ... function cast(value) { if (value === '') return null; if (value === 'false') return false; if (value === 'true') return true; // string -> number const n = Number(value); if (!isNaN(n)) return n; // string -> date const d = moment(value); if (d.isValid()) return d.toDate(); return value; } function toObject(arr, recordFormat) { let res = recordFormat ? [] : {}; // console.log(res); arr.forEach(row => { if (recordFormat) { res.push(flat.unflatten(row)); } else { const val = Object.values(row); res[val[0]] = cast(val[1]); } }); return recordFormat ? res : flat.unflatten(res); } const load = function (parsedUri, options = {}) { if (!parsedUri.pathname) return Promise.reject(`No pathname given in ${parsedUri.href}`); options.format = 'json'; debug(`loading ${parsedUri.protocol}//${parsedUri.username}@${parsedUri.host}${parsedUri.pathname}`); // @ts-ignore const defaultFallback = moment.createFromInputFallback; // @ts-ignore moment.createFromInputFallback = function (config) { config._d = new Date(NaN); }; const conn = `${parsedUri.protocol}//${parsedUri.username}:${parsedUri.password}@${parsedUri.host}${parsedUri.pathname}`; const sql = decodeURI(parsedUri.hash.substring(1)); // debug(`conn ${conn}`); debug(`query ${sql}`); let client; return ( // connect to database async_1.default .retry(() => { client = new pg.Client({ connectionString: conn }); return client.connect().catch((e) => { debug(`WARN: ${e.message}`); client.end(); return Promise.reject(e); }); }) // query data .then(() => options.search && client.query(`SET search_path TO ${options.search}`)) .then(() => client.query(sql)) .catch((e) => { client.end(); console.error(e); // @ts-ignore moment.createFromInputFallback = defaultFallback; return Promise.reject(e); }) // process results .then((res) => { debugDetails(`postgres rows ${util_1.inspect(res.rowCount)}`); debugDetails(`postgres result ${util_1.inspect(res.rows)}`); const recordFormat = options.records || res.rows.length && Object.keys(res.rows[0]).length > 2; return Promise.resolve(toObject(res.rows, recordFormat)); }) // end connection and return data .then((data) => { client.end(); // @ts-ignore moment.createFromInputFallback = defaultFallback; return Promise.resolve([Buffer.from(JSON.stringify(data)), {}]); })); }; exports.load = load; const save = (function (parsedUri, buffer, options) { if (!parsedUri.pathname) return Promise.reject(`No pathname given in ${parsedUri.href}`); debug(`storing to ${parsedUri.protocol}//${parsedUri.username}@${parsedUri.host}${parsedUri.pathname}`); return Promise.reject(new Error('Save not implemented here!')); }); exports.save = save; const modified = async function (parsedUri, options) { if (!parsedUri.pathname) return Promise.reject(`No pathname given in ${parsedUri.href}`); debug(`last modification check ${parsedUri.protocol}//${parsedUri.username}@${parsedUri.host}${parsedUri.pathname}`); return Promise.resolve(new Date()); // always use current date }; exports.modified = modified; //# sourceMappingURL=postgres.js.map