1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.data.mapping.engines.sqlshared;
7
8 import std.conv : to;
9
10 import mysql;
11
12 import diamond.database : DbParam;
13
14 public
15 {
16 import diamond.data.mapping.engines.sqlshared.sqladapter;
17 import diamond.data.mapping.engines.sqlshared.sqlentityformatter;
18 }
19
20 mixin template CreatePool(TPool, string extraParams = "")
21 {
22 /// Global pool lock to ensure we don't attempt to create a connection pool twice on same connection string.
23 private static shared globalPoolLock = new Object;
24
25 static const poolFormat = q{
26 package(diamond.data.mapping.engines) TPool getPool(string connectionString)
27 {
28 auto pool = _pools.get(connectionString, null);
29
30 if (!pool)
31 {
32 synchronized (globalPoolLock)
33 {
34 pool = new TPool(connectionString%s);
35
36 _pools[connectionString] = pool;
37 }
38
39 return getPool(connectionString);
40 }
41
42 return pool;
43 }
44 };
45
46 import std..string : format;
47
48 mixin(poolFormat.format("," ~ extraParams));
49 }
50
51 /**
52 * Prepares a specialized parameter sql.
53 * Params:
54 * sql = The sql.
55 * params = The params.
56 * transformedSql = The newly transformed sql.
57 * Returns:
58 * The raw db parameters, iff keepParameters is false.
59 */
60 package(diamond.data.mapping.engines) auto prepareSql(bool keepParameters = false)(string sql, DbParam[string] params, out string transformedSql)
61 {
62 transformedSql = "";
63
64 static if (keepParameters)
65 {
66 return params;
67 }
68 else
69 {
70 string paramName = "";
71 bool selectParam = false;
72 DbParam[] sqlParams;
73
74 foreach (i; 0 .. sql.length)
75 {
76 auto c = sql[i];
77
78 if (c == 13) continue;
79
80 bool isEnd = i == (sql.length - 1);
81
82 if (c == '@')
83 {
84 paramName = "";
85 selectParam = true;
86 }
87 else if (selectParam && (
88 c == ';' || c == '=' ||
89 c == '+' || c == '-' ||
90 c == 9 || c == 13 ||
91 c == 10 || c == ' ' ||
92 c == 0 || c == '|' ||
93 c == '.' || c == '/' ||
94 c == '*' || c == '(' ||
95 c == ')' || c == '[' ||
96 c == ']' || c == ',' ||
97 c == '`' || c == 39
98 ))
99 {
100 if (paramName == "table")
101 {
102 transformedSql ~= params[paramName].get!string ~ to!string(c);
103 selectParam = false;
104 paramName = "";
105 }
106 else
107 {
108 sqlParams ~= params[paramName];
109 transformedSql ~= "?" ~ c;
110
111 selectParam = false;
112 paramName = "";
113 }
114 }
115 else if (selectParam)
116 {
117 paramName ~= c;
118
119 if (isEnd)
120 {
121 if (paramName == "table")
122 {
123 transformedSql ~= params[paramName].get!string ~ to!string(c);
124 }
125 else
126 {
127 sqlParams ~= params[paramName];
128 transformedSql ~= "?";
129 }
130 }
131 }
132 else
133 {
134 transformedSql ~= c;
135 }
136 }
137
138 return sqlParams;
139 }
140 }