entria / graphql-pg-loader

GraphQL PG Loader and Connection helpers
14 stars 0 forks source link

add pg-loader #2

Open sibelius opened 5 years ago

sibelius commented 5 years ago
/**
 * Postgresql Loader use dataloader to batch sql queries
 * @flow
 */
import type { TableSinglePrimaryKey } from '../../TypeDefinition';

function indexResults(results, indexField, cacheKeyFn = key => key) {
  const indexedResults = new Map();
  results.forEach(res => {
    indexedResults.set(cacheKeyFn(res[indexField]), res);
  });
  return indexedResults;
}

function normalizeResults(keys, indexField, cacheKeyFn = key => key) {
  return results => {
    const indexedResults = indexResults(results, indexField, cacheKeyFn);
    return keys.map(val => indexedResults.get(cacheKeyFn(val)) || null);
    //new Error(`Key not found : ${val}`));
  };
}

const pgLoader = async (client: Object, table: TableSinglePrimaryKey, ids: Array<string>, key?: string) => {
  const _key = key || table.primaryKey;
  const where = ids.map(id => `'${id}'`).join(' , ');
  const sql = `select ${Object.keys(table.fields).join(', ')} from ${table.tableName} where ${_key} in (${where})`;

  // console.log('pg loader sql: ', sql);
  // const TAG = `${table.tableName}-${Math.random()}`;
  // console.time(TAG);
  try {
    const result = await client.query(sql, []);
    // console.timeEnd(TAG);

    const { rows } = result;

    // order rows by ids
    return normalizeResults(ids, _key, id => id.toString())(rows);
  } catch (err) {
    console.log('ERROR:POSTGRESQL:', err);
    return normalizeResults(ids, _key, id => id.toString())([]);
  }
};

export default pgLoader;
sibelius commented 5 years ago

usage

export const getLoader = (context: GraphQLContext) =>
  new DataLoader(async ids => pgLoader(context['TableName'], tTable, ids), {
    maxBatchSize: 500,
  });