@storecraft/database-sqlite 1.0.1 → 1.0.2

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/src/con.shared.js DELETED
@@ -1,616 +0,0 @@
1
- import { ExpressionWrapper, InsertQueryBuilder, Transaction } from 'kysely'
2
- import { jsonArrayFrom, stringArrayFrom } from './con.helpers.json.js'
3
- import { SQL } from '../index.js';
4
- import { query_to_eb } from './utils.query.js';
5
-
6
-
7
- /**
8
- * @param {SQL} driver
9
- * @param {keyof Database} table_name
10
- *
11
- * @returns {import('@storecraft/core/v-database').db_crud["count"]}
12
- */
13
- export const count_regular = (driver, table_name) => {
14
- return async (query) => {
15
-
16
- const result = await driver.client
17
- .selectFrom(table_name)
18
- .select(
19
- (eb) => eb.fn.countAll().as('count')
20
- )
21
- .where(
22
- (eb) => {
23
- return query_to_eb(eb, query, table_name);
24
- }
25
- )
26
- .executeTakeFirst();
27
-
28
- return Number(result.count);
29
- }
30
- }
31
-
32
- /**
33
- *
34
- * @param {string} id_or_handle
35
- */
36
- export const where_id_or_handle_entity = (id_or_handle) => {
37
- /**
38
- * @param {import('kysely').ExpressionBuilder<Database>} eb
39
- */
40
- return (eb) => eb.or(
41
- [
42
- eb('entity_handle', '=', id_or_handle),
43
- eb('entity_id', '=', id_or_handle),
44
- ]
45
- );
46
- }
47
-
48
- /**
49
- *
50
- * @param {string} id_or_handle
51
- */
52
- export const where_id_or_handle_table = (id_or_handle) => {
53
- /**
54
- * @param {import('kysely').ExpressionBuilder<Database>} eb
55
- */
56
- return (eb) => eb.or(
57
- [
58
- eb('id', '=', id_or_handle),
59
- eb('handle', '=', id_or_handle),
60
- ]
61
- );
62
- }
63
-
64
- /**
65
- * @typedef { keyof Pick<Database,
66
- * 'entity_to_media' | 'entity_to_search_terms'
67
- * | 'entity_to_tags_projections' | 'products_to_collections'
68
- * | 'products_to_discounts' | 'products_to_variants'
69
- * | 'products_to_related_products' | 'storefronts_to_other'>
70
- * } EntityTableKeys
71
- */
72
-
73
- /**
74
- * helper to generate entity values delete
75
- *
76
- * @param {EntityTableKeys} entity_table_name
77
- */
78
- export const delete_entity_values_by_value_or_reporter = (entity_table_name) => {
79
- /**
80
- *
81
- * @param {Transaction<Database>} trx
82
- * @param {string} value delete by entity value
83
- * @param {string} [reporter] delete by reporter
84
- */
85
- return (trx, value, reporter=undefined) => {
86
-
87
- return trx.deleteFrom(entity_table_name).where(
88
- eb => eb.or(
89
- [
90
- value && eb('value', '=', value),
91
- reporter && eb('reporter', '=', reporter),
92
- ].filter(Boolean)
93
- )
94
- ).executeTakeFirst();
95
- }
96
- }
97
-
98
- /**
99
- * helper to generate entity values delete
100
- *
101
- * @param {EntityTableKeys} entity_table_name
102
- */
103
- export const delete_entity_values_of_by_entity_id_or_handle =
104
- (entity_table_name) => {
105
- /**
106
- *
107
- * @param {Transaction<import('../index.js').Database>} trx
108
- * @param {string} entity_id delete by id
109
- * @param {string} [entity_handle=entity_id] delete by handle
110
- */
111
- return (trx, entity_id, entity_handle=undefined) => {
112
- return trx.deleteFrom(entity_table_name).where(
113
- eb => eb.or(
114
- [
115
- eb('entity_id', '=', entity_id),
116
- eb('entity_handle', '=', entity_handle ?? entity_id),
117
- ]
118
- )
119
- ).executeTakeFirst();
120
- }
121
- }
122
-
123
- /**
124
- * helper to generate entity values for simple tables
125
- * @param {EntityTableKeys} entity_table_name
126
- */
127
- export const insert_entity_array_values_of = (entity_table_name) => {
128
- /**
129
- *
130
- * @param {Transaction<Database>} trx
131
- * @param {string[]} values values of the entity
132
- * @param {string} item_id whom the tags belong to
133
- * @param {string} [item_handle] whom the tags belong to
134
- * @param {boolean} [delete_previous=true] if true and `reporter`,
135
- * then will delete by reporter, otherwise by `item_id/item_handle`
136
- * @param {string} [reporter=undefined] the reporter of the batch values
137
- * (another segment technique)
138
- * @param {string} [context=undefined] the context (another segment technique)
139
- */
140
- return async (trx, values, item_id, item_handle, delete_previous=true,
141
- reporter=undefined, context=undefined) => {
142
-
143
- if(delete_previous) {
144
- if(reporter) {
145
- await delete_entity_values_by_value_or_reporter(entity_table_name)(
146
- trx, undefined, reporter
147
- );
148
- } else {
149
- await delete_entity_values_of_by_entity_id_or_handle(entity_table_name)(
150
- trx, item_id, item_handle
151
- );
152
- }
153
- }
154
-
155
- if(!values?.length) return Promise.resolve();
156
-
157
- return await trx.insertInto(entity_table_name).values(
158
- values.map(t => ({
159
- entity_handle: item_handle,
160
- entity_id: item_id,
161
- value: t,
162
- reporter,
163
- context
164
- })
165
- )
166
- ).executeTakeFirst();
167
- }
168
- }
169
-
170
- /**
171
- * helper to generate entity values delete
172
- *
173
- * @param {EntityTableKeys} entity_table_name
174
- */
175
- export const insert_entity_values_of = (entity_table_name) => {
176
- /**
177
- *
178
- * @param {Transaction<Database>} trx
179
- * @param {{value: string, reporter: string}[]} values values of the entity
180
- * @param {string} item_id whom the tags belong to
181
- * @param {string} [item_handle] whom the tags belong to
182
- * @param {string} [context=undefined] the context (another segment technique)
183
- */
184
- return async (trx, values, item_id, item_handle, context=undefined) => {
185
-
186
- if(!values?.length) return Promise.resolve();
187
-
188
- return await trx.insertInto(entity_table_name).values(
189
- values.map(t => ({
190
- entity_id: item_id,
191
- entity_handle: item_handle,
192
- value: t.value,
193
- reporter: t.reporter,
194
- context
195
- })
196
- )
197
- ).executeTakeFirst();
198
- }
199
- }
200
-
201
-
202
- /**
203
- * Delete previous entities by `id/handle` and insert new ones
204
- *
205
- * @param {EntityTableKeys} entity_table
206
- */
207
- export const insert_entity_array_values_with_delete_of = (entity_table) => {
208
- /**
209
- * @param {Transaction<Database>} trx
210
- * @param {string[]} values values of the entity
211
- * @param {string} item_id entity id
212
- * @param {string} [item_handle] entity handle
213
- * @param {string} [context] context
214
- */
215
- return (trx, values, item_id, item_handle, context) => {
216
- return insert_entity_array_values_of(entity_table)(
217
- trx, values, item_id, item_handle, true, undefined, context
218
- )
219
- };
220
- }
221
-
222
- export const insert_tags_of = insert_entity_array_values_with_delete_of('entity_to_tags_projections');
223
- export const insert_search_of = insert_entity_array_values_with_delete_of('entity_to_search_terms');
224
- export const insert_media_of = insert_entity_array_values_with_delete_of('entity_to_media');
225
-
226
- export const delete_tags_of = delete_entity_values_of_by_entity_id_or_handle('entity_to_tags_projections');
227
- export const delete_search_of = delete_entity_values_of_by_entity_id_or_handle('entity_to_search_terms');
228
- export const delete_media_of = delete_entity_values_of_by_entity_id_or_handle('entity_to_media');
229
-
230
- /**
231
- * @typedef {import('../index.js').Database} Database
232
- */
233
-
234
-
235
- /**
236
- * @template {keyof Database} T
237
- *
238
- * @param {Transaction<Database>} trx
239
- * @param {T} table_name
240
- * @param {import('kysely').InsertObject<Database, T>} item values of the entity
241
- *
242
- */
243
- export const regular_upsert_me = async (trx, table_name, item) => {
244
-
245
- // TODO: maybe use only `id`
246
- await trx.deleteFrom(table_name).where(
247
- eb => eb.or(
248
- [
249
- item.id && eb('id', '=', item.id),
250
- item.handle && eb('handle', '=', item.handle),
251
- ].filter(Boolean)
252
- )
253
- ).execute();
254
-
255
- return await trx.insertInto(table_name).values(item).executeTakeFirst()
256
- }
257
-
258
-
259
- /**
260
- *
261
- * @param {Transaction<Database>} trx
262
- * @param {keyof Database} table_name
263
- * @param {string} id_or_handle
264
- */
265
- export const delete_me = async (trx, table_name, id_or_handle) => {
266
- // console.log('delete ', id_or_handle)
267
- return await trx.deleteFrom(table_name).where(
268
- where_id_or_handle_table(id_or_handle)
269
- ).executeTakeFirst();
270
- }
271
-
272
- /**
273
- *
274
- * @param {import('kysely').ExpressionBuilder<Database>} eb
275
- * @param {string | ExpressionWrapper<Database>} id_or_handle
276
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
277
- */
278
- export const with_tags = (eb, id_or_handle, sql_type) => {
279
- return stringArrayFrom(
280
- select_values_of_entity_by_entity_id_or_handle(
281
- eb, 'entity_to_tags_projections', id_or_handle
282
- ), sql_type
283
- ).as('tags');
284
- }
285
-
286
- /**
287
- *
288
- * @param {import('kysely').ExpressionBuilder<Database>} eb
289
- * @param {string | ExpressionWrapper<Database>} id_or_handle
290
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
291
- */
292
- export const with_search = (eb, id_or_handle, sql_type) => {
293
- return stringArrayFrom(
294
- select_values_of_entity_by_entity_id_or_handle(
295
- eb, 'entity_to_search_terms', id_or_handle
296
- ), sql_type
297
- ).as('search');
298
- }
299
-
300
- /**
301
- *
302
- * @param {import('kysely').ExpressionBuilder<Database>} eb
303
- * @param {string | ExpressionWrapper<Database>} id_or_handle
304
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
305
- */
306
- export const with_media = (eb, id_or_handle, sql_type) => {
307
- return stringArrayFrom(
308
- select_values_of_entity_by_entity_id_or_handle(
309
- eb, 'entity_to_media', id_or_handle
310
- ), sql_type
311
- ).as('media');
312
- }
313
-
314
- /**
315
- * helper to select base attributes
316
- * @param {import('kysely').ExpressionBuilder<Database>} eb
317
- * @param {keyof Database} table
318
- * @return {import('kysely').SelectQueryBuilder<Database, table>}
319
- */
320
- const select_base_from = (eb, table) => {
321
- return [
322
- 'active', 'attributes', 'created_at', 'updated_at',
323
- 'description', 'handle', 'id'
324
- ].map(k => `${table}.${k}`).reduce(
325
- (p, c) => p.select(c), eb.selectFrom(table)
326
- );
327
- }
328
-
329
- /**
330
- * select as json array collections of a product
331
- *
332
- * @param {import('kysely').ExpressionBuilder<Database, 'products'>} eb
333
- * @param {string | ExpressionWrapper<Database>} product_id_or_handle
334
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
335
- */
336
- export const products_with_collections = (eb, product_id_or_handle, sql_type) => {
337
- return jsonArrayFrom(
338
- select_base_from(eb, 'collections')
339
- .select('collections.title')
340
- .select('collections.published')
341
- .select(eb => [
342
- with_tags(eb, eb.ref('collections.id'), sql_type),
343
- with_media(eb, eb.ref('collections.id'), sql_type),
344
- ])
345
- .where('collections.id', 'in',
346
- eb => select_values_of_entity_by_entity_id_or_handle(
347
- eb, 'products_to_collections', product_id_or_handle
348
- )
349
- ), sql_type
350
- ).as('collections');
351
- }
352
-
353
- /**
354
- * select as json array collections of a product
355
- *
356
- * @param {import('kysely').ExpressionBuilder<Database, 'products'>} eb
357
- * @param {string | ExpressionWrapper<Database>} product_id_or_handle
358
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
359
- */
360
- export const products_with_discounts = (eb, product_id_or_handle, sql_type) => {
361
- return jsonArrayFrom(
362
- select_base_from(eb, 'discounts')
363
- .select('discounts.title')
364
- .select('discounts.published')
365
- .select('discounts.application')
366
- .select('discounts.info')
367
- .select('discounts.priority')
368
- .select(eb => [
369
- with_tags(eb, eb.ref('discounts.id'), sql_type),
370
- with_media(eb, eb.ref('discounts.id'), sql_type),
371
- ])
372
- .where('discounts.id', 'in',
373
- eb => select_values_of_entity_by_entity_id_or_handle(
374
- eb, 'products_to_discounts', product_id_or_handle
375
- )
376
- ), sql_type
377
- ).as('discounts');
378
- }
379
-
380
- /**
381
- * select as json array collections of a product
382
- *
383
- * @param {import('kysely').ExpressionBuilder<Database, 'products'>} eb
384
- * @param {string | ExpressionWrapper<Database>} product_id_or_handle
385
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
386
- */
387
- export const products_with_variants = (eb, product_id_or_handle, sql_type) => {
388
- return jsonArrayFrom(
389
- select_base_from(eb, 'products')
390
- .select('products.compare_at_price')
391
- .select('products.parent_handle')
392
- .select('products.parent_id')
393
- .select('products.price')
394
- .select('products.qty')
395
- .select('products.title')
396
- .select('products.variant_hint')
397
- .select('products.variants_options')
398
- .select('products.video')
399
- .select(eb => [
400
- with_tags(eb, eb.ref('products.id'), sql_type),
401
- with_media(eb, eb.ref('products.id'), sql_type),
402
- ])
403
- .where('products.id', 'in',
404
- eb => select_values_of_entity_by_entity_id_or_handle(
405
- eb, 'products_to_variants', product_id_or_handle
406
- )
407
- ), sql_type
408
- ).as('variants');
409
- }
410
-
411
- /**
412
- * select as json array collections of a product
413
- *
414
- * @param {import('kysely').ExpressionBuilder<Database, 'products'>} eb
415
- * @param {string | ExpressionWrapper<Database>} product_id_or_handle
416
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
417
- */
418
- export const products_with_related_products = (eb, product_id_or_handle, sql_type) => {
419
- return jsonArrayFrom(
420
- select_base_from(eb, 'products')
421
- .select('products.compare_at_price')
422
- .select('products.parent_handle')
423
- .select('products.parent_id')
424
- .select('products.price')
425
- .select('products.qty')
426
- .select('products.title')
427
- .select('products.variant_hint')
428
- .select('products.variants_options')
429
- .select('products.video')
430
- .select(eb => [
431
- with_tags(eb, eb.ref('products.id'), sql_type),
432
- with_media(eb, eb.ref('products.id'), sql_type),
433
- ])
434
- .where('products.id', 'in',
435
- eb => select_values_of_entity_by_entity_id_or_handle(
436
- eb, 'products_to_related_products', product_id_or_handle
437
- )
438
- ), sql_type
439
- ).as('related_products');
440
- }
441
-
442
-
443
- /**
444
- * select as json array collections of a product
445
- *
446
- * @param {import('kysely').ExpressionBuilder<Database, 'storefronts'>} eb
447
- * @param {string | ExpressionWrapper<Database>} sf_id_or_handle
448
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
449
- */
450
- export const storefront_with_collections = (eb, sf_id_or_handle, sql_type) => {
451
- return jsonArrayFrom(
452
- select_base_from(eb, 'collections')
453
- .select('collections.title')
454
- .select('collections.published')
455
- .select(eb => [
456
- with_tags(eb, eb.ref('collections.id'), sql_type),
457
- with_media(eb, eb.ref('collections.id'), sql_type),
458
- ])
459
- .where('collections.id', 'in',
460
- eb => select_values_of_entity_by_entity_id_or_handle(
461
- eb, 'storefronts_to_other', sf_id_or_handle
462
- )
463
- ), sql_type
464
- ).as('collections');
465
- }
466
-
467
- /**
468
- * select as json array collections of a product
469
- *
470
- * @param {import('kysely').ExpressionBuilder<Database>} eb
471
- * @param {string | ExpressionWrapper<Database>} sf_id_or_handle
472
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
473
- */
474
- export const storefront_with_products = (eb, sf_id_or_handle, sql_type) => {
475
- return jsonArrayFrom(
476
- select_base_from(eb, 'products')
477
- .select('products.title')
478
- .select('products.compare_at_price')
479
- .select('products.parent_handle')
480
- .select('products.parent_id')
481
- .select('products.price')
482
- .select('products.qty')
483
- .select('products.variant_hint')
484
- .select('products.variants_options')
485
- .select('products.video')
486
- .select(eb => [
487
- with_tags(eb, eb.ref('products.id'), sql_type),
488
- with_media(eb, eb.ref('products.id'), sql_type),
489
- ])
490
- .where('products.id', 'in',
491
- eb => select_values_of_entity_by_entity_id_or_handle(
492
- eb, 'storefronts_to_other', sf_id_or_handle
493
- )
494
- ), sql_type
495
- ).as('products');
496
- }
497
-
498
- /**
499
- * select as json array collections of a product
500
- *
501
- * @param {import('kysely').ExpressionBuilder<Database>} eb
502
- * @param {string | ExpressionWrapper<Database>} sf_id_or_handle
503
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
504
- */
505
- export const storefront_with_discounts = (eb, sf_id_or_handle, sql_type) => {
506
- return jsonArrayFrom(
507
- select_base_from(eb, 'discounts')
508
- .select('discounts.application')
509
- .select('discounts.info')
510
- .select('discounts.priority')
511
- .select('discounts.published')
512
- .select('discounts.title')
513
- .select(eb => [
514
- with_tags(eb, eb.ref('discounts.id'), sql_type),
515
- with_media(eb, eb.ref('discounts.id'), sql_type),
516
- ])
517
- .where('discounts.id', 'in',
518
- eb => select_values_of_entity_by_entity_id_or_handle(
519
- eb, 'storefronts_to_other', sf_id_or_handle
520
- )
521
- ), sql_type
522
- ).as('discounts');
523
- }
524
-
525
- /**
526
- * select as json array collections of a product
527
- *
528
- * @param {import('kysely').ExpressionBuilder<Database>} eb
529
- * @param {string | ExpressionWrapper<Database>} sf_id_or_handle
530
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
531
- */
532
- export const storefront_with_posts = (eb, sf_id_or_handle, sql_type) => {
533
- return jsonArrayFrom(
534
- select_base_from(eb, 'posts')
535
- .select('posts.text')
536
- .select('posts.title')
537
- .select(eb => [
538
- with_tags(eb, eb.ref('posts.id'), sql_type),
539
- with_media(eb, eb.ref('posts.id'), sql_type),
540
- ])
541
- .where('posts.id', 'in',
542
- eb => select_values_of_entity_by_entity_id_or_handle(
543
- eb, 'storefronts_to_other', sf_id_or_handle
544
- )
545
- ), sql_type
546
- ).as('posts');
547
- }
548
-
549
- /**
550
- * select as json array collections of a product
551
- *
552
- * @param {import('kysely').ExpressionBuilder<Database>} eb
553
- * @param {string | ExpressionWrapper<Database>} sf_id_or_handle
554
- * @param {import('../types.public.d.ts').SqlDialectType} sql_type
555
- */
556
- export const storefront_with_shipping = (eb, sf_id_or_handle, sql_type) => {
557
- return jsonArrayFrom(
558
- select_base_from(eb, 'shipping_methods')
559
- .select('shipping_methods.price')
560
- .select('shipping_methods.title')
561
- .select(eb => [
562
- with_tags(eb, eb.ref('shipping_methods.id'), sql_type),
563
- with_media(eb, eb.ref('shipping_methods.id'), sql_type),
564
- ])
565
- .where('shipping_methods.id', 'in',
566
- eb => select_values_of_entity_by_entity_id_or_handle(
567
- eb, 'storefronts_to_other', sf_id_or_handle
568
- )
569
- ), sql_type
570
- ).as('shipping_methods');
571
- }
572
-
573
- /**
574
- * select all the entity values by entity id or handle
575
- *
576
- * @param {import('kysely').ExpressionBuilder<Database>} eb
577
- * @param {EntityTableKeys} entity_junction_table
578
- * @param {string | ExpressionWrapper<Database>} entity_id_or_handle
579
- */
580
- export const select_values_of_entity_by_entity_id_or_handle =
581
- (eb, entity_junction_table, entity_id_or_handle) => {
582
- return eb
583
- .selectFrom(entity_junction_table)
584
- .select(`${entity_junction_table}.value`)
585
- .where(eb2 => eb2.or(
586
- [
587
- eb2(`${entity_junction_table}.entity_id`, '=', entity_id_or_handle),
588
- eb2(`${entity_junction_table}.entity_handle`, '=', entity_id_or_handle),
589
- ]
590
- )
591
- )
592
- .orderBy(`${entity_junction_table}.id`);
593
- }
594
-
595
- /**
596
- * select the entity ids which are constrained by value or reporter
597
- *
598
- * @param {import('kysely').ExpressionBuilder<Database>} eb
599
- * @param {EntityTableKeys} entity_junction_table
600
- * @param {string | ExpressionWrapper<Database>} value
601
- * @param {string | ExpressionWrapper<Database>} [reporter]
602
- */
603
- export const select_entity_ids_by_value_or_reporter =
604
- (eb, entity_junction_table, value, reporter=undefined) => {
605
- return eb
606
- .selectFrom(entity_junction_table)
607
- .select(`${entity_junction_table}.entity_id`)
608
- .where(eb2 => eb2.or(
609
- [
610
- eb2(`${entity_junction_table}.value`, '=', value ?? reporter),
611
- eb2(`${entity_junction_table}.reporter`, '=', reporter ?? value),
612
- ]
613
- )
614
- )
615
- .orderBy(`${entity_junction_table}.entity_id`);
616
- }