doix-db 1.0.72 → 1.0.74

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/DbClient.js CHANGED
@@ -250,15 +250,25 @@ class DbClient extends EventEmitter {
250
250
 
251
251
  const executor = this.batch (options)
252
252
 
253
- return new Promise ((ok, fail) => {
253
+ try {
254
254
 
255
- statements.on ('error', fail)
256
- executor.on ('error', fail)
257
- executor.on ('close', ok)
255
+ await new Promise ((ok, fail) => {
258
256
 
259
- statements.pipe (executor)
257
+ statements.on ('error', fail)
258
+ executor.on ('error', fail)
259
+ executor.on ('close', ok)
260
+
261
+ statements.pipe (executor)
262
+
263
+ })
264
+
260
265
 
261
- })
266
+ }
267
+ catch (cause) {
268
+
269
+ throw Error (cause.message, {cause})
270
+
271
+ }
262
272
 
263
273
  }
264
274
 
@@ -59,6 +59,8 @@ class DbCsvPrinter extends Transform {
59
59
 
60
60
  if (!Array.isArray (columns)) columns = Object.entries (columns).map (([name, def]) => {
61
61
 
62
+ if (typeof def === 'string') def = this.lang.parseColumn (def)
63
+
62
64
  const col = new DbColumn (def)
63
65
 
64
66
  col.name = name
package/lib/DbLang.js CHANGED
@@ -14,6 +14,17 @@ const DbTypeCharacter = require ('./model/types/DbTypeCharacter.js')
14
14
  const DbTypeDate = require ('./model/types/DbTypeDate.js')
15
15
  const DbTypeTimestamp = require ('./model/types/DbTypeTimestamp.js')
16
16
 
17
+ const CH_ROUND_CLOSE = ')'.charCodeAt (0)
18
+ const CH_SQUARE_CLOSE = ']'.charCodeAt (0)
19
+ const CH_CURLY_OPEN = '{'.charCodeAt (0)
20
+ const CH_CURLY_CLOSE = '}'.charCodeAt (0)
21
+ const CH_SLASH = '/'.charCodeAt (0)
22
+ const CH_BACK_SLASH = '\\'.charCodeAt (0)
23
+ const CH_QUESTION = '?'.charCodeAt (0)
24
+ const CH_EXCLAMATION = '!'.charCodeAt (0)
25
+
26
+ const RE_INT = /^[1-9][0-9]*$/
27
+
17
28
  const CH_Q = "'", CH_QQ = '"'
18
29
 
19
30
  const Q_ESC = new stringEscape ([
@@ -93,6 +104,30 @@ class DbLang {
93
104
 
94
105
  }
95
106
 
107
+ createDbObject (options) {
108
+
109
+ {
110
+
111
+ const {columns} = options; if (columns)
112
+
113
+ for (const name in columns)
114
+
115
+ if (typeof columns [name] === 'string')
116
+
117
+ columns [name] = this.parseColumn (columns [name])
118
+
119
+ }
120
+
121
+ const clazz = this.getDbObjectClass (options)
122
+
123
+ const dbObject = new clazz (options)
124
+
125
+ dbObject.setLang (this)
126
+
127
+ return dbObject
128
+
129
+ }
130
+
96
131
  getDbObjectClassesToDiscover () {
97
132
 
98
133
  return [DbTable]
@@ -548,6 +583,183 @@ class DbLang {
548
583
 
549
584
  }
550
585
 
586
+ parseColumn (src) {
587
+
588
+ const o = {src: src.trim ()}
589
+
590
+ try {
591
+
592
+ this.parseColumnComment (o)
593
+ this.parseColumnExtra (o)
594
+ this.parseColumnPattern (o)
595
+ this.parseColumnRange (o)
596
+ this.parseColumnDefault (o)
597
+
598
+ if (o.src.length === 0) throw Error (`Cannot determine the type`)
599
+
600
+ this.parseColumnNullable (o)
601
+
602
+ o.isReference = o.type.startsWith ('(')
603
+
604
+ if (!o.isReference) {
605
+ this.parseColumnDimension (o)
606
+ }
607
+
608
+ o.src = src
609
+
610
+ return o
611
+
612
+ }
613
+ catch (cause) {
614
+
615
+ if (o.src.length === 0) throw Error (`Invalid column definition: '${src}'`, {cause})
616
+
617
+ }
618
+
619
+ }
620
+
621
+ parseColumnComment (o) {
622
+
623
+ const {src} = o, pos = src.lastIndexOf ('//'); if (pos < 0) return
624
+
625
+ o.comment = src.substring (pos + 2).trimStart ()
626
+
627
+ o.src = src.substring (0, pos).trimEnd ()
628
+
629
+ }
630
+
631
+ parseColumnExtra (o) {
632
+
633
+ const {src} = o
634
+
635
+ let pos = src.length - 1; if (src.charCodeAt (pos) !== CH_CURLY_CLOSE) return
636
+
637
+ let level = 1; while (level !== 0) {
638
+
639
+ if (-- pos < 0) throw Error ('Unbalanced "}"')
640
+
641
+ switch (src.charCodeAt (pos)) {
642
+
643
+ case CH_CURLY_CLOSE:
644
+ level ++
645
+ break
646
+
647
+ case CH_CURLY_OPEN:
648
+ level --
649
+ break
650
+
651
+ }
652
+
653
+ }
654
+
655
+ for (const [k, v] of Object.entries (new Function ('return ' + src.substring (pos)) ())) o [k] = v
656
+
657
+ o.src = src.substring (0, pos).trimEnd ()
658
+
659
+ }
660
+
661
+ parseColumnPattern (o) {
662
+
663
+ const {src} = o
664
+
665
+ let pos = src.length - 1; if (src.charCodeAt (pos) !== CH_SLASH) return
666
+
667
+ while (true) {
668
+
669
+ pos = src.lastIndexOf ('/', pos - 1); if (pos < 0) throw Error (`Cannot find opening '/' for the pattern`)
670
+
671
+ if (src.charCodeAt (pos - 1) !== CH_BACK_SLASH) break
672
+
673
+ }
674
+
675
+ o.pattern = src.slice (pos + 1, -1)
676
+
677
+ o.src = src.substring (0, pos).trimEnd ()
678
+
679
+ }
680
+
681
+ parseColumnRange (o) {
682
+
683
+ const {src} = o
684
+
685
+ if (src.charCodeAt (src.length - 1) !== CH_SQUARE_CLOSE) return
686
+
687
+ const begin = src.lastIndexOf ('['); if (begin < 0) throw Error (`Cannot find the opening '[' for range`)
688
+
689
+ const range = src.slice (begin + 1, -1)
690
+
691
+ o.src = src.substring (0, begin).trimEnd ()
692
+
693
+ const pos = range.indexOf ('..'); if (pos < 0) throw Error (`Cannot find '..' between '[' and ']'`)
694
+
695
+ const min = range.substring (0, pos).trim (); if (min.length !== 0) o.min = min
696
+
697
+ const max = range.substring (pos + 2).trim (); if (max.length !== 0) o.max = max
698
+
699
+ }
700
+
701
+ parseColumnDefault (o) {
702
+
703
+ const {src} = o, pos = src.indexOf ('='); if (pos < 0) return
704
+
705
+ o.default = src.substring (pos + 1).trimStart ()
706
+
707
+ if (o.default.length === 0) throw Error (`Empty (but not NULL neither '') default definition`)
708
+
709
+ o.src = src.substring (0, pos).trimEnd ()
710
+
711
+ }
712
+
713
+ parseColumnNullable (o) {
714
+
715
+ let nullable = !('default' in o)
716
+
717
+ const {src} = o, {length} = src, override = nullable ? CH_EXCLAMATION : CH_QUESTION
718
+
719
+ if (src.charCodeAt (length - 1) === override) {
720
+
721
+ nullable = !nullable
722
+
723
+ o.src = src.slice (0, -1).trim ()
724
+
725
+ }
726
+
727
+ o.nullable = nullable
728
+
729
+ o.type = o.src
730
+
731
+ }
732
+
733
+ parseColumnDimension (o) {
734
+
735
+ const src = o.type
736
+
737
+ if (src.charCodeAt (src.length - 1) !== CH_ROUND_CLOSE) return
738
+
739
+ const begin = src.lastIndexOf ('('); if (begin < 0) throw Error (`Cannot find opening '(' for dimension`)
740
+
741
+ let dimension = src.slice (begin + 1, -1)
742
+
743
+ o.type = src.slice (0, begin).trim ()
744
+
745
+ const pos = dimension.indexOf (','); if (pos >= 0) {
746
+
747
+ const scale = dimension.slice (pos + 1).trim ()
748
+
749
+ if (!RE_INT.test (scale)) throw Error (`Not a positive integer as scale`)
750
+
751
+ o.scale = parseInt (scale)
752
+
753
+ dimension = dimension.slice (0, pos).trim ()
754
+
755
+ }
756
+
757
+ if (!RE_INT.test (dimension)) throw Error (`Not a positive integer as column dimension`)
758
+
759
+ o.size = parseInt (dimension)
760
+
761
+ }
762
+
551
763
  }
552
764
 
553
765
  module.exports = DbLang
@@ -1,175 +1,23 @@
1
1
  const DbReference = require ('./DbReference.js')
2
2
 
3
- const CH_ROUND_OPEN = '('.charCodeAt (0)
4
- const CH_ROUND_CLOSE = ')'.charCodeAt (0)
5
- const CH_CURLY_CLOSE = '}'.charCodeAt (0)
6
- const CH_SLASH = '/'.charCodeAt (0)
7
- const CH_BACK_SLASH = '\\'.charCodeAt (0)
8
- const CH_QUESTION = '?'.charCodeAt (0)
9
- const CH_EXCLAMATION = '!'.charCodeAt (0)
10
-
11
- const RE_INT = /^[1-9][0-9]*$/
12
-
13
3
  class DbColumn {
14
4
 
15
5
  constructor (o) {
16
6
 
17
- if (typeof o === 'string') {
18
-
19
- this.src = o
20
-
21
- this.parse ()
22
-
23
- }
24
- else {
25
-
26
- for (const k in o) this [k] = o [k]
27
-
28
- if (!('nullable' in this)) this.nullable = !('default' in this)
29
-
30
- }
31
-
32
- }
33
-
34
- parse () {
35
-
36
- const {src} = this, pos = src.lastIndexOf ('//')
37
-
38
- if (pos < 0) {
39
-
40
- this.type = src.trim ()
41
-
42
- }
43
- else {
44
-
45
- this.type = src.slice (0, pos).trim ()
7
+ const {isReference} = o
46
8
 
47
- this.comment = src.slice (pos + 2).trim ()
9
+ for (const k in o) if (k !== 'isReference') this [k] = o [k]
48
10
 
49
- }
50
-
51
- this.parseDefault ()
52
- this.parsePattern ()
53
- this.parseRange ()
54
- this.parseNullable ()
55
-
56
- if (this.type.charCodeAt (0) === CH_ROUND_OPEN) {
11
+ if (isReference) {
57
12
 
58
13
  this.reference = new DbReference (this.type, this)
59
-
14
+
60
15
  this.type = undefined
61
-
62
- }
63
- else {
64
-
65
- this.parseDimension ()
66
-
67
- }
68
16
 
69
- }
17
+ }
70
18
 
71
- parseDefault () {
72
-
73
- const pos = this.type.indexOf ('='); if (pos < 0) return
74
-
75
- this.default = this.type.slice (pos + 1).trim ()
76
-
77
- this.type = this.type.slice (0, pos).trim ()
78
-
79
- }
80
-
81
- parsePattern () {
82
-
83
- const last = this.default ? 'default' : 'type', src = this [last]
84
-
85
- let pos = src.length - 1; if (src.charCodeAt (pos) !== CH_SLASH) return
86
-
87
- while (true) {
88
-
89
- pos = src.lastIndexOf ('/', pos - 1)
90
-
91
- if (pos < 0) throw Error (`Invalid column definition: cannot find opening '/' for pattern in '${this.src}'`)
92
-
93
- if (pos === 0) throw Error (`Invalid column definition: the ${last} is empty in '${this.src}'`)
94
-
95
- if (src.charCodeAt (pos - 1) !== CH_BACK_SLASH) break
19
+ if (!('nullable' in this)) this.nullable = !('default' in this)
96
20
 
97
- }
98
-
99
- this.pattern = src.slice (pos + 1, -1)
100
-
101
- this [last] = src.slice (0, pos).trim ()
102
-
103
- }
104
-
105
- parseRange () {
106
-
107
- const last = this.default ? 'default' : 'type', src = this [last]
108
-
109
- if (src.charCodeAt (src.length - 1) !== CH_CURLY_CLOSE) return
110
-
111
- const begin = src.lastIndexOf ('{'); if (begin < 0) throw Error (`Invalid column definition: cannot find opening '{' for range in '${this.src}'`)
112
-
113
- const range = src.slice (begin + 1, -1)
114
-
115
- this [last] = src.slice (0, begin).trim ()
116
-
117
- const pos = range.indexOf ('..'); if (pos < 0) throw Error (`Invalid column definition: cannot find '..' between '{' and '}' in '${this.src}'`)
118
-
119
- const min = range.slice (0, pos).trim (); if (min.length !== 0) this.min = min
120
-
121
- const max = range.slice (pos + 2).trim (); if (max.length !== 0) this.max = max
122
-
123
- }
124
-
125
- parseNullable () {
126
-
127
- let nullable = !('default' in this)
128
-
129
- const src = this.type, {length} = src; if (length === 0) throw Error (`Invalid column definition: cannot determine type in '${this.src}'`)
130
-
131
- const override = nullable ? CH_EXCLAMATION : CH_QUESTION
132
-
133
- if (src.charCodeAt (length - 1) === override) {
134
-
135
- nullable = !nullable
136
-
137
- this.type = src.slice (0, -1).trim ()
138
-
139
- }
140
-
141
- this.nullable = nullable
142
-
143
- }
144
-
145
- parseDimension () {
146
-
147
- const src = this.type
148
-
149
- if (src.charCodeAt (src.length - 1) !== CH_ROUND_CLOSE) return
150
-
151
- const begin = src.lastIndexOf ('('); if (begin < 0) throw Error (`Invalid column definition: cannot find opening '(' for dimension in '${this.src}'`)
152
-
153
- let dimension = src.slice (begin + 1, -1)
154
-
155
- this.type = src.slice (0, begin).trim ()
156
-
157
- const pos = dimension.indexOf (','); if (pos >= 0) {
158
-
159
- const scale = dimension.slice (pos + 1).trim ()
160
-
161
- if (!RE_INT.test (scale)) throw Error (`Invalid column definition: not a positive integer as scale in '${this.src}'`)
162
-
163
- this.scale = parseInt (scale)
164
-
165
- dimension = dimension.slice (0, pos).trim ()
166
-
167
- }
168
-
169
- if (!RE_INT.test (dimension)) throw Error (`Invalid column definition: not a positive integer as column dimension in '${this.src}'`)
170
-
171
- this.size = parseInt (dimension)
172
-
173
21
  }
174
22
 
175
23
  setLang (lang) {
@@ -42,14 +42,12 @@ class DbSchema extends require ('events') {
42
42
 
43
43
  create (options) {
44
44
 
45
- const {model} = this, {lang} = model
45
+ const {model} = this, {lang} = model
46
46
 
47
47
  options.model = model
48
48
  options.schema = this
49
49
 
50
- const dbObject = new (lang.getDbObjectClass (options)) (options)
51
-
52
- dbObject.setLang (lang)
50
+ const dbObject = lang.createDbObject (options)
53
51
 
54
52
  this.emit ('object-created', dbObject)
55
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doix-db",
3
- "version": "1.0.72",
3
+ "version": "1.0.74",
4
4
  "description": "Shared database related code for doix",
5
5
  "main": "index.js",
6
6
  "files": [