// @flow import type { QueryCriteria, QueryObj } from './types'; function flatten(arr: Array>): Array { return arr.reduce((arr, inner) => [ ...arr, ...inner ], []); } function clause(criteria: Array): QueryObj { const clauses = criteria.map(criteria => { const keys = Object.keys(criteria), constraints = keys.map(key => { const val = criteria[key]; if (Array.isArray(val)) { const subsontraints = val.map(() => `${ key } = ?`).join(' OR '); return { sql: subsontraints, args: val }; } else { return { sql: `${ key } = ?`, args: [ val ] }; } }); return { sql: constraints.map(c => c.sql).join(' AND '), args: flatten(constraints.map(c => c.args)) }; }); return { sql: clauses.map(c => `(${ c.sql })`).join(' OR '), args: flatten(clauses.map(c => c.args)) }; } /** * `whereClause :: { where?: QueryCriteria } -> QueryObj` */ export function where(props: {} | { where: Array }): QueryObj { if (props.where != null) { const where = ((props.where: any): Array); if (Array.isArray(where)) { const obj = Array.isArray(where) ? clause(where) : {}; return { sql: `WHERE ${ obj.sql }`, args: obj.args }; } } return { sql: ``, args: [] }; }