1 
2 module hunt.database.query.Common;
3 
4 import std.conv;
5 import std.variant;
6 
7 enum QUERY_TYPE : byte
8 {
9     SELECT,
10     UPDATE,
11     DELETE,
12     INSERT,
13     COUNT,
14     SHOW_TABLES,
15     DESC_TABLE
16 }
17 
18 class ValueVariant 
19 {
20     string key; // columnName
21     Variant value;
22 
23     this(string key, Variant value)
24     {
25         this.key = key;
26         this.value = value;
27     }
28 	
29     override string toString()
30     {
31         return  key ~ " = " ~ value.toString ;
32     }
33 }
34 
35 
36 string quoteSqlString(string s,string quotes = "\'") 
37 {
38 		string res = quotes;
39 		foreach(ch; s) {
40 			switch(ch) {
41 				case '\'': res ~= "\\\'"; break;
42 				case '\"': res ~= "\\\""; break;
43 				case '\\': res ~= "\\\\"; break;
44 				case '\0': res ~= "\\n"; break;
45 				case '\a': res ~= "\\a"; break;
46 				case '\b': res ~= "\\b"; break;
47 				case '\f': res ~= "\\f"; break;
48 				case '\n': res ~= "\\n"; break;
49 				case '\r': res ~= "\\r"; break;
50 				case '\t': res ~= "\\t"; break;
51 				case '\v': res ~= "\\v"; break;
52 				default:
53 					res ~= ch;
54 			}
55 		}
56 		res ~= quotes;
57 		//writeln("quoted " ~ s ~ " is " ~ res);
58 		return res;
59 }
60 
61 string quoteSqlStringIfNeed(T)(T t)
62 {
63     static if(is(T == string))
64         return quoteSqlString(t);
65     else
66         return t.to!string;
67 }
68 
69 
70 
71 import std.datetime;
72 import std.variant;
73 import std.json;
74 
75 // look other data type https://dev.mysql.com/doc/workbench/en/wb-migration-database-postgresql-typemapping.html?spm=5176.100239.blogcont69388.22.hCGHvq
76 
77 enum FieldType
78 {
79     FIELD_TYPE_CHAR,
80 
81     FIELD_TYPE_SHORT,
82     FIELD_TYPE_INT,
83     FIELD_TYPE_LONG,
84 
85     FIELD_TYPE_FLOAT,
86     FIELD_TYPE_DOUBLE,
87 
88     FIELD_TYPE_STRING,
89 
90     FIELD_TYPE_DATE,
91     FIELD_TYPE_TIME,
92     FIELD_TYPE_DATE_TIME,
93 
94     FIELD_TYPE_RAW
95 }
96 
97 enum ParamType
98 {
99     PARAM_BOOL,
100     PARAM_NULL,
101     PARAM_INT,
102     PARAM_STR,
103     PARAM_LOB,
104     PARAM_STMT,
105     PARAM_INPUT_OUTPUT
106 }
107 
108 enum SqlType {
109     //sometimes referred to as a type code, that identifies the generic SQL type ARRAY.
110     //ARRAY,
111     ///sometimes referred to as a type code, that identifies the generic SQL type BIGINT.
112     BIGINT,
113     ///sometimes referred to as a type code, that identifies the generic SQL type BINARY.
114     //BINARY,
115     //sometimes referred to as a type code, that identifies the generic SQL type BIT.
116     BIT,
117     ///sometimes referred to as a type code, that identifies the generic SQL type BLOB.
118     BLOB,
119     ///somtimes referred to as a type code, that identifies the generic SQL type BOOLEAN.
120     BOOLEAN,
121     ///sometimes referred to as a type code, that identifies the generic SQL type CHAR.
122     CHAR,
123     ///sometimes referred to as a type code, that identifies the generic SQL type CLOB.
124     CLOB,
125     //somtimes referred to as a type code, that identifies the generic SQL type DATALINK.
126     //DATALINK,
127     ///sometimes referred to as a type code, that identifies the generic SQL type DATE.
128     DATE,
129     ///sometimes referred to as a type code, that identifies the generic SQL type DATETIME.
130     DATETIME,
131     ///sometimes referred to as a type code, that identifies the generic SQL type DECIMAL.
132     DECIMAL,
133     //sometimes referred to as a type code, that identifies the generic SQL type DISTINCT.
134     //DISTINCT,
135     ///sometimes referred to as a type code, that identifies the generic SQL type DOUBLE.
136     DOUBLE,
137     ///sometimes referred to as a type code, that identifies the generic SQL type FLOAT.
138     FLOAT,
139     ///sometimes referred to as a type code, that identifies the generic SQL type INTEGER.
140     INTEGER,
141     //sometimes referred to as a type code, that identifies the generic SQL type JAVA_OBJECT.
142     //JAVA_OBJECT,
143     ///sometimes referred to as a type code, that identifies the generic SQL type LONGNVARCHAR.
144     LONGNVARCHAR,
145     ///sometimes referred to as a type code, that identifies the generic SQL type LONGVARBINARY.
146     LONGVARBINARY,
147     ///sometimes referred to as a type code, that identifies the generic SQL type LONGVARCHAR.
148     LONGVARCHAR,
149     ///sometimes referred to as a type code, that identifies the generic SQL type NCHAR
150     NCHAR,
151     ///sometimes referred to as a type code, that identifies the generic SQL type NCLOB.
152     NCLOB,
153     ///The constant in the Java programming language that identifies the generic SQL value NULL.
154     NULL,
155     ///sometimes referred to as a type code, that identifies the generic SQL type NUMERIC.
156     NUMERIC,
157     ///sometimes referred to as a type code, that identifies the generic SQL type NVARCHAR.
158     NVARCHAR,
159     ///indicates that the SQL type is database-specific and gets mapped to a object that can be accessed via the methods getObject and setObject.
160     OTHER,
161     //sometimes referred to as a type code, that identifies the generic SQL type REAL.
162     //REAL,
163     //sometimes referred to as a type code, that identifies the generic SQL type REF.
164     //REF,
165     //sometimes referred to as a type code, that identifies the generic SQL type ROWID
166     //ROWID,
167     ///sometimes referred to as a type code, that identifies the generic SQL type SMALLINT.
168     SMALLINT,
169     //sometimes referred to as a type code, that identifies the generic SQL type XML.
170     //SQLXML,
171     //sometimes referred to as a type code, that identifies the generic SQL type STRUCT.
172     //STRUCT,
173     ///sometimes referred to as a type code, that identifies the generic SQL type TIME.
174     TIME,
175     //sometimes referred to as a type code, that identifies the generic SQL type TIMESTAMP.
176     //TIMESTAMP,
177     ///sometimes referred to as a type code, that identifies the generic SQL type TINYINT.
178     TINYINT,
179     ///sometimes referred to as a type code, that identifies the generic SQL type VARBINARY.
180     VARBINARY,
181     ///sometimes referred to as a type code, that identifies the generic SQL type VARCHAR.
182     VARCHAR,
183 }
184 
185 enum MysqlField {
186 	//MysqlFieldAffinity Numeric Types
187 	BIT,
188 	TINYINT,
189 	BOOL,
190 	SMALLINT,
191 	MEDIUMINT,
192 	INT,
193 	INTEGER,
194 	BIGINT,
195 	SERIAL,
196 	DECIMAL,
197 	DEC,
198 	FLOAT,
199 	DOUBLE,
200 	//MysqlFieldAffinity Date/Time Types
201 	DATE,
202 	DATETIME,
203 	TIMESTAMP,
204 	TIME,
205 	YEAR,
206 	//MysqlFieldAffinity String Types
207 	BINARY,
208 	VARBINARY,
209 	TINYBLOB,
210 	TINYTEXT,
211 	BLOB,
212 	TEXT,
213 	MEDIUMBLOB,
214 	MEDIUMTEXT,
215 	LONGBLOB,
216 	LONGTEXT,
217 	ENUM,
218 	SET
219 }
220 enum PgsqlField {
221 	//PgsqlFieldAffinity Numeric Types
222 	SMALLINT,
223 	INTEGER,
224 	BIGINT,
225 	DECIMAL,
226 	NUMERIC,
227 	REAL,
228 	DOUBLE,
229 	SMALLSERIAL,
230 	SERIAL,
231 	BIGSERIAL,
232 	//PgsqlFieldAffinity Monetary Type
233 	MONEY,
234 	//PgsqlFieldAffinity Character Types
235 	CHARACTER,
236 	TEXT,
237 	//PgsqlFieldAffinity Binary Data Type
238 	BYTEA,
239 	//PgsqlFieldAffinity Date/Time Types
240 	TIMESTAMP,
241 	DATE,
242 	TIME,
243 	INTERVAL,
244 	//PgsqlFieldAffinity Boolean Type
245 	BOOLEAN,
246 	//PgsqlFieldAffinity Enumerated Type
247 	ENUM,
248 	//PgsqlFieldAffinity Geometric Types
249 	POINT,
250 	LINE,
251 	LSEG,
252 	BOX,
253 	PATH,
254 	POLYGON,
255 	CIRCLE,
256 	//PgsqlFieldAffinity Network Address Types
257 	CIDR,
258 	INET,
259 	MACADDR,
260 	//PgsqlFieldAffinity Bit String Type
261 	BIT,
262 	//PgsqlFieldAffinity Text Search Types
263 	TSVECTOR,
264 	TSQUERY,
265 	//PgsqlFieldAffinity UUID Type
266 	UUID,
267 	//PgsqlFieldAffinity XML Type
268 	XML,
269 	//PgsqlFieldAffinity JSON Type
270 	JSON,
271 	//PgsqlFieldAffinity Arrays Type
272 	ARRAYS,
273 	//OTHER
274 }
275 
276 enum SqliteField {
277 	//SqliteFieldAffinity INTEGER Types
278 	INT,
279 	INTEGER,
280 	TINYINT,
281 	SMALLINT,
282 	MEDIUMINT,
283 	BIGINT,
284 	UNSIGNEDBIGINT,
285 	INT2,
286 	INT8,
287 	//SqliteFieldAffinity Text Types
288 	CHARACTER,
289 	VARCHAR,
290 	NCHAR,
291 	NVARCHAR,
292 	TEXT,
293 	CLOB,
294 	//SqliteFieldAffinity Blob Type
295 	BLOB,
296 	//SqliteFieldAffinity REAL Type
297 	REAL,
298 	DOUBLE,
299 	FLOAT,
300 	//SqliteFieldAffinity Numeric Types
301 	NUMERIC,
302 	DECIMAL,
303 	BOOLEAN,
304 	DATE,
305 	DATETIME,
306 }
307 
308 enum MysqlFieldAffinity {
309 	Numeric,
310 	DateTime,
311 	String,
312 	JSON,
313 }
314 enum PgsqlFieldAffinity {
315 	Numeric,
316 	Monetary,
317 	Character,
318 	BinaryData,
319 	DateTime,
320 	Boolean,
321 	Enumerated,
322 	Geometric,
323 	NetworkAddress ,
324 	BitString,
325 	TextSearch,
326 	UUID,
327 	XML,
328 	JSON,
329 	Arrays,
330 	Composite,
331 	Range,
332 	ObjectIdentifier,
333 	pg_lsn,
334 	Pseudos
335 }
336 enum SqliteFieldAffinity {
337 	TEXT,
338 	NUMERIC,
339 	INTEGER,
340 	REAL,
341 	BLOB,
342 }
343 
344 class DlangDataType {
345 	string getName(){return "void";}
346 }
347 
348 class dBoolType : DlangDataType {
349 	override string getName(){return "bool";}
350 }
351 class dByteType : DlangDataType {
352 	override string getName(){return "byte";}
353 }
354 class dUbyteType : DlangDataType {
355 	override string getName(){return "ubyte";}
356 }
357 class dShortType : DlangDataType {
358 	override string getName(){return "short";}
359 }
360 class dUshortType : DlangDataType {
361 	override string getName(){return "ushort";}
362 }
363 class dIntType : DlangDataType {
364 	override string getName(){return "int";}
365 }
366 class dUintType : DlangDataType {
367 	override string getName(){return "uint";}
368 }
369 class dLongType : DlangDataType {
370 	override string getName(){return "long";}
371 }
372 class dUlongType : DlangDataType {
373 	override string getName(){return "ulong";}
374 }
375 class dFloatType : DlangDataType {
376 	override string getName(){return "float";}
377 }
378 class dDoubleType : DlangDataType {
379 	override string getName(){return "double";}
380 }
381 class dRealType : DlangDataType {
382 	override string getName(){return "real";}
383 }
384 class dIfloatType : DlangDataType {
385 	override string getName(){return "ifloat";}
386 }
387 class dIdoubleType : DlangDataType {
388 	override string getName(){return "idouble";}
389 }
390 class dIrealType : DlangDataType {
391 	override string getName(){return "ireal";}
392 }
393 class dCfloatType : DlangDataType {
394 	override string getName(){return "cfloat";}
395 }
396 class dCdoubleType : DlangDataType {
397 	override string getName(){return "cdouble";}
398 }
399 class dCrealType : DlangDataType {
400 	override string getName(){return "creal";}
401 }
402 class dCharType : DlangDataType {
403 	override string getName(){return "char";}
404 }
405 class dWcharType : DlangDataType {
406 	override string getName(){return "wchar";}
407 }
408 class dDcharType : DlangDataType {
409 	override string getName(){return "dchar";}
410 }
411 class dEnumType : DlangDataType {
412 	override string getName(){return "enum";}
413 }
414 class dStructType : DlangDataType {
415 	override string getName(){return "struct";}
416 }
417 class dUnionType : DlangDataType {
418 	override string getName(){return "union";}
419 }
420 class dClassType : DlangDataType {
421 	override string getName(){return "class";}
422 }
423 class dStringType : DlangDataType {
424 	override string getName(){return "string";}
425 }
426 class dJsonType : DlangDataType {
427 	override string getName(){return "json";}
428 }
429 class dDateType : DlangDataType {
430 	override string getName(){return "date";}
431 }
432 class dTimeType : DlangDataType {
433 	override string getName(){return "time";}
434 }
435 
436 
437 DlangDataType getDlangDataType(T)()
438 {
439 	static if(is(T == int))
440 		 return new dIntType();
441 	else static if(is(T == bool))
442 		 return new dBoolType();
443 	else static if(is(T == byte))
444 		 return new dByteType();
445 	else static if(is(T == ubyte))
446 		 return new dUbyteType();
447 	else static if(is(T == short))
448 		 return new dShortType();
449 	else static if(is(T == ushort))
450 		 return new dUshortType();
451 	else static if(is(T == uint))
452 		 return new dUintType();
453 	else static if(is(T == long))
454 		 return new dLongType();
455 	else static if(is(T == float))
456 		 return new dFloatType();
457 	else static if(is(T == double))
458 		 return new dDoubleType();
459 	else static if(is(T == real))
460 		 return new dRealType();
461 	else static if(is(T == ifloat))
462 		 return new dIfloatType();
463 	else static if(is(T == idouble))
464 		 return new dIdoubleType();
465 	else static if(is(T == ireal))
466 		 return new dIrealType();
467 	else static if(is(T == cfloat))
468 		 return new dCfloatType();
469 	else static if(is(T == cdouble))
470 		 return new dCdoubleType();
471 	else static if(is(T == creal))
472 		 return new dCrealType();
473 	else static if(is(T == char))
474 		 return new dCharType();
475 	else static if(is(T == wchar))
476 		 return new dWcharType();
477 	else static if(is(T == dchar))
478 		 return new dCharType();
479 	else static if(is(T == enum))
480 		 return new dEnumType();
481 	else static if(is(T == JSONValue))
482 		 return new dJsonType();
483 	else static if(is(T == SysTime))
484 		 return new dTimeType();
485 	else static if(is(T == DateTime))
486 		 return new dDateType();
487 	else 
488 		 return new dStringType();
489 }
490 string getDlangDataTypeStr(T)()
491 {
492 	static if(is(T == int))
493 		return "dIntType";
494 	else static if(is(T == bool))
495 		return "dBoolType";
496 	else static if(is(T == byte))
497 		return "dByteType";
498 	else static if(is(T == ubyte))
499 		return "dUbyteType";
500 	else static if(is(T == short))
501 		return "dShortType";
502 	else static if(is(T == ushort))
503 		return "dUshortType";
504 	else static if(is(T == uint))
505 		return "dUintType";
506 	else static if(is(T == long))
507 		return "dLongType";
508 	else static if(is(T == float))
509 		return "dFloatType";
510 	else static if(is(T == double))
511 		return "dDoubleType";
512 	else static if(is(T == real))
513 		return "dRealType";
514 	else static if(is(T == ifloat))
515 		return "dIfloatType";
516 	else static if(is(T == idouble))
517 		return "dIdoubleType";
518 	else static if(is(T == ireal))
519 		return "dIrealType";
520 	else static if(is(T == cfloat))
521 		return "dCfloatType";
522 	else static if(is(T == cdouble))
523 		return "dCdoubleType";
524 	else static if(is(T == creal))
525 		return "dCrealType";
526 	else static if(is(T == char))
527 		return "dCharType";
528 	else static if(is(T == wchar))
529 		return "dWcharType";
530 	else static if(is(T == dchar))
531 		return "dCharType";
532 	else static if(is(T == enum))
533 		return "dEnumType";
534 	else static if(is(T == JSONValue))
535 		return "dJsonType";
536 	else static if(is(T == SysTime))
537 		return "dTimeType";
538 	else static if(is(T == DateTime))
539 		return "dDateType";
540 	else 
541 		return "dStringType";
542 }
543 string getDlangTypeStr(T)()
544 {
545 	static if(is(T == int))
546 		return "int";
547 	else static if(is(T == bool))
548 		return "bool";
549 	else static if(is(T == byte))
550 		return "byte";
551 	else static if(is(T == ubyte))
552 		return "ubyte";
553 	else static if(is(T == short))
554 		return "short";
555 	else static if(is(T == ushort))
556 		return "ushort";
557 	else static if(is(T == uint))
558 		return "uint";
559 	else static if(is(T == long))
560 		return "long";
561 	else static if(is(T == float))
562 		return "float";
563 	else static if(is(T == double))
564 		return "double";
565 	else static if(is(T == real))
566 		return "real";
567 	else static if(is(T == ifloat))
568 		return "ifloat";
569 	else static if(is(T == idouble))
570 		return "idouble";
571 	else static if(is(T == ireal))
572 		return "ireal";
573 	else static if(is(T == cfloat))
574 		return "cfloat";
575 	else static if(is(T == cdouble))
576 		return "cdouble";
577 	else static if(is(T == creal))
578 		return "creal";
579 	else static if(is(T == char))
580 		return "char";
581 	else static if(is(T == wchar))
582 		return "wchar";
583 	else static if(is(T == dchar))
584 		return "dchar";
585 	else static if(is(T == JSONValue))
586 		return "JSONValue";
587 	else 
588 		return "string";
589 }
590 
591 enum JoinMethod : string {
592     InnerJoin = " INNER JOIN ",
593     LeftJoin = " LEFT JOIN ",
594     RightJoin = " RIGHT JOIN ",
595     FullJoin = " FULL JOIN ",
596     CrossJoin = " CROSS JOIN ",
597 }
598 enum Method : string {
599     Select = " SELECT ",
600     Insert = " INSERT INTO ",
601     Update = " UPDATE ",
602     Delete = " DELETE FROM",
603 	Count = " SELECT count(*) FROM ",
604 	ShowTables = "SHOW TABLES",
605 	DescTable = "DESC TABLE",
606 }
607 enum Relation : string {
608     And = " AND ", 
609     Or = " OR "
610 }
611 enum CompareType : string {
612     eq = " = ", 
613     ne = " != ", 
614     gt = " > ", 
615     lt = " < ", 
616     ge = " >= ", 
617     le = " <= ", 
618     eqnull = " is ",
619     nenull = " is not ",
620     like = " like "
621 }
622 
623 
624 enum PropertyMemberType : int {
625     BOOL_TYPE,    // bool
626     BYTE_TYPE,    // byte
627     SHORT_TYPE,   // short
628     INT_TYPE,     // int
629     LONG_TYPE,    // long
630     UBYTE_TYPE,   // ubyte
631     USHORT_TYPE,  // ushort
632     UINT_TYPE,    // uint
633     ULONG_TYPE,   // ulong
634     FLOAT_TYPE,   // float
635     DOUBLE_TYPE,   // double
636     STRING_TYPE,   // string
637 }
638 
639 enum PropertyMemberType[string] DTypeToPropertyType = [
640 	"bool" : PropertyMemberType.BOOL_TYPE,
641 	"short" : PropertyMemberType.SHORT_TYPE,
642 	"ushort" : PropertyMemberType.USHORT_TYPE,
643 	"int" : PropertyMemberType.INT_TYPE,
644 	"uint" : PropertyMemberType.UINT_TYPE,
645 	"long" : PropertyMemberType.LONG_TYPE,
646 	"ulong" : PropertyMemberType.ULONG_TYPE,
647 	"byte" : PropertyMemberType.BYTE_TYPE,
648 	"ubyte" : PropertyMemberType.UBYTE_TYPE,
649 	"float" : PropertyMemberType.FLOAT_TYPE,
650 	"double" : PropertyMemberType.DOUBLE_TYPE,
651 	"string" : PropertyMemberType.STRING_TYPE
652 ];