1
+ import { DeleteStatement , QueryObject , RenameStatement , UpdateObject , WhereStatement } from './types/plainsqlbuilderTypes'
2
+
3
+ const generateConditionQuery = ( where : WhereStatement , filters : string [ ] ) => {
4
+ filters . push (
5
+ `${ where [ "column" ] } ${ where [ "type" ] } (${
6
+ typeof ( where [ "value" ] ) === "string" ? where [ "value" ] : generateQuery ( where [ "value" ] )
7
+ } ) ${
8
+ where [ "connector" ] ? where [ "connector" ] : ""
9
+ } `
10
+ )
11
+ }
12
+
13
+ function generateQuery ( queries : QueryObject ) {
14
+ let statement : string = "SELECT " ;
15
+ // SELECT comes as a string array or object to rename
16
+ /*
17
+ * renameObject
18
+ * {
19
+ * column, -> original name
20
+ * rename -> name to override
21
+ * }
22
+ * */
23
+ if ( queries [ "SELECT" ] ) {
24
+ let indexToDeleteDistinct : number = 0 ;
25
+ if ( Array . isArray ( queries [ "SELECT" ] ) && queries [ "SELECT" ] . find ( ( val , index ) => {
26
+ if ( typeof val == 'string' && val . toLowerCase ( ) === 'distinct' ) indexToDeleteDistinct = index ;
27
+ let res : boolean ;
28
+ if ( typeof val === 'string' ) res = val . toLowerCase ( ) === 'distinct' ;
29
+ else res = false ;
30
+ return res ;
31
+ } ) ) {
32
+ statement += "DISTINCT " ;
33
+ delete queries [ "SELECT" ] [ indexToDeleteDistinct ] ;
34
+ }
35
+ const selectColumns : string [ ] = [ ] ;
36
+
37
+ queries [ "SELECT" ] . forEach ( select => {
38
+ let preparedStr = "" ;
39
+ typeof ( select ) === 'string' ? preparedStr += select + " " : preparedStr += `${ select [ "column" ] } AS ${ select [ "rename" ] } ` ;
40
+ selectColumns . push ( preparedStr ) ;
41
+ } )
42
+
43
+ statement += selectColumns . join ( ", " )
44
+ }
45
+ else statement += `* `
46
+ // FROM comes as a string array and Object to specify the JOIN
47
+ /*
48
+ * JOIN setting object
49
+ * {
50
+ * type, -> "INNER JOIN" | "OUTER JOIN"
51
+ * table, -> Table to join | Can be a query object with "rename" property to exec a rename
52
+ * condition : [{
53
+ column,
54
+ type, -> ">" | "<" | ">=" | "LIKE" | "ON"
55
+ value, -> Can be query object.
56
+ connector? -> "AND" | "OR" to the next filter
57
+ }]
58
+ * }
59
+ * */
60
+ if ( queries [ "FROM" ] ) {
61
+ const joinFilters : string [ ] = [ ] ;
62
+
63
+ if ( queries [ "FROM" ] . length > 2 ) throw ( 'JOIN solo se puede hacer con 2 tablas' ) ;
64
+
65
+ if ( queries [ "FROM" ] . length == 1 ) statement += `FROM ${ queries [ "FROM" ] [ 0 ] } `
66
+ else {
67
+ ( queries [ "FROM" ] [ 1 ] ) ?. condition . forEach ( ( condition ) => {
68
+ joinFilters . push (
69
+ `${ condition [ "column" ] } ${ condition [ "type" ] } (${
70
+ typeof ( condition [ "value" ] ) === "string" ? condition [ "value" ] : generateQuery ( condition [ "value" ] )
71
+ } ) ${
72
+ condition [ "connector" ] ? condition [ "connector" ] : ""
73
+ } `
74
+ )
75
+ } )
76
+ statement += `FROM ${ queries [ "FROM" ] [ 0 ] } ${ queries [ "FROM" ] [ 1 ] ?. table } (${
77
+ ( typeof ( queries [ "FROM" ] [ 1 ] ?. table ) === 'string' ? queries [ "FROM" ] [ 1 ] . table : generateQuery ( queries [ "FROM" ] [ 1 ] ?. table as QueryObject ) )
78
+ } ) ON ${ joinFilters . join ( "" ) } `
79
+ }
80
+ }
81
+ else throw ( 'Debe existir un FROM o alguna tabla a la cual consultar' )
82
+ // WHERE comes as a object array
83
+ /*
84
+ * {
85
+ * column,
86
+ * type, -> ">" | "<" | ">=" | "LIKE" | "ON"
87
+ * value, -> Can be query object with "rename" property.
88
+ * connector? -> "AND" | "OR" to the next filter
89
+ * }
90
+ * */
91
+ if ( queries [ "WHERE" ] ) {
92
+ const filters : string [ ] = [ ]
93
+ queries [ "WHERE" ] . forEach ( where => {
94
+ generateConditionQuery ( where , filters ) ;
95
+ } )
96
+
97
+ statement += `WHERE ${ filters . join ( "" ) } `
98
+ }
99
+
100
+ // GROUP BY comes as string array
101
+ if ( queries [ "GROUP_BY" ] ) {
102
+ statement += `GROUP BY (${ queries [ "GROUP_BY" ] . join ( "," ) } ) ` ;
103
+ }
104
+
105
+ if ( queries [ "HAVING" ] ) {
106
+ const filters : string [ ] = [ ]
107
+ queries [ "HAVING" ] . forEach ( where => {
108
+ generateConditionQuery ( where , filters ) ;
109
+ } )
110
+
111
+ statement += `HAVING ${ filters . join ( "" ) } ;`
112
+ }
113
+ return statement ;
114
+ }
115
+
116
+ function generateInsertStatement ( table : string , data : object ) {
117
+ return `INSERT INTO ${ table } (${ Object . keys ( data ) . join ( ", " ) } ) VALUES(${ Object . values ( data ) . join ( ", " ) } ) `
118
+ }
119
+
120
+
121
+ /*
122
+ * update object
123
+ * {
124
+ * column, -> Column affected
125
+ * newValue, -> New value for the column,
126
+ * condition: [{
127
+ * column,
128
+ * type, -> ">" | "<" | ">=" | "LIKE" | "ON"
129
+ * value, -> Can be query object with "rename" property.
130
+ * connector? -> "AND" | "OR" to the next filter
131
+ * }]
132
+ * }
133
+ *
134
+ * */
135
+ function generateUpdateStatement ( table : string , update : UpdateObject ) {
136
+ let statement = `UPDATE ${ table } SET ${ update [ "column" ] } = ${ update [ "newValue" ] } `
137
+
138
+ const filters : string [ ] = [ ] ;
139
+
140
+ update [ "condition" ] . forEach ( where => {
141
+ generateConditionQuery ( where , filters ) ;
142
+ } )
143
+
144
+ statement += `WHERE ${ filters . join ( "" ) } `
145
+
146
+ return statement ;
147
+ }
148
+
149
+ function generateDeleteStatement ( table : string , deleteData : DeleteStatement ) {
150
+ if ( ! deleteData [ "condition" ] ) throw ( 'Para eliminar debe tener un Condition Object' )
151
+ let statement = `DELETE FROM ${ table } ` ;
152
+
153
+ const filters : string [ ] = [ ] ;
154
+
155
+ deleteData [ "condition" ] . forEach ( where => {
156
+ generateConditionQuery ( where , filters ) ;
157
+ } )
158
+
159
+ statement += `WHERE ${ filters . join ( "" ) } ` ;
160
+
161
+ return statement ;
162
+ }
163
+
164
+ module . exports = { generateQuery, generateInsertStatement, generateUpdateStatement, generateDeleteStatement }
0 commit comments