1 module uim.sql; 2 3 public import std.algorithm; 4 public import std.conv; 5 public import std.stdio; 6 public import std.string; 7 8 public import uim.core; 9 public import uim.sql.statements; 10 public import uim.sql.tables; 11 public import uim.sql.index; 12 public import uim.sql.functions; 13 14 string OR(string[] conditions) { 15 string[] c = new string[conditions.length]; 16 foreach(i, x; conditions) c[i] = "("~x~")"; 17 if (conditions.length > 0) return c.join(" OR "); 18 return ""; 19 } 20 string AND(string[] conditions) { 21 string[] c = new string[conditions.length]; 22 foreach(i, x; conditions) c[i] = "("~x~")"; 23 if (conditions.length > 0) return c.join(" AND "); 24 return ""; 25 } 26 27 alias STRINGAA = string[string]; 28 29 //auto tableNames(Database db) { 30 // string[] names; 31 // foreach (row; db.execute("SELECT name FROM sqlite_master WHERE (type='table')")) { 32 // auto name = row[0].as!string.toUpper; 33 // if (name == "SQLITE_STAT1") continue; 34 // 35 // names ~= name; 36 // } 37 // return names; 38 //} 39 //string[] readTableColumns(Database db) { 40 // string[][string] results; 41 // foreach(tableName; tableNames(db)) { 42 // if (tableName == "STOCKS") continue; 43 // results[tableName] ~= readTableColumns(db, tableName); 44 // } 45 // return uniqueColumns(results); 46 //} 47 //string[] uniqueColumns(string[][string] colinTableNames) { 48 // string[string] results; 49 // foreach(tName, cols; colinTableNames) 50 // foreach(col; cols) results[col] = tName; 51 // return results.keys; 52 //} 53 //string[] readTableColumns(Database db, string tableName) { 54 // foreach (row; QueryCache(db.execute("SELECT * FROM "~tableName~" LIMIT 1"))) return row.columnIndexes.keys; 55 // return null; 56 //} 57 58 /++ 59 readRow - Reading data from a SQL result 60 +/ 61 void readFromDB(T)(DataRow!T dataRow, QueryCache.CachedRow dbRow, size_t[string] colName2Index, size_t[string] ignoreFlds = null) { 62 if (dataRow) { 63 if (ignoreFlds) { 64 foreach(k, v; dbRow.columnIndexes) { 65 auto kk = k.toUpper; 66 if (!(kk in ignoreFlds)) dataRow[colName2Index[kk]] = dbRow[v].as!T; 67 } 68 } 69 else { 70 foreach(k, v; dbRow.columnIndexes) { 71 dataRow[colName2Index[k.toUpper]] = dbRow[v].as!T; 72 } 73 } 74 } 75 } 76 77 void readFromDB(T)(DataMatrix!T matrix, size_t pos, QueryCache.CachedRow dbRow, size_t[string] colName2Index, size_t[string] ignoreFlds = null) { 78 if (!matrix) return; 79 80 if (auto row = matrix[pos]) { 81 if (ignoreFlds) { 82 foreach(k, v; dbRow.columnIndexes) { 83 auto kk = k.toUpper; 84 if (!(kk in ignoreFlds)) row[colName2Index[kk]] = dbRow[v].as!T; 85 } 86 } 87 else { 88 foreach(k, v; dbRow.columnIndexes) { 89 auto kk = k.toUpper; 90 row[colName2Index[kk]] = dbRow[v].as!T; 91 } 92 } 93 } 94 } 95 96 void readFromDB(T)(DataSplice!T splice, size_t pos, QueryCache.CachedRow dbRow, size_t[string] colName2Index, size_t[string] ignoreFlds = null) { 97 if ((splice) && (pos < splice.height)) { 98 if (ignoreFlds) { 99 foreach(k, v; dbRow.columnIndexes) { 100 auto kk = k.toUpper; 101 if (!(kk in ignoreFlds)) splice[pos, colName2Index[kk]] = dbRow[v].as!T; 102 } 103 } 104 else { 105 foreach(k, v; dbRow.columnIndexes) { 106 auto kk = k.toUpper; 107 splice[pos, colName2Index[kk]] = dbRow[v].as!T; 108 } 109 } 110 } 111 } 112 113 void save(T)(Database db, DataTable!T rows, string[] sources, string company) { 114 writeln("--- void save(Database db, DRow[] rows, string[] sources)..."); 115 116 auto pre = "(IDAY = %s) AND (NAME = '"~company~"')"; 117 foreach(iday, row; rows) if (row) { 118 auto sel = pre.format(iday); 119 auto update = ""; 120 foreach(source; sources) { 121 if (auto cells = row.changedCells(source)) { 122 update ~= "UPDATE "~source.sets(cells).where(sel)~";"; 123 } 124 } 125 try { 126 db.execute(update); 127 } 128 catch(Exception e) { 129 foreach(source; sources) { 130 if (auto cells = row.changedCells(source)) { 131 db.run("UPDATE "~source.sets(cells).where(sel)); 132 } 133 } 134 } 135 } 136 } 137 138 void save(T)(Database db, DataRow!(T)[] rows, string[] tableNames) { 139 // writeln("--- void save(Database db, DRow[] rows, string[] sources)..."); 140 141 auto pre = "(IDAY = %s) AND (NAME = '%s')"; 142 foreach(row; rows) if (row) { 143 auto name = row["NAME"].value!string; 144 auto iday = row["IDAY"].value!int; 145 auto sel = pre.format(iday, name); 146 147 auto update = ""; 148 foreach(tableName; tableNames) { 149 if (auto cells = row.changedCells(tableName)) { 150 update ~= "UPDATE "~tableName.sets(cells).where(sel)~";"; 151 } 152 } 153 try { 154 debug writeln(update); 155 db.run(update); 156 } 157 catch(Exception e) { 158 writeln(e); 159 foreach(tableName; tableNames) { 160 if (auto cells = row.changedCells(tableName)) { 161 db.run("UPDATE "~tableName.sets(cells).where(sel)); 162 } 163 } 164 } 165 } 166 } 167 //string[] columns(Database db, string tableName, string[] ignoreNames = null) { 168 // string[] names; 169 // foreach(row; db.execute("PRAGMA table_info("~tableName~")")) { 170 // auto name = row[1].as!string.toUpper; 171 // if(name.isIn(ignoreNames)) continue; 172 // 173 // names ~= name; 174 // } 175 // return names; 176 //} 177 // 178 //void save(T)(Database db, T[size_t][] changedCellsInRows, string[][string] tableCells, string companyName, size_t start = 0, bool dMode = false) { 179 // writeln("--- void save(Database db, DRow[] rows, string[] sources)..."); 180 // 181 // auto pre = "(NAME = '"~companyName~"') AND (IDAY = %s)"; 182 // foreach(iday, row; changedCellsInRows) if (row) { 183 // if (iday < start) continue; 184 // auto where = pre.format(iday); 185 // 186 // auto update = ""; 187 // foreach(tName, table; tableCells) { 188 // string[] sets; 189 // foreach(cell; table) if (cell in row) sets ~= "%s=%s".format(cell, row[cell]); 190 // if (sets) update ~= "UPDATE %s SET %s WHERE %s;".format(tName, sets.join(","), where); 191 // } 192 // try { 193 // //writeln(update); 194 // db.run(update); } 195 // catch(Exception e) { writeln(e); } 196 // } 197 //} 198 199 string sqlDeleteFrom(string tableName, string where = null) { 200 if (where) return "DELETE FROM %s WHERE %s;".format(tableName, where); 201 return "DELETE FROM %s;".format(tableName); 202 } 203 //void deleteFrom(Database db, string tableName, string where = null) { 204 // try { db.run(sqlDeleteFrom(tableName, where)); } 205 // catch(Exception e) { writeln("ERROR ", e); } 206 //} 207 // 208 //string sqlInsertInto(string tableName, string[] valueNames, string[] values) { 209 // return sqlInsertInto(tableName, valueNames.join(","), values.join(",")); } 210 //string sqlInsertInto(string tableName, string valueNames, string values) { 211 // return "INSERT INTO %s (%s) VALUES(%s);".format(tableName, valueNames, values); } 212 // 213 //void insertInto(Database db, string tableName, string[] valueNames, string[] values) { 214 // insertInto(db, tableName, valueNames.join(","), values.join(",")); } 215 //void insertInto(Database db, string tableName, string valueNames, string values) { 216 // try { db.run(sqlInsertInto(tableName, valueNames, values)); } 217 // catch(Exception e) { writeln("ERROR ", e); } 218 //} 219 //void insertInto(Database db, string sql) { 220 // try { db.run(sql); } 221 // catch(Exception e) { writeln("ERROR ", e); } 222 //} 223 //bool exists(Database db, string sql) { 224 // foreach(data; db.execute(sql)) return true; 225 // return false; 226 //} 227 228 string[] quote(string[] source, string quoteString) { return quote(source, quoteString, quoteString); } 229 string[] quote(string[] source, string start, string end) { 230 string[] result; 231 foreach(s; source) result ~= start~s~end; 232 return result; 233 } 234 235 //void update(Database db, string tableName, string[] sets, string where = null) { update(db, tableName, sets.join(","), where); } 236 //void update(Database db, string tableName, string sets, string[] where) { 237 // try { db.run(sqlUpdate(tableName, sets, where)); } 238 // catch(Exception e) { writeln("ERROR ", e); } 239 //} 240 //void update(Database db, string tableName, string sets, string where = null) { 241 // try { db.run(sqlUpdate(tableName, sets, where)); } 242 // catch(Exception e) { writeln("ERROR ", e); } 243 //} 244 // 245 //auto readTradesLevel0(Database db, string where = "") { 246 // STRINGAA tradeStrategies; 247 // auto select = "SELECT ID, L0 FROM TRADES WHERE (LEVEL = 0)"~(where.length > 0 ? " AND "~where : ""); 248 // foreach(row; db.execute(select)) { 249 // auto id = row[0].as!string; 250 // auto level0 = row[1].as!string; 251 // tradeStrategies[level0] = id; 252 // } 253 // return tradeStrategies; 254 //} 255 256 //auto readTradesLevel1(Database db, string where = "") { 257 // STRINGAA[string] tradeStrategies; 258 // auto select = "SELECT ID, L0, L1 FROM TRADES WHERE (LEVEL = 1)"~(where.length > 0 ? " AND "~where : ""); 259 // foreach(row; db.execute(select)) { 260 // auto id = row[0].as!string; 261 // auto level0 = row[1].as!string; 262 // auto level1 = row[2].as!string; 263 // if (level0 !in tradeStrategies) { 264 // STRINGAA values; 265 // tradeStrategies[level0] = values; 266 // } 267 // tradeStrategies[level0][level1] = id; 268 // } 269 // return tradeStrategies; 270 //} 271 // 272 //auto readTradesLevel2(Database db, string where = "") { 273 // STRINGAA[string][string] tradeStrategies; 274 // auto select = "SELECT ID, L0, L1, L2 FROM TRADES WHERE (LEVEL = 2)"~(where.length > 0 ? " AND "~where : ""); 275 // foreach(row; db.execute(select)) { 276 // auto id = row[0].as!string; 277 // auto level0 = row[1].as!string; 278 // auto level1 = row[2].as!string; 279 // auto level2 = row[3].as!string; 280 // if (level0 !in tradeStrategies) { 281 // STRINGAA[string] values; 282 // tradeStrategies[level0] = values; 283 // } 284 // if (level1 !in tradeStrategies[level0]) { 285 // STRINGAA values; 286 // tradeStrategies[level0][level1] = values; 287 // } 288 // tradeStrategies[level0][level1][level2] = id; 289 // } 290 // return tradeStrategies; 291 //} 292 //auto readTradesLevel3(Database db, string where = "") { 293 // STRINGAA[string][string][string] tradeStrategies; 294 // auto select = "SELECT ID, L0, L1, L2, L3 FROM TRADES WHERE (LEVEL = 3)"~(where.length > 0 ? " AND "~where : ""); 295 // foreach(row; db.execute(select)) { 296 // auto id = row[0].as!string; 297 // auto level0 = row[1].as!string; 298 // auto level1 = row[2].as!string; 299 // auto level2 = row[3].as!string; 300 // auto level3 = row[4].as!string; 301 // if (level0 !in tradeStrategies) { 302 // STRINGAA[string][string] values; 303 // tradeStrategies[level0] = values; 304 // } 305 // if (level1 !in tradeStrategies[level0]) { 306 // STRINGAA[string] values; 307 // tradeStrategies[level0][level1] = values; 308 // } 309 // if (level2 !in tradeStrategies[level0][level1]) { 310 // STRINGAA values; 311 // tradeStrategies[level0][level1][level2] = values; 312 // } 313 // tradeStrategies[level0][level1][level2][level3] = id; 314 // } 315 // return tradeStrategies; 316 //} 317 318 string deleteStrategy(string strategy) { 319 return sqlDeleteFrom("trades", "(ID = '%')".format(strategy)); 320 } 321 322 //string[] colNames(Database db, string[] exclusiveCols = []) { return colNames(db, db.tableNames, exclusiveCols); } 323 //string[] colNames(Database db, string[] tableNames, string[] exclusiveCols) { 324 // string[] result; 325 // 326 // foreach(tableName; tableNames) { 327 // auto cols = db.columns(tableName, exclusiveCols~result); 328 // result ~= cols; 329 // } 330 // 331 // return result; 332 //} 333 334 //string[][string] colNamesOfTables(Database db, string[] exclusiveCols) { return colNamesOfTables(db, db.tableNames, exclusiveCols); } 335 //string[][string] colNamesOfTables(Database db, string[] tableNames, string[] exclusiveCols) { 336 // string[][string] result; 337 // string[] allColumns; 338 // 339 // foreach(tableName; tableNames) { 340 // auto cols = db.columns(tableName, exclusiveCols~allColumns); 341 // allColumns ~= cols; 342 // result[tableName] = cols; 343 // } 344 // 345 // return result; 346 //} 347 // 348 //enum TABLEINITHEIGHT = 7000; 349 // 350 //string[] readCompanies(Database db, string select = "(ID > '%')") { 351 // string[] result; 352 // foreach (row; QueryCache(db.execute("SELECT ID FROM COMPANIES WHERE %s ORDER BY ID".format(select)))) 353 // result ~= row[0].as!string; 354 // return result; 355 //} 356 // 357 //string[] readGens(Database db, string select = "(NAME > '%')") { 358 // string[] result; 359 // foreach(row; db.execute("SELECT NAME FROM GENS")) result ~= row[0].as!string; 360 // return result; 361 //} 362 // 363 //T count(T:size_t)(Database db, string table, string where) { 364 // return SQLSelect("count(*)", table).where(where)(db).oneValue!T; 365 //}