json-fs-query 2.3.0 → 3.0.0

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.
Files changed (58) hide show
  1. package/README.md +82 -9
  2. package/browser/jsonFsQuery.js +486 -209
  3. package/browser/jsonFsQuery.min.js +1 -1
  4. package/dist/data/queries/groupBy.d.ts +20 -1
  5. package/dist/data/queries/groupBy.js +71 -9
  6. package/dist/data/queries/groupBy.min.js +1 -1
  7. package/dist/data/queries/limitOffset.d.ts +1 -1
  8. package/dist/data/queries/limitOffset.js +1 -1
  9. package/dist/data/queries/selectFields.d.ts +6 -4
  10. package/dist/data/queries/selectFields.js +15 -10
  11. package/dist/data/queries/selectFields.min.js +1 -1
  12. package/dist/data/utilities/parsers/findCommand.d.ts +2 -1
  13. package/dist/data/utilities/parsers/findCommand.js +5 -5
  14. package/dist/data/utilities/parsers/findCommand.min.js +1 -1
  15. package/dist/data/utilities/parsers/findConditions.d.ts +8 -9
  16. package/dist/data/utilities/parsers/findConditions.js +29 -41
  17. package/dist/data/utilities/parsers/findConditions.min.js +1 -1
  18. package/dist/data/utilities/parsers/findGroupBy.d.ts +6 -4
  19. package/dist/data/utilities/parsers/findGroupBy.js +17 -9
  20. package/dist/data/utilities/parsers/findGroupBy.min.js +1 -1
  21. package/dist/data/utilities/parsers/findInsertValues.d.ts +4 -3
  22. package/dist/data/utilities/parsers/findInsertValues.js +9 -9
  23. package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
  24. package/dist/data/utilities/parsers/findJoinClauses.d.ts +4 -3
  25. package/dist/data/utilities/parsers/findJoinClauses.js +20 -13
  26. package/dist/data/utilities/parsers/findJoinClauses.min.js +1 -1
  27. package/dist/data/utilities/parsers/findJoinEntity.d.ts +1 -1
  28. package/dist/data/utilities/parsers/findJoinEntity.js +3 -5
  29. package/dist/data/utilities/parsers/findJoinEntity.min.js +1 -1
  30. package/dist/data/utilities/parsers/findLimit.d.ts +4 -3
  31. package/dist/data/utilities/parsers/findLimit.js +8 -8
  32. package/dist/data/utilities/parsers/findLimit.min.js +1 -1
  33. package/dist/data/utilities/parsers/findMergeJoins.d.ts +4 -3
  34. package/dist/data/utilities/parsers/findMergeJoins.js +19 -12
  35. package/dist/data/utilities/parsers/findMergeJoins.min.js +1 -1
  36. package/dist/data/utilities/parsers/findOffset.d.ts +4 -3
  37. package/dist/data/utilities/parsers/findOffset.js +8 -8
  38. package/dist/data/utilities/parsers/findOffset.min.js +1 -1
  39. package/dist/data/utilities/parsers/findSelects.d.ts +4 -3
  40. package/dist/data/utilities/parsers/findSelects.js +13 -14
  41. package/dist/data/utilities/parsers/findSelects.min.js +1 -1
  42. package/dist/data/utilities/parsers/findSortClauses.d.ts +4 -3
  43. package/dist/data/utilities/parsers/findSortClauses.js +12 -12
  44. package/dist/data/utilities/parsers/findSortClauses.min.js +1 -1
  45. package/dist/data/utilities/parsers/findUpdateValues.d.ts +5 -7
  46. package/dist/data/utilities/parsers/findUpdateValues.js +10 -13
  47. package/dist/data/utilities/parsers/findUpdateValues.min.js +1 -1
  48. package/dist/data/utilities/parsers/parseQuery.js +83 -9
  49. package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
  50. package/dist/data/utilities/parsers/splitClauses.d.ts +29 -0
  51. package/dist/data/utilities/parsers/splitClauses.js +139 -0
  52. package/dist/data/utilities/parsers/splitClauses.min.js +1 -0
  53. package/dist/data/utilities/runQuery.js +5 -4
  54. package/dist/data/utilities/runQuery.min.js +1 -1
  55. package/package.json +1 -1
  56. package/dist/data/utilities/parsers/removeFromQuery.d.ts +0 -2
  57. package/dist/data/utilities/parsers/removeFromQuery.js +0 -8
  58. package/dist/data/utilities/parsers/removeFromQuery.min.js +0 -1
package/README.md CHANGED
@@ -64,9 +64,9 @@ const [workouts, exercises] = await query("read workouts where date = '2024-06-0
64
64
 
65
65
  The `;` after the last (or only) query is optional. A `;` inside a string, a comment or brackets doesn't end a query.
66
66
 
67
- Write the commands `read`, `insert`, `update` and `delete`, and the sort directions `asc` and `desc`, in lowercase:
68
- `READ t` is an error, and `sort a ASC` sorts descending. Other keywords (`where`, `and`, `sort`, `limit`, `create`,
69
- `show records`...) and comparators can be written in any case.
67
+ Keywords (`where`, `and`, `sort`, `limit`, `create`, `show records`...), command words (`read`, `insert`, `update`,
68
+ `delete`), sort directions (`asc`, `desc`) and comparators can be written in any case: `READ t` and `sort a ASC` work.
69
+ Record and field names are case-sensitive.
70
70
 
71
71
  ### Strings
72
72
 
@@ -166,7 +166,8 @@ matches any text, `_` one character, ignoring case). `is null`, `is not null`, `
166
166
  for null and missing fields (see below). In a where clause, the keywords (`where`, `and`, `or`, `not`, `is null`...) and comparators (`IN`, `LIKE`) can be
167
167
  written in any case (see the casing note under Writing queries).
168
168
 
169
- The older form, a `where` per condition (`where a = 1 and where b = 2`, `or where`), still works and means the same.
169
+ A query has one where clause: join every condition inside it. The 2.x forms of a second where (`and where`,
170
+ `or where`, or another `where`) are errors since 3.0, with a hint to use `and` / `or` instead.
170
171
 
171
172
  Mistakes are errors that point at the place: an unclosed or unexpected bracket, an operator with nothing after it
172
173
  (`where a = 1 and`), empty brackets, or two conditions with nothing between them (`where a = 1 b = 2`).
@@ -254,12 +255,18 @@ These are errors:
254
255
  - a condition on a record that only links the join (`exercise_muscle` above)
255
256
  - a condition on a record that isn't in the query
256
257
  - in `update` and `delete`, any condition on another record's fields. They only change the record they name, and
257
- check its own fields before any join runs.
258
+ take no join (see Clause order).
258
259
 
259
260
  ### Clause order
260
261
 
261
- Clauses can come in any order after the record name, but the SQL order reads best and is recommended (a fixed order
262
- may become required in a later version):
262
+ Every clause is optional and can come at most once, in this order (as in SQL):
263
+
264
+ | Command | Clauses, in order |
265
+ |---|---|
266
+ | `read <record>[.<joined>]` | `select`, `on`, `merge`, `where`, `group by`, `sort`, `limit`, `offset` |
267
+ | `insert <record>` | `values` |
268
+ | `update <record>` | `set`, `where` |
269
+ | `delete <record>` | `where` |
263
270
 
264
271
  ```sql
265
272
  read workouts.exercises select date, reps
@@ -270,6 +277,50 @@ read workouts.exercises select date, reps
270
277
  limit 10 offset 0
271
278
  ```
272
279
 
280
+ Two clauses carry on instead of repeating: `and on` adds another join step, and a `merge` straight after another
281
+ (with or without `and`) adds another merge.
282
+
283
+ Anything else is an error that says what's wrong:
284
+
285
+ | Query | Error |
286
+ |---|---|
287
+ | `read t limit 1 where a = 1` | `"where" can't come after "limit" (order: select, on, merge, where, group by, sort, limit, offset)` |
288
+ | `read t sort a sort b` | `Only one "sort" clause is allowed` |
289
+ | `delete t where a = 1 limit 1` | `"limit" isn't allowed in a delete query (allowed: where)` |
290
+ | `update t.u set a = 1` | `A joined record (t.u) isn't allowed in an update query` |
291
+ | `read t sort a b` | `Unexpected "b" after "sort a"` |
292
+
293
+ A clause word is still a name where a name has to go: as a clause's first word (`sort limit`), after a comma or `as`
294
+ (`select a, offset`), and before a comparator (`where limit = 1`).
295
+
296
+ ### Grouping: `group by`
297
+
298
+ `group by` splits the rows into groups that share a value. A read with it returns a list of groups instead of rows.
299
+ Each group has the field, the value, and its rows, in the order the rows were sorted. For example:
300
+
301
+ ```sql
302
+ read workouts select _id, reps group by date sort date desc
303
+ ```
304
+
305
+ ```js
306
+ [
307
+ { field: 'date', value: '2024-06-05', rows: [{ _id: 4, reps: 10 }, { _id: 5, reps: 10 }] },
308
+ { field: 'date', value: '2024-06-02', rows: [{ _id: 1, reps: 10 }] }
309
+ ]
310
+ ```
311
+
312
+ - Rows are grouped on all their fields, before `select`, so you can group by a field you don't select. `select`
313
+ shapes the rows inside each group, and each group keeps its own `field` and `value`.
314
+ - `sort` runs first, so it orders the groups and the rows within them. `limit` and `offset` count groups:
315
+ `group by date sort date desc limit 7` is the seven latest dates, with all their rows.
316
+ - Several fields nest: `group by date, exercise_id` groups by date, then by exercise within each date. An outer group
317
+ has `groups` instead of `rows`.
318
+ - A value keeps its type: `1` and `'1'` are two groups, and so are `null` and a missing field. Arrays share a group
319
+ when their items are the same, in order; objects when their keys and values are, in any key order. A group of rows
320
+ missing the field has `missing: true` and no `value` (see Null and missing fields).
321
+
322
+ There are no aggregates (`count`, `sum`, ...) yet, so a group always lists its rows.
323
+
273
324
  ### Creating a record: `create`
274
325
 
275
326
  The query form of `create()`. Inside the brackets: the fields, then the keys, separated by commas. Everything is
@@ -353,7 +404,7 @@ queryStatus('read notes;') // { complete: true, waitingFor: ''
353
404
  stored the text `"null"` and an `int` field stored `0`.
354
405
  - `create()` throws for a default that doesn't fit its field's type, and for a nullable primary key field.
355
406
  - `or where` means `or` (2.3). In 1.x it was read as `and where`, returning the wrong rows, and in 2.0 to 2.2 it was an
356
- error.
407
+ error. Since 3.0 it's an error again: use `or` inside one where clause.
357
408
  - A select alias needs `as`: `select name as n`. Before, the first field took the next word as its alias, so
358
409
  `select name where a = 1` failed and `select name limit 1` lost its limit; `select name n` is now an error.
359
410
  - Sort fields need a comma between them: `sort a, b desc`. Before, the list ran on into the next clause, so
@@ -361,7 +412,7 @@ queryStatus('read notes;') // { complete: true, waitingFor: ''
361
412
 
362
413
  ### Upgrading to 2.3
363
414
 
364
- - `and`, `or`, `not` and brackets in a where clause (above). `or where` works again, now as `or`.
415
+ - `and`, `or`, `not` and brackets in a where clause (above). `or where` works again, now as `or` (until 3.0).
365
416
  - A condition on a joined record's field works, as an inner join. Before, an unindexed one matched nothing, and an
366
417
  indexed one (`exercises._id = 1`) returned every row, most of them with an empty list of joined rows. Only rows
367
418
  with a matching joined row are returned now.
@@ -369,6 +420,28 @@ queryStatus('read notes;') // { complete: true, waitingFor: ''
369
420
  - A condition on a record that isn't in the query, or only links a join, is an error. Before, it matched nothing or
370
421
  failed to read the record.
371
422
  - Comparators are case-insensitive (`IN`, `LIKE`). Before, only lowercase ones matched anything.
423
+ - Command words and sort directions are case-insensitive (`READ t`, `sort a ASC`). Before, `READ t` was an
424
+ error and `sort a ASC` sorted descending.
425
+
426
+ ### Upgrading to 3.0
427
+
428
+ Queries that worked in 2.x can be errors now (each error names the problem), and a grouped read returns a new shape:
429
+
430
+ - Clauses come in a fixed order, at most once each (see Clause order). In 2.x any order worked, and a repeated
431
+ clause gave a confusing error or was quietly joined.
432
+ - One where clause per query. `and where`, `or where` and a second `where` are errors: write
433
+ `where a = 1 and b = 2` (or `or`).
434
+ - Only `read` takes a joined record (`t.u`) and `on`. In 2.x a join on `update` or `delete` did nothing useful: a
435
+ condition on the joined record's fields was refused, and without `on` the join was ignored.
436
+ - `sort`, `limit` and `offset` are only for `read`. In 2.x they were accepted on `update` and `delete`, but they ran
437
+ after the change, so they never limited which rows were changed.
438
+ - `group by` returns a list of groups (see Grouping), not an object keyed by value. Because 2.x used an object, its
439
+ number keys always came out ascending (whatever the sort), and every key became a string (`null` became
440
+ `"null"`). `limit` and `offset` count groups now: in 2.x they cut the rows before grouping. Several fields
441
+ (`group by a, b`) nest. In 2.x `group by a,b` grouped every row into one `"undefined"` group.
442
+ - Text a clause can't read is reported against that clause, as `Unexpected "b" after "sort a"` or
443
+ `Missing a whole number after limit: x`. In 2.x these were `Unrecognized query value: ...`. Check any code that
444
+ matches on that message.
372
445
 
373
446
  ## Configuration
374
447