utilitas 1995.2.12 → 1995.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/dbio.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import {
2
- assertSet, ensureArray, ensureString, log as _log, need,
2
+ assertSet, ensureArray, ensureString, log as _log, need, throwError,
3
3
  } from './utilitas.mjs';
4
4
 
5
5
  import { isPrimary } from './callosum.mjs';
@@ -9,6 +9,8 @@ const [mysqlDefaultPort, postgresqlDefaultPort] = [3306, 5432];
9
9
  const [mysqlQuote, postgresqlQuote] = ['`', ''];
10
10
  const IFSC = 'information_schema';
11
11
  const orders = { '+': 'ASC', '-': 'DESC' };
12
+ const [INSERT, UPDATE, RETURNING] = ['INSERT', 'UPDATE', 'RETURNING'];
13
+ const RETURNING_ALL = ` RETURNING *`;
12
14
  const [fieldId, fieldAny] = ['id', '*'];
13
15
  const fieldCount = `COUNT(${fieldAny})`;
14
16
  const direct = { direct: true };
@@ -22,9 +24,10 @@ const [MYSQL, POSTGRESQL] = ['MYSQL', 'POSTGRESQL'];
22
24
  const quote = name => `${bracket}${name}${bracket}`;
23
25
  const join = elements => elements.join(', ');
24
26
  const assembleDelete = table => `DELETE FROM ${quote(assertTable(table))}`;
27
+ const execByQuery = async (...a) => await rawQuery(...distillArguments(...a));
25
28
 
26
- let provider, pool, actExecute, bracket, actDuplicate, sqlShowTables,
27
- placeholder, sqlShowIndexes, fieldCountResult, sqlDesc, doublePlaceholder;
29
+ let provider, pool, actExecute, bracket, sqlShowTables, placeholder,
30
+ sqlShowIndexes, fieldCountResult, sqlDesc, doublePlaceholder;
28
31
 
29
32
  const init = async (options) => {
30
33
  if (options) {
@@ -37,12 +40,11 @@ const init = async (options) => {
37
40
  const mysql = await need('mysql2/promise');
38
41
  delete options.provider;
39
42
  [
40
- provider, pool, port, actExecute, bracket, actDuplicate,
41
- sqlShowTables, placeholder, fieldCountResult,
43
+ provider, pool, port, actExecute, bracket, sqlShowTables,
44
+ placeholder, fieldCountResult,
42
45
  ] = [
43
46
  MYSQL, mysql.createPool(options), mysqlDefaultPort,
44
- 'execute', mysqlQuote, 'ON DUPLICATE KEY',
45
- 'SHOW TABLES', '?', fieldCount,
47
+ 'execute', mysqlQuote, 'SHOW TABLES', '?', fieldCount,
46
48
  ];
47
49
  doublePlaceholder = `${placeholder}${placeholder}`;
48
50
  [sqlShowIndexes, sqlDesc] = [
@@ -57,12 +59,11 @@ const init = async (options) => {
57
59
  // https://node-postgres.com/apis/pool
58
60
  const { Pool } = await need('pg');
59
61
  [
60
- provider, pool, port, actExecute, bracket, actDuplicate,
61
- placeholder, fieldCountResult,
62
+ provider, pool, port, actExecute, bracket, placeholder,
63
+ fieldCountResult,
62
64
  ] = [
63
65
  POSTGRESQL, new Pool(options), postgresqlDefaultPort,
64
- 'query', postgresqlQuote, 'ON CONFLICT DO', '$1',
65
- 'count',
66
+ 'query', postgresqlQuote, '$1', 'count',
66
67
  ];
67
68
  [sqlShowTables, sqlShowIndexes, sqlDesc] = [
68
69
  [`${IFSC}.tables`, 'table_schema', "'public'", direct],
@@ -174,7 +175,15 @@ const assembleQuery = (table, options) => {
174
175
 
175
176
  const rawAssembleKeyValue = (key, value, options) => {
176
177
  assertKeyValue(key, value);
177
- const val = options?.direct ? value : placeholder;
178
+ let _placeholder;
179
+ switch (provider) {
180
+ case MYSQL:
181
+ _placeholder = placeholder;
182
+ break;
183
+ case POSTGRESQL:
184
+ _placeholder = `$${options?.placeholderIndex || 1}`;
185
+ }
186
+ const val = options?.direct ? value : _placeholder;
178
187
  let express = `${getComparison(value) || '='} ${val}`;
179
188
  if (Array.isArray(value)) {
180
189
  assert(value.length, 'Invalid array value.', 500);
@@ -195,36 +204,63 @@ const assembleSet = (data, options) => {
195
204
  const [isArray, result] = [options?.asArray || Array.isArray(data), []];
196
205
  ensureArray(data).map((item) => {
197
206
  assert(Object.keys(item).length, 'Fields are required.', 500);
198
- let [keys, vals, values, dupSql] = [[], [], [], []];
207
+ let [pairs, keys, vals, values, dupSql, i, sql]
208
+ = [[], [], [], [], [], 0, ''];
199
209
  for (let k in item) {
200
210
  keys.push(k);
201
211
  switch (provider) {
202
- case MYSQL: vals.push('?'); break;
203
- case POSTGRESQL: vals.push(`$${vals.length + 1}`); break;
212
+ case MYSQL:
213
+ vals.push('?');
214
+ pairs.push(`${quote(k)} = ?`);
215
+ break;
216
+ case POSTGRESQL:
217
+ vals.push(`$${++i}`);
218
+ pairs.push(`${quote(k)} = $${i}`);
204
219
  }
205
220
  pushValue(values, item[k]);
206
221
  }
207
222
  if (options?.upsert) {
208
223
  for (let k in item) {
209
- dupSql.push(`${quote(k)} = ?`);
224
+ switch (provider) {
225
+ case MYSQL: dupSql.push(`${quote(k)} = ?`); break;
226
+ case POSTGRESQL: dupSql.push(`${quote(k)} = $${++i}`); break;
227
+ }
210
228
  pushValue(values, item[k]);
211
229
  }
212
- dupSql = ` ${actDuplicate} UPDATE ${join(dupSql)}`;
230
+ switch (provider) {
231
+ case MYSQL:
232
+ dupSql = ` ON DUPLICATE KEY UPDATE ${join(dupSql)}`;
233
+ break;
234
+ case POSTGRESQL:
235
+ const target = options?.key ? ` (${options?.key})` : '';
236
+ dupSql = ` ON CONFLICT${target} DO UPDATE SET ${join(dupSql)}`;
237
+ break;
238
+ }
213
239
  } else { dupSql = ''; }
214
- const sql = `${options?.prefix || ''}`
215
- + `(${join(keys.map(quote))}) VALUES (${join(vals)})${dupSql}`
216
- + `${options?.subfix || ''}`
240
+ switch (options?.action) {
241
+ case INSERT:
242
+ sql = `(${join(keys.map(quote))}) VALUES (${join(vals)})`;
243
+ break;
244
+ case UPDATE:
245
+ sql = `SET ${pairs.join(', ')}`;
246
+ break;
247
+ default:
248
+ throwError(`Invalid action: '${options?.action}'.`, 400);
249
+ }
250
+ sql = `${options?.prefix || ''}${sql}${dupSql}${options?.subfix || ''}`;
217
251
  result.push({ sql, values, object: item });
218
252
  });
219
253
  return isArray ? result : result[0];
220
254
  };
221
255
 
222
256
  const assembleInsert = (table, data, options) => assembleSet(data, {
223
- ...options || {}, prefix: `INSERT INTO ${quote(assertTable(table))} `
257
+ ...options || {}, action: INSERT,
258
+ prefix: `INSERT INTO ${quote(assertTable(table))} `,
224
259
  });
225
260
 
226
261
  const assembleUpdate = (table, data, options) => assembleSet(data, {
227
- ...options || {}, prefix: `UPDATE ${quote(assertTable(table))} `
262
+ ...options || {}, action: UPDATE,
263
+ prefix: `UPDATE ${quote(assertTable(table))} `,
228
264
  });
229
265
 
230
266
  const assembleTail = (options) => {
@@ -300,8 +336,8 @@ const insert = async (table, fields, options) => {
300
336
  let [isArray, key, ids, error, result]
301
337
  = [Array.isArray(fields), defaultKey(options), [], [], []];
302
338
  const subfix = provider === POSTGRESQL ? (options?.skipEcho ? (
303
- options?.key ? ` RETURNING ${key}` : ''
304
- ) : ` RETURNING *`) : '';
339
+ options?.key ? ` ${RETURNING} ${key}` : ''
340
+ ) : RETURNING_ALL) : '';
305
341
  for (let item of assembleInsert(
306
342
  table, fields, { ...options || {}, asArray: true, subfix })
307
343
  ) {
@@ -349,11 +385,17 @@ const countByKeyValue = async (table, key, value) => {
349
385
 
350
386
  const updateByKeyValue = async (table, key, value, fields, options) => {
351
387
  assertTable(table);
352
- let { sql, values } = assembleUpdate(table, fields);
353
- sql += assembleKeyValue(key, value) + assembleTail(options);
388
+ const dfKey = defaultKey(options);
389
+ const subfix = assembleKeyValue(key, value, {
390
+ placeholderIndex: Object.keys(fields).length + 1,
391
+ }) + (provider === POSTGRESQL ? (options?.skipEcho ? (
392
+ options?.key ? ` ${RETURNING} ${dfKey}` : ''
393
+ ) : RETURNING_ALL) : '');
394
+ let { sql, values } = assembleUpdate(table, fields, { subfix });
395
+ sql += assembleTail(options);
354
396
  const resp = await query(sql, [...values, value]);
355
- return options?.skipEcho
356
- ? resp : await queryByKeyValue(table, key, value, options);
397
+ return !options?.skipEcho && provider === MYSQL
398
+ ? await queryByKeyValue(table, key, value, options) : resp;
357
399
  };
358
400
 
359
401
  const updateById = async (table, id, fields, options) => {
@@ -367,7 +409,9 @@ const deleteByKeyValue = async (table, key, value, options) => {
367
409
  const sql = assembleDelete(table)
368
410
  + assembleKeyValue(key, value)
369
411
  + assembleTail(options);
370
- return await query(sql, [value]);
412
+ return await {
413
+ [MYSQL]: query, [POSTGRESQL]: execByQuery,
414
+ }[provider](sql, [value]);
371
415
  };
372
416
 
373
417
  const deleteById = async (table, id, options) =>
package/lib/manifest.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  const manifest = {
2
2
  "name": "utilitas",
3
3
  "description": "Just another common utility for JavaScript.",
4
- "version": "1995.2.12",
4
+ "version": "1995.2.13",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "utilitas",
3
3
  "description": "Just another common utility for JavaScript.",
4
- "version": "1995.2.12",
4
+ "version": "1995.2.13",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",