1 module postgresql.core; 2 3 public 4 { 5 import postgresql.value: Value; 6 import postgresql.protocol: PGType, Field; 7 } 8 9 package 10 { 11 import std.regex; 12 13 auto regexParam = ctRegex!(`\$\d+`, "g"); 14 15 void _debug(A...)(lazy A args) 16 { 17 debug version (POSTGRESQL_USE_DEBUG) 18 { 19 import std.stdio; 20 writefln(args); 21 } 22 } 23 } 24 25 import std.traits; 26 27 /** 28 * Error container 29 * 30 * API is stable 31 */ 32 struct PgError 33 { 34 //@disable this(); 35 private 36 { 37 string _msg; 38 int _code = -1; 39 } 40 41 @property const nothrow @safe @nogc 42 { 43 ///// Returns true if no error, otherwise false 44 bool empty() 45 { 46 return _code <= 0 && !_msg; 47 } 48 49 /// Error code 50 int code() 51 { 52 return _code; 53 } 54 55 /// Error text 56 const(string) msg() 57 { 58 return _msg; 59 } 60 61 T opCast(T)() 62 if ( is(T == bool) ) 63 { 64 return !this.empty; 65 } 66 } 67 68 this(in string m, int c = -1) nothrow @safe 69 { 70 _msg = m.dup; 71 _code = c; 72 } 73 } 74 /// 75 unittest 76 { 77 PgError empty; 78 79 assert(empty.empty); 80 assert(!empty); 81 assert(empty.code == -1); 82 assert(empty.msg == ""); 83 84 85 auto error = PgError("Some error", 100); 86 87 assert(error); 88 assert(!error.empty); 89 assert(error.code == 100); 90 assert(error.msg == "Some error"); 91 } 92 93 interface ILink 94 { 95 @property bool isAttached(); 96 @property string error(); 97 98 bool attach(bool wait = true); 99 void detach(); 100 101 final bool begin() 102 { 103 return exec("BEGIN"); 104 } 105 106 final bool commit() 107 { 108 return exec("COMMIT"); 109 } 110 111 final void rollback() 112 { 113 exec("ROLLBACK"); 114 } 115 116 final bool exec(A ...)(in string query, A args) 117 { 118 return exec(query, valueArray(args)); 119 } 120 121 bool exec(in string query, Value[] args = null); 122 123 bool query(T, A ...)(ref T result, in string query, A args) 124 { 125 return query(result, query, valueArray(args)); 126 } 127 128 bool query(T)(ref T result, in string query, Value[] args = null); 129 } 130 131 132 enum bool isResult(T) = isCallable!(T.reset) && arity!(T.reset) == 0 133 // setCols(size_t) 134 //&& isCallable!(T.setCols) 135 //&& arity!(T.setCols) == 1 136 //&& is(Parameters!(T.setCols)[0] == size_t) 137 // setRows(size_t) 138 //&& isCallable!(T.setRows) 139 //&& arity!(T.setRows) == 1 140 //&& is(Parameters!(T.setRows)[0] == size_t) 141 // rowBegin(size_t) 142 && isCallable!(T.rowBegin) 143 && arity!(T.rowBegin) == 1 144 && is(Parameters!(T.rowBegin)[0] == size_t) 145 // rowEnd(size_t) 146 && isCallable!(T.rowEnd) 147 && arity!(T.rowEnd) == 1 148 && is(Parameters!(T.rowEnd)[0] == size_t) 149 // dataAdd(size_t row, size_t col, Value val) 150 && isCallable!(T.dataAdd) 151 && arity!(T.dataAdd) == 3 152 && is(Parameters!(T.dataAdd)[0] == size_t) 153 && is(Parameters!(T.dataAdd)[1] == size_t) 154 && is(Parameters!(T.dataAdd)[2] == Value) 155 ; 156