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 }