1 module microrm.util; 2 3 enum IDNAME = "id"; 4 5 string tableName(T)() 6 { 7 return T.stringof; 8 } 9 10 void fieldToCol(string name, T, Writer)(Writer w) 11 { 12 import std.format : formattedWrite; 13 static if (name == IDNAME) 14 { 15 w.put(IDNAME); 16 w.put(" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"); 17 } 18 else 19 { 20 enum NOTNULL = " NOT NULL"; 21 string type, param; 22 static if (is(T : ulong)) 23 { 24 type = "INTEGER"; 25 param = NOTNULL; 26 } 27 else static if (is(T : string)) 28 { 29 // TODO UDAs for VARCHAR 30 type = "TEXT"; 31 param = ""; 32 } 33 else static if (is(T : float)) 34 { 35 type = "REAL"; 36 param = ""; 37 } 38 else static assert(0, "unsupported type: " ~ T.stringof); 39 40 formattedWrite(w, "%s %s%s", name, type, param); 41 } 42 } 43 44 mixin template whereCondition() 45 { 46 import std.format : formattedWrite; 47 import std.range : isOutputRange; 48 static assert(isOutputRange!(typeof(this.query), char)); 49 50 ref where(V)(string field, V val) 51 { 52 this.query.formattedWrite(" WHERE %s '%s'", field, val); 53 return this; 54 } 55 56 ref whereQ(string field, string cmd) 57 { 58 this.query.formattedWrite(" WHERE %s %s", field, cmd); 59 return this; 60 } 61 62 ref and(V)(string field, V val) 63 { 64 this.query.formattedWrite(" AND %s '%s'", field, val); 65 return this; 66 } 67 68 ref andQ(string field, string cmd) 69 { 70 this.query.formattedWrite(" AND %s %s", field, cmd); 71 return this; 72 } 73 } 74 75 mixin template baseQueryData(string SQLTempl, size_t BufLen=512) 76 { 77 import std.array : Appender, appender; 78 import std.format : formattedWrite, format; 79 80 enum initialSQL = format(SQLTempl, tableName!T); 81 82 Database* db; 83 Appender!(char[]) query; 84 85 @disable this(); 86 87 this(Database* db) 88 { 89 this.db = db; 90 query.reserve(BufLen); 91 query.put(initialSQL); 92 } 93 94 void reset() 95 { 96 query.clear(); 97 query.put(initialSQL); 98 } 99 }