@xuda.io/xuda-dbs-plugin-xuda 1.0.1

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 (3) hide show
  1. package/index.mjs +1025 -0
  2. package/package.json +17 -0
  3. package/setup.mjs +39 -0
package/index.mjs ADDED
@@ -0,0 +1,1025 @@
1
+ const check_unique = async function (docP, table_obj) {
2
+ var len = docP.udfIndex.length;
3
+ if (!len) {
4
+ return { code: -11, data: "table must have primary index" };
5
+ }
6
+ var found_unique;
7
+ var ret = { code: 1, data: "ok" };
8
+
9
+ for await (var val of docP.udfIndex) {
10
+ if (!table_obj.tableIndexes) {
11
+ ret = {
12
+ code: -14,
13
+ data: "table definition missing for: " + val.fileId,
14
+ };
15
+ break;
16
+ }
17
+
18
+ const table_index = find_item_by_key_root(
19
+ table_obj.tableIndexes,
20
+ "id",
21
+ val.indexId
22
+ );
23
+
24
+ if (!table_index) {
25
+ ret = {
26
+ code: -13,
27
+ data: "keys definition missing for Table: " + val.fileId,
28
+ };
29
+ break;
30
+ }
31
+
32
+ if (!table_index.data.unique) {
33
+ continue;
34
+ }
35
+ if (!table_index?.data?.keys || _.isEmpty(table_index.data.keys)) {
36
+ ret = {
37
+ code: -14,
38
+ data: "keys definition missing for index: " + val.indexId,
39
+ };
40
+ break;
41
+ }
42
+
43
+ var keysArr = table_index.data.keys;
44
+ var keyValue = [];
45
+
46
+ for await (const [keySegment, valSegment] of Object.entries(keysArr)) {
47
+ // run on key segment
48
+ let _fieldType = find_item_by_key(
49
+ table_obj.tableFields,
50
+ "field_id",
51
+ valSegment
52
+ ).props.fieldType;
53
+ let _val = await get_cast_val(
54
+ "check_unique",
55
+ valSegment,
56
+ _fieldType,
57
+ val.keyValue[keySegment]
58
+ );
59
+ keyValue.push(_val);
60
+ }
61
+
62
+ var key =
63
+ '["' +
64
+ val.fileId +
65
+ '","' +
66
+ val.indexId +
67
+ '",[' +
68
+ keyValue.join(",") +
69
+ "]]";
70
+ try {
71
+ const json = await _this.runtime_xuda_driver("runtime_get_index", e);
72
+
73
+ // var data;
74
+
75
+ if (json.code > 0) {
76
+ var data = json.data;
77
+ if (data?.rows?.length) {
78
+ for await (var val of data.rows) {
79
+ if (val.id !== docP._id) {
80
+ found_unique = true;
81
+ }
82
+ }
83
+ if (found_unique) {
84
+ throw "error checking unique:" + key;
85
+ }
86
+ }
87
+ }
88
+ // throw json.data;
89
+ return { code: 1, data: "ok" };
90
+ } catch (msg) {
91
+ console.error(msg);
92
+ ret = { code: -22, data: msg };
93
+ break;
94
+ }
95
+ }
96
+
97
+ return ret;
98
+ };
99
+
100
+ const get_index_json = async function (docInP, table_obj) {
101
+ try {
102
+ var keysArr = [];
103
+ var index_json = [];
104
+ var key_val = [];
105
+
106
+ if (docInP.udfData && table_obj) {
107
+ // check for udf data array
108
+ if (table_obj.tableIndexes) {
109
+ // console.log(udfDicIndexT.rows);
110
+ for await (var valIndex of table_obj.tableIndexes) {
111
+ // run on index rows
112
+ keysArr = valIndex.data.keys; // create array from keys string segment
113
+ key_val = [];
114
+ for await (var valSegment of keysArr) {
115
+ // run on key segment
116
+ // find keys values
117
+ if (docInP.udfData.data[valSegment]) {
118
+ key_val.push(docInP.udfData.data[valSegment]);
119
+ continue;
120
+ }
121
+ // put the value
122
+ // debugger;
123
+ const field_obj = find_item_by_key(
124
+ table_obj.tableFields,
125
+ "field_id",
126
+ valSegment
127
+ );
128
+ if (!field_obj) {
129
+ throw "field not found in key: " + valSegment;
130
+ }
131
+
132
+ let _val = await get_cast_val(
133
+ "get_index_json",
134
+ field_obj.id,
135
+ field_obj.props.fieldType,
136
+ null
137
+ );
138
+ key_val.push(_val);
139
+ }
140
+
141
+ index_json.push({
142
+ fileId: docInP.udfData.udffileid,
143
+ indexId: valIndex.id,
144
+ keySegments: keysArr,
145
+ keyValue: key_val,
146
+ });
147
+ }
148
+ // );
149
+ }
150
+ }
151
+ return { code: 1, data: index_json };
152
+ } catch (msg) {
153
+ return { code: -1, data: msg };
154
+ }
155
+ };
156
+
157
+ export const Create = async (e, db, table_obj) => {
158
+ const batch = async function () {
159
+ var docs = [];
160
+ try {
161
+ for await (var val of e.table_data) {
162
+ var doc = {
163
+ docType: "database",
164
+
165
+ user: e.uid,
166
+ stat: 3,
167
+ udfData: {
168
+ udffileid: e.table_id,
169
+ data: val,
170
+ error: {},
171
+ },
172
+
173
+ ts: new Date().valueOf(),
174
+ date: new Date().valueOf(),
175
+ };
176
+ const index_ret = await get_index_json(doc, table_obj);
177
+ if (index_ret < 0) throw index_ret.data;
178
+ doc.udfIndex = index_ret.data;
179
+
180
+ const ret = await check_unique(doc, table_obj);
181
+ if (ret.code < 0) {
182
+ throw ret;
183
+ }
184
+ docs.push(doc);
185
+ }
186
+ try {
187
+ const body = await db.bulk({ docs: docs });
188
+ return { code: 110, data: body };
189
+ } catch (error) {
190
+ return { code: -400, data: error };
191
+ }
192
+ } catch (msg) {
193
+ return { code: -400, data: msg };
194
+ }
195
+ };
196
+ const single = async function () {
197
+ var doc = {
198
+ docType: "database",
199
+
200
+ user: e.uid,
201
+ stat: 3,
202
+ udfData: {
203
+ udffileid: e.table_id,
204
+ data: e.table_data,
205
+ error: {},
206
+ },
207
+
208
+ ts: new Date().valueOf(),
209
+ date: new Date().valueOf(),
210
+ };
211
+ const index_ret = await get_index_json(doc, table_obj);
212
+ if (index_ret.code < 0) {
213
+ return index_ret;
214
+ }
215
+ doc.udfIndex = index_ret.data;
216
+ const ret = await check_unique(doc, table_obj);
217
+ if (ret.code < 0) {
218
+ return ret;
219
+ }
220
+ try {
221
+ const body = await db.insert(doc);
222
+ return { code: 110, data: body };
223
+ } catch (error) {
224
+ return { code: -400, data: error };
225
+ }
226
+ };
227
+ if (Array.isArray(e.table_data)) {
228
+ return await batch();
229
+ }
230
+ return await single();
231
+ };
232
+ export const Read = async (e, db, table_obj) => {
233
+ var key;
234
+
235
+ const runtime_get_mango_data = async function () {
236
+ const done = async function (body) {
237
+ const raw_data = async function () {
238
+ var rows = [];
239
+
240
+ for await (var val of body.docs) {
241
+ var data = {};
242
+ if (e.fields) {
243
+ for await (const [key2, val2] of Object.entries(
244
+ typeof e.fields === "string" ? e.fields.split(",") : e.fields
245
+ )) {
246
+ if (val.udfData) {
247
+ data[val2] = val["udfData"]["data"][val2];
248
+ } else {
249
+ data[val2] = null;
250
+ }
251
+ }
252
+ } else {
253
+ for await (const [key2, val2] of Object.entries(
254
+ table_obj.tableFields
255
+ )) {
256
+ if (val.udfData) {
257
+ data[val2.data.field_id] =
258
+ val["udfData"]["data"][val2.data.field_id];
259
+ } else {
260
+ data[val2.data.field_id] = null;
261
+ }
262
+ }
263
+ }
264
+
265
+ rows.push({
266
+ id: val._id,
267
+ value: {
268
+ udfData: { data: data },
269
+ _id: val._id,
270
+ _rev: val._rev,
271
+ },
272
+ });
273
+ }
274
+
275
+ return {
276
+ code: 443,
277
+ data: { rows: rows, total_rows: rows.length },
278
+ };
279
+ };
280
+ const count_data = async function () {
281
+ var rows = [];
282
+ var keys_obj = {};
283
+ const table_index = find_item_by_key_root(
284
+ table_obj.tableIndexes,
285
+ "id",
286
+ e.indexId
287
+ );
288
+ if (e.indexId && table_index) {
289
+ var index_keys = table_index.data.keys;
290
+ var index_id = e.indexId;
291
+
292
+ for await (var val of body.docs) {
293
+ var data = {};
294
+ const _tableFieldsObj = find_item_by_key(
295
+ table_obj.tableFields,
296
+ "field_id",
297
+ e.field_id
298
+ );
299
+
300
+ for await (const [key2, val2] of Object.entries(
301
+ table_obj.tableFields
302
+ )) {
303
+ data[val2.data.field_id] =
304
+ val["udfData"]["data"][val2.data.field_id];
305
+ }
306
+
307
+ var key_arr = [];
308
+
309
+ for await (const [key_idx, key_name] of Object.entries(
310
+ index_keys
311
+ )) {
312
+ key_arr.push(data[key_name]);
313
+ }
314
+ keys_obj[key_arr]++;
315
+ }
316
+
317
+ for await (const [key_arr, key_count] of Object.entries(keys_obj)) {
318
+ rows.push({
319
+ key: [e.key, index_id, key_arr],
320
+ value: body.docs.length,
321
+ });
322
+ }
323
+ } else {
324
+ // no index
325
+ rows.push({ key: "", value: body.docs.length });
326
+ }
327
+ return {
328
+ code: 443,
329
+ data: { rows: rows, total_rows: rows.length },
330
+ };
331
+ };
332
+
333
+ const totals = async function () {
334
+ const median = (arr) => {
335
+ const mid = Math.floor(arr.length / 2),
336
+ nums = [...arr].sort((a, b) => a - b);
337
+ return arr.length % 2 !== 0
338
+ ? nums[mid]
339
+ : (nums[mid - 1] + nums[mid]) / 2;
340
+ };
341
+
342
+ var total_fields_info = JSON.parse(e.total_fields_info);
343
+ var totals_prop = {};
344
+ var totals_obj = {};
345
+ var totals_counts = {};
346
+ var totals_arr = {};
347
+ var totals_sums = {};
348
+ var totals_group_obj = {};
349
+
350
+ for await (const [key, val] of Object.entries(total_fields_info)) {
351
+ totals_counts[val.field_id] = 0;
352
+ totals_prop[val.field_id] = val;
353
+ totals_arr[val.field_id] = [];
354
+ totals_sums[val.field_id] = 0;
355
+ totals_group_obj[val.field_id] = {};
356
+ }
357
+
358
+ for await (var row_data of body.docs) {
359
+ for await (const [key, val] of Object.entries(
360
+ row_data.udfData.data
361
+ )) {
362
+ var field_id = key;
363
+ var value = val;
364
+ totals_counts[field_id]++;
365
+
366
+ switch (totals_prop[field_id].sum_type) {
367
+ case "sum":
368
+ if (typeof totals_obj[field_id] === "undefined") {
369
+ totals_obj[field_id] = value;
370
+ } else {
371
+ totals_obj[field_id] += value;
372
+ }
373
+ break;
374
+
375
+ case "average":
376
+ totals_sums[field_id] += value;
377
+ totals_obj[field_id] =
378
+ totals_sums[field_id] / totals_counts[field_id];
379
+ break;
380
+
381
+ case "median":
382
+ if (!totals_arr[field_id].includes(value)) {
383
+ totals_arr[field_id].push(value);
384
+ }
385
+ totals_obj[field_id] = median(totals_arr[field_id]);
386
+ break;
387
+ case "min":
388
+ if (
389
+ typeof totals_obj[field_id] === "undefined" ||
390
+ value < totals_obj[field_id]
391
+ ) {
392
+ totals_obj[field_id] = value;
393
+ }
394
+ break;
395
+ case "max":
396
+ if (
397
+ typeof totals_obj[field_id] === "undefined" ||
398
+ value > totals_obj[field_id]
399
+ ) {
400
+ totals_obj[field_id] = value;
401
+ }
402
+ break;
403
+ case "count":
404
+ if (typeof totals_obj[field_id] === "undefined") {
405
+ totals_obj[field_id] = 1;
406
+ } else {
407
+ totals_obj[field_id]++;
408
+ }
409
+ break;
410
+ case "distinct":
411
+ if (!totals_arr[field_id].includes(value)) {
412
+ totals_arr[field_id].push(value);
413
+ }
414
+ totals_obj[field_id] = totals_arr[field_id].length;
415
+ break;
416
+
417
+ case "group":
418
+ if (!totals_obj[field_id]) {
419
+ totals_obj[field_id] = {};
420
+ }
421
+
422
+ if (typeof totals_obj[field_id][value] === "undefined") {
423
+ totals_obj[field_id][value] = 1; //value;
424
+ } else {
425
+ totals_obj[field_id][value]++; //+= value;
426
+ }
427
+
428
+ break;
429
+ default:
430
+ totals_obj[field_id] = null;
431
+ }
432
+ }
433
+ }
434
+ return { code: 443, data: totals_obj };
435
+ };
436
+ if (e.count === "true" || e.count === true) {
437
+ return count_data();
438
+ }
439
+ if (e.total_fields_info) {
440
+ return totals();
441
+ }
442
+ return raw_data();
443
+ };
444
+
445
+ var limit = 99999;
446
+ var skip = 0;
447
+
448
+ if (e.limit) {
449
+ limit = parseInt(e.limit);
450
+ }
451
+
452
+ if (e.skip) {
453
+ skip = JSON.parse(e.skip);
454
+ }
455
+
456
+ var fields = [];
457
+ if (e.fields) {
458
+ for await (const [key, val] of Object.entries(
459
+ typeof e.fields === "string" ? e.fields.split(",") : e.fields
460
+ )) {
461
+ fields.push(val);
462
+ }
463
+ } else {
464
+ for await (const [key, val] of Object.entries(table_obj.tableFields)) {
465
+ fields.push(val.data.field_id);
466
+ }
467
+ }
468
+
469
+ var data = {};
470
+ var from = e.filter_from ? JSON.parse(e.filter_from) : {};
471
+ var to = e.filter_to ? JSON.parse(e.filter_to) : {};
472
+ var sort = [];
473
+ for await (const [key, val] of Object.entries(from)) {
474
+ var field_name = key;
475
+
476
+ sort.push(field_name);
477
+
478
+ if (val === to[key]) {
479
+ data[field_name] = val;
480
+ } else {
481
+ data[field_name] = { $gte: val };
482
+ }
483
+ }
484
+
485
+ for await (const [key, val] of Object.entries(to)) {
486
+ var field_name = key;
487
+
488
+ if (val !== from[key]) {
489
+ data[field_name]["$lte"] = val;
490
+ }
491
+ }
492
+
493
+ var selector = {};
494
+
495
+ if (from && !_.isEmpty(from)) {
496
+ selector = data;
497
+ }
498
+
499
+ var opt = {
500
+ selector: selector,
501
+ limit: limit,
502
+ skip: skip,
503
+ fields: fields,
504
+ };
505
+
506
+ if (sort.length) {
507
+ opt.sort = sort;
508
+ }
509
+
510
+ if (e.sort_fields && JSON.parse(e.sort_fields).length) {
511
+ opt.sort = JSON.parse(e.sort_fields);
512
+ for await (const [key, val] of Object.entries(opt.sort)) {
513
+ var field_name = val.colId;
514
+ opt.sort[key] = {
515
+ ["udfData.data." + field_name]: val.sort,
516
+ };
517
+ }
518
+ }
519
+
520
+ if (e.grid_filter_info) {
521
+ for await (const [key, val] of Object.entries(
522
+ JSON.parse(e.grid_filter_info)
523
+ )) {
524
+ var field_name = key;
525
+ var condition = "$and";
526
+ const make_selector = function (val) {
527
+ var value = "";
528
+ var operator = "";
529
+ var value_to = "";
530
+ var operator_to = "";
531
+
532
+ if (val.filterType === "date") {
533
+ var date = val.dateFrom.substr(0, 10);
534
+ switch (val.type) {
535
+ case "equals":
536
+ operator = "$regex";
537
+ value = `^${date}`;
538
+ break;
539
+
540
+ case "greaterThan":
541
+ operator = "$gt";
542
+ value = `${date}`;
543
+ break;
544
+
545
+ case "lessThan":
546
+ operator = "$lt";
547
+ value = `${date}`;
548
+ break;
549
+
550
+ case "blank":
551
+ operator = "$eq";
552
+ value = "";
553
+ break;
554
+
555
+ case "inRange":
556
+ operator = "$gte";
557
+ value = date;
558
+ operator_to = "$lte";
559
+ value_to = val.dateTo.substr(0, 10);
560
+ break;
561
+
562
+ case "notEqual":
563
+ operator = "$regex";
564
+ value = `^((?!${date}).)*$`;
565
+ break;
566
+
567
+ case "notBlank":
568
+ operator = "$ne";
569
+ value = "";
570
+ break;
571
+
572
+ default:
573
+ operator = "$regex";
574
+ value = `^${date}`;
575
+ }
576
+ }
577
+
578
+ if (val.filterType === "text") {
579
+ switch (val.type) {
580
+ case "contains":
581
+ operator = "$regex";
582
+ value = `${val.filter}`;
583
+ break;
584
+
585
+ case "notContains":
586
+ operator = "$regex";
587
+ value = `^((?!${val.filter}).)*$`;
588
+ break;
589
+
590
+ case "equals":
591
+ operator = "$eq";
592
+ value = `${val.filter}`;
593
+ break;
594
+
595
+ case "notEqual":
596
+ operator = "$ne";
597
+ value = `${val.filter}`;
598
+ break;
599
+
600
+ case "startsWith":
601
+ operator = "$regex";
602
+ value = `^${val.filter}`;
603
+ break;
604
+
605
+ case "endsWith":
606
+ operator = "$regex";
607
+ value = `${val.filter}$`;
608
+ break;
609
+
610
+ case "blank":
611
+ operator = "$eq";
612
+ value = "";
613
+ break;
614
+
615
+ case "notBlank":
616
+ operator = "$ne";
617
+ value = "";
618
+ break;
619
+
620
+ default:
621
+ value = "^" + val.filter;
622
+ }
623
+ }
624
+
625
+ if (val.filterType === "number") {
626
+ switch (val.type) {
627
+ case "equals":
628
+ operator = "$eq";
629
+ value = val.filter;
630
+ break;
631
+
632
+ case "notEqual":
633
+ operator = "$ne";
634
+ value = val.filter;
635
+ break;
636
+
637
+ case "lessThanOrEqual":
638
+ operator = "$lte";
639
+ value = val.filter;
640
+ break;
641
+
642
+ case "greaterThanOrEqual":
643
+ operator = "$gte";
644
+ value = val.filter;
645
+ break;
646
+
647
+ case "lessThan":
648
+ operator = "$lt";
649
+ value = val.filter;
650
+ break;
651
+
652
+ case "greaterThan":
653
+ operator = "$gt";
654
+ value = val.filter;
655
+ break;
656
+
657
+ case "blank":
658
+ operator = "$eq";
659
+ value = 0;
660
+ break;
661
+
662
+ case "notBlank":
663
+ operator = "$ne";
664
+ value = 0;
665
+ break;
666
+
667
+ case "inRange":
668
+ operator = "$gte";
669
+ value = val.filter;
670
+ operator_to = "$lte";
671
+ value_to = val.filterTo;
672
+ break;
673
+
674
+ default:
675
+ operator = "$eq";
676
+ value = val.filter;
677
+ }
678
+ }
679
+ if (!opt.selector[field_name]) {
680
+ opt.selector[field_name] = {};
681
+ }
682
+ if (!opt.selector[field_name][condition]) {
683
+ opt.selector[field_name][condition] = [];
684
+ }
685
+ opt.selector[field_name][condition].push({
686
+ [operator]: value,
687
+ });
688
+
689
+ if (operator_to) {
690
+ opt.selector[field_name][condition].push({
691
+ [operator_to]: value_to,
692
+ });
693
+ }
694
+ };
695
+
696
+ if (!val.condition1) {
697
+ make_selector(val);
698
+ } else {
699
+ condition = "$" + val.operator.toLowerCase();
700
+ make_selector(val.condition1);
701
+ make_selector(val.condition2);
702
+ }
703
+ }
704
+ }
705
+
706
+ if (e.total_fields_info) {
707
+ fields = [];
708
+ for await (const [key, val] of Object.entries(
709
+ JSON.parse(e.total_fields_info)
710
+ )) {
711
+ var field_name = val.field_id;
712
+
713
+ fields.push(field_name);
714
+ }
715
+ opt.fields = fields;
716
+ }
717
+ // fix names
718
+
719
+ for await (const [key, val] of Object.entries(opt.fields)) {
720
+ opt.fields[key] = "udfData.data." + val;
721
+ }
722
+ if (!e.sort_fields || !JSON.parse(e.sort_fields).length) {
723
+ // added 2021 09 10
724
+
725
+ for await (const [key, val] of Object.entries(opt.sort)) {
726
+ opt.sort[key] = {
727
+ ["udfData.data." + val]: e.sortOrder === "des" ? "desc" : "asc",
728
+ };
729
+ }
730
+ }
731
+
732
+ var selector_new = {};
733
+
734
+ for await (const [key, val] of Object.entries(opt.selector)) {
735
+ selector_new["udfData.data." + key] = val;
736
+ }
737
+
738
+ if (e.viewDbQuery) {
739
+ for await (const [key, val] of Object.entries(table_obj.tableFields)) {
740
+ if (e.viewDbQuery.includes(val.id)) {
741
+ const replacer = new RegExp(val.id, "g");
742
+ e.viewDbQuery = e.viewDbQuery.replace(
743
+ replacer,
744
+ "udfData.data." + val.data.field_id
745
+ );
746
+ }
747
+ }
748
+
749
+ let viewDbQuery = JSON.parse(e.viewDbQuery.replace(/\\/g, ""));
750
+
751
+ for await (const [key, val] of Object.entries(viewDbQuery)) {
752
+ selector_new[key] = val;
753
+ }
754
+ }
755
+
756
+ opt.selector = selector_new;
757
+ opt.selector["udfData.udffileid"] = e.fileId;
758
+ opt.selector.stat = e.archived ? 4 : 3;
759
+
760
+ opt.fields.push("_id");
761
+ opt.fields.push("_rev");
762
+
763
+ // xuda
764
+ var cache_string = JSON.stringify(opt);
765
+ const app_id_reference = await _this.get_app_id(e.app_id);
766
+ if (
767
+ // __.CACHE_QUERY_REQ[app_id_reference] &&
768
+ // __.CACHE_QUERY_REQ[app_id_reference][e.table_id] &&
769
+ __.CACHE_QUERY_REQ?.[app_id_reference]?.[e.table_id]?.[cache_string]
770
+ ) {
771
+ return await done(
772
+ __.CACHE_QUERY_REQ[app_id_reference][e.table_id][cache_string].doc
773
+ );
774
+ }
775
+ try {
776
+ try {
777
+ const doc = await db.find(opt);
778
+ if (!__.CACHE_QUERY_REQ[app_id_reference]) {
779
+ __.CACHE_QUERY_REQ[app_id_reference] = {};
780
+ }
781
+
782
+ if (!__.CACHE_QUERY_REQ[app_id_reference][e.table_id]) {
783
+ __.CACHE_QUERY_REQ[app_id_reference][e.table_id] = {};
784
+ }
785
+
786
+ __.CACHE_QUERY_REQ[app_id_reference][e.table_id][cache_string] = {
787
+ doc: doc,
788
+ ts: Date.now(),
789
+ };
790
+
791
+ if (doc?.warning?.includes("No matching index found")) {
792
+ const index_name = `index_${e.table_id}_${new Date()
793
+ .valueOf()
794
+ .toString()}`;
795
+ var index = [];
796
+
797
+ for await (const [key, val] of Object.entries(opt.selector)) {
798
+ index.push(key);
799
+ }
800
+ mango_index_obj = {
801
+ index: {
802
+ fields: index,
803
+ },
804
+ name: index_name,
805
+ ddoc: `mango_index_table_${e.table_id}`,
806
+ };
807
+ db.createIndex(mango_index_obj).then((result) => {
808
+ console.log(result);
809
+ });
810
+ }
811
+ return await done(doc);
812
+ } catch (err) {
813
+ if (err.error === "no_usable_index") {
814
+ const index_name = `index_${e.table_id}_${new Date()
815
+ .valueOf()
816
+ .toString()}`;
817
+
818
+ mango_index_obj = {
819
+ index: {
820
+ fields: opt.sort,
821
+ },
822
+ name: index_name,
823
+ ddoc: `mango_index_table_${e.table_id}`,
824
+ };
825
+
826
+ try {
827
+ const result = await db.createIndex(mango_index_obj);
828
+ // try {
829
+ const doc = await db.find(opt);
830
+ return await done(doc);
831
+ // } catch (err) {
832
+ // return { code: -443, data: err.message };
833
+ // }
834
+ } catch (error) {
835
+ return { code: -400, data: error };
836
+ }
837
+ } else {
838
+ return { code: -444, data: err.message };
839
+ }
840
+ }
841
+ } catch (err) {
842
+ return { code: -445, data: err.error };
843
+ }
844
+ };
845
+
846
+ const runtime_get_query_data = async function () {
847
+ var limit = 99999;
848
+ var skip = 0;
849
+
850
+ if (e.limit) {
851
+ limit = e.limitP;
852
+ }
853
+
854
+ if (e.skipP) {
855
+ skip = e.skipP;
856
+ }
857
+
858
+ var desc = e.desc === "true" ? true : false;
859
+
860
+ var opt;
861
+ if (key) {
862
+ opt = {
863
+ key: key,
864
+ include_docs: !e.ids && view !== "db_index_reduce",
865
+ limit: limit,
866
+ skip: skip,
867
+ };
868
+ } else {
869
+ if (e.reduce == "true") {
870
+ opt = {
871
+ startkey: e.startkey ? JSON.parse(e.startkey) : "",
872
+ endkey: e.endkey ? JSON.parse(e.endkey) : "",
873
+ include_docs: false,
874
+ reduce: true,
875
+ group_level: 3,
876
+
877
+ descending: desc,
878
+ };
879
+ } else {
880
+ opt = {
881
+ startkey: e.startkey ? JSON.parse(e.startkey) : "",
882
+ endkey: e.endkey ? JSON.parse(e.endkey) : "",
883
+ include_docs: !e.ids,
884
+ limit: limit,
885
+ skip: skip,
886
+ descending: desc,
887
+ };
888
+ }
889
+ }
890
+
891
+ try {
892
+ const body = db.view(`xuda`, view, opt);
893
+ if (e.reduce) {
894
+ return { code: 440, data: body };
895
+ }
896
+ var rows = [];
897
+
898
+ for await (var val of body.rows) {
899
+ if (e.ids) {
900
+ rows.push({ id: val.id, value: val.value._id });
901
+ return true;
902
+ }
903
+ rows.push({
904
+ id: val.id,
905
+ value: { udfData: val.doc.udfData, _id: val.id },
906
+ });
907
+ }
908
+ return {
909
+ code: 440,
910
+ data: { rows: rows, total_rows: rows.length },
911
+ };
912
+ } catch (error) {
913
+ return { code: -442, data: error };
914
+ }
915
+ };
916
+
917
+ if (e.reduce && JSON.parse(e.reduce)) {
918
+ view = "db_index_reduce";
919
+ return await runtime_get_query_data();
920
+ }
921
+ if (e.view === "db_index") {
922
+ key = e.key;
923
+ view = e.view;
924
+ return await runtime_get_query_data();
925
+ }
926
+ return await runtime_get_mango_data();
927
+ };
928
+ export const Update = async (e, db, table_obj) => {
929
+ try {
930
+ const doc = await db.get(e.row_id, {});
931
+ let data = doc.udfData.data;
932
+ var error;
933
+
934
+ const _tableFieldsObj = find_item_by_key(
935
+ table_obj.tableFields,
936
+ "field_id",
937
+ e.field_id
938
+ );
939
+ if (!_tableFieldsObj || _.isEmpty(_tableFieldsObj)) {
940
+ return {
941
+ code: -552,
942
+ data: "Error:" + e.field_id + " - field not found",
943
+ };
944
+ }
945
+
946
+ data[e.field_id] = await get_cast_val(
947
+ "runtime_update_data",
948
+ e.field_id,
949
+ _tableFieldsObj.props.fieldType,
950
+ e.field_value
951
+ );
952
+ if (error) {
953
+ return {
954
+ code: -554,
955
+ data: error,
956
+ };
957
+ }
958
+
959
+ doc.ts = Date.now();
960
+ const index_ret = await get_index_json(doc, table_obj);
961
+ if (index_ret.code < 0) {
962
+ return index_ret;
963
+ }
964
+ doc.udfIndex = index_ret.data;
965
+ const ret = await check_unique(doc, table_obj);
966
+ if (ret.code < 0) {
967
+ return ret;
968
+ }
969
+ try {
970
+ const body = await db.insert(doc);
971
+ return { code: 460, data: body };
972
+ } catch (error) {
973
+ return { code: -460, data: error };
974
+ }
975
+ } catch (error) {
976
+ return { code: -550, data: error };
977
+ }
978
+ };
979
+ export const Delete = async (e, db, table_obj) => {
980
+ const data = await db.fetch({ keys: e.ids });
981
+ for await (var val of data.rows) {
982
+ var doc = val.doc;
983
+
984
+ if (doc && doc._id) {
985
+ if (e.permanent) {
986
+ docs_to_delete.push({
987
+ _id: doc._id,
988
+ _rev: doc._rev,
989
+ _deleted: true,
990
+ });
991
+ } else {
992
+ doc.stat = 4;
993
+ doc.ts = new Date().valueOf();
994
+ docs_to_delete.push(doc);
995
+ }
996
+ }
997
+ }
998
+ try {
999
+ await db.bulk({ docs: docs_to_delete });
1000
+ return { code: 110, data: docs_to_delete };
1001
+ } catch (error) {
1002
+ return { code: -110, data: error };
1003
+ }
1004
+ };
1005
+ export const Restore = async (e, db, table_obj) => {
1006
+ var docs_to_restore = [];
1007
+ const data = await db.fetch({ keys: e.ids });
1008
+
1009
+ for await (var val of data.rows) {
1010
+ var doc = val.doc;
1011
+
1012
+ if (doc && doc._id) {
1013
+ doc.stat = 3;
1014
+ doc.ts = new Date().valueOf();
1015
+ docs_to_restore.push(doc);
1016
+ }
1017
+ }
1018
+
1019
+ try {
1020
+ await db.bulk({ docs: docs_to_restore });
1021
+ return { code: 110, data: docs_to_restore };
1022
+ } catch (error) {
1023
+ return { code: -110, data: error };
1024
+ }
1025
+ };
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@xuda.io/xuda-dbs-plugin-xuda",
3
+ "version": "1.0.1",
4
+ "description": "Xuda Database Socket for Xuda's proprietary structure powered by CouchDB",
5
+ "scripts": {
6
+ "pub": "npm version patch --force && npm publish --access public"
7
+ },
8
+ "keywords": [
9
+ "dbs",
10
+ "socket",
11
+ "xuda",
12
+ "plugin"
13
+ ],
14
+ "author": "xuda.io",
15
+ "license": "Proprietary software licenses",
16
+ "svg_icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\" viewBox=\"0 0 256 256\" version=\"1.1\" preserveAspectRatio=\"xMidYMid\"> <g> <path d=\"M128.151659,0.00118559798 C148.92891,0.00118559798 168.492891,4.85546114 186.843602,14.2583047 L186.843602,14.2583047 L189.270142,15.4715749 L187.146919,17.1398213 C181.990521,21.2346081 177.895735,26.5426649 175.317536,32.6090156 L175.317536,32.6090156 L174.559242,34.2772621 L173.042654,33.5189682 C158.938389,26.8459825 143.924171,23.3578308 128.303318,23.3578308 C70.521327,23.3578308 23.6587678,70.3720488 23.6587678,128.002381 C23.6587678,185.632712 70.3696682,232.64693 128.151659,232.64693 C185.933649,232.64693 232.796209,185.632712 232.796209,128.002381 C232.796209,114.201433 230.218009,100.703802 224.758294,87.9644659 L224.758294,87.9644659 L224,86.2962194 L225.668246,85.5379256 C231.886256,83.2630441 237.345972,79.4715749 241.744076,74.6184943 L241.744076,74.6184943 L243.412322,72.4952716 L244.473934,74.9218119 C252.208531,91.7559351 256,109.65167 256,127.699063 C256,198.22039 198.521327,255.699063 128,255.699063 C57.478673,255.699063 0,198.22039 0,127.699063 C0,57.177736 57.478673,-0.300936964 128.151659,0.00118559798 Z M128.151659,69.7654137 C160.151659,69.7654137 186.388626,95.8507218 186.540284,128.154039 C186.540284,160.457357 160.454976,186.542665 128.151659,186.542665 C95.8483412,186.542665 69.7630332,160.457357 69.7630332,128.154039 C69.7630332,95.8507218 96,69.7654137 128.151659,69.7654137 Z M211.71564,21.5379256 C226.457193,21.5379256 238.407583,33.4883156 238.407583,48.2298687 C238.407583,62.9714219 226.457193,74.9218119 211.71564,74.9218119 C196.974087,74.9218119 185.023697,62.9714219 185.023697,48.2298687 C185.023697,33.4883156 196.974087,21.5379256 211.71564,21.5379256 Z\" fill=\"#3880FF\"/> </g> </svg>"
17
+ }
package/setup.mjs ADDED
@@ -0,0 +1,39 @@
1
+ export function tabs(doc) {
2
+ return {
3
+ accounts: {
4
+ svg_icon:
5
+ '<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-palette" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#2c3e50" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"/> <path d="M12 21a9 9 0 1 1 0 -18a9 8 0 0 1 9 8a4.5 4 0 0 1 -4.5 4h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25" /> <circle cx="7.5" cy="10.5" r=".5" fill="currentColor" /> <circle cx="12" cy="7.5" r=".5" fill="currentColor" /> <circle cx="16.5" cy="10.5" r=".5" fill="currentColor" /> </svg>',
6
+ text: "Accounts",
7
+ type: "multi",
8
+
9
+ fields: {
10
+ db_name: {
11
+ type: "text",
12
+ placeholder: "My Db",
13
+ mandatory: true,
14
+ label: "Name",
15
+ size: 12,
16
+ value: `Main Db`,
17
+ },
18
+ db_connection_string: {
19
+ type: "text",
20
+ placeholder: "https://john:12345678@db.xuda.io:6984/employees",
21
+ mandatory: true,
22
+ label: "Db Connection String",
23
+ size: 12,
24
+ value: `https://${doc.app_db_admin_username}:${doc.app_db_admin_password}@db.xuda.io/${doc.app_db_name}`,
25
+ },
26
+ },
27
+ },
28
+ };
29
+ }
30
+
31
+ export function public_filter(doc) {
32
+ var ret = {};
33
+
34
+ for (const [key, val] of Object.entries(doc.accounts)) {
35
+ ret[key] = {};
36
+ }
37
+
38
+ return ret;
39
+ }