1 module mysql.appender; 2 3 4 import std.conv; 5 import std.datetime; 6 import std.format; 7 import std.traits; 8 9 import mysql.protocol; 10 import mysql.type; 11 12 13 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == typeof(null))) { 14 appender.put("null"); 15 } 16 17 void appendValue(Appender, T)(ref Appender appender, T value) if (isScalarType!T) { 18 appender.put(cast(ubyte[])to!string(value)); 19 } 20 21 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == SysTime)) { 22 value = value.toUTC; 23 24 auto hour = value.hour; 25 auto minute = value.minute; 26 auto second = value.second; 27 auto usec = value.fracSecs.total!"usecs"; 28 29 formattedWrite(appender, "%04d%02d%02d", value.year, value.month, value.day); 30 if (hour | minute | second | usec) { 31 formattedWrite(appender, "%02d%02d%02d", hour, minute, second); 32 if (usec) 33 formattedWrite(appender, ".%06d", usec); 34 } 35 } 36 37 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == DateTime)) { 38 auto hour = value.hour; 39 auto minute = value.minute; 40 auto second = value.second; 41 42 if (hour | minute | second) { 43 formattedWrite(appender, "%04d%02d%02d%02d%02d%02d", value.year, value.month, value.day, hour, minute, second); 44 } else { 45 formattedWrite(appender, "%04d%02d%02d", value.year, value.month, value.day); 46 } 47 } 48 49 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == TimeOfDay)) { 50 formattedWrite(appender, "%02d%02d%02d", value.hour, value.minute, value.second); 51 } 52 53 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == Date)) { 54 formattedWrite(appender, "%04d%02d%02d", value.year, value.month, value.day); 55 } 56 57 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == Duration)) { 58 auto parts = value.split(); 59 if (parts.days) { 60 appender.put('\''); 61 formattedWrite(appender, "%d ", parts.days); 62 } 63 formattedWrite(appender, "%02d%02d%02d", parts.hours, parts.minutes, parts.seconds); 64 if (parts.usecs) 65 formattedWrite(appender, ".%06d ", parts.usecs); 66 if (parts.days) 67 appender.put('\''); 68 } 69 70 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLFragment)) { 71 appender.put(cast(char[])value.data); 72 } 73 74 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLRawString)) { 75 appender.put('\''); 76 appender.put(cast(char[])value.data); 77 appender.put('\''); 78 } 79 80 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLBinary)) { 81 appendValue(appender, value.data); 82 } 83 84 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLValue)) { 85 final switch(value.type) with (ColumnTypes) { 86 case MYSQL_TYPE_NULL: 87 appender.put("null"); 88 break; 89 case MYSQL_TYPE_TINY: 90 if (value.isSigned) { 91 appendValue(appender, value.peek!byte); 92 } else { 93 appendValue(appender, value.peek!ubyte); 94 } 95 break; 96 case MYSQL_TYPE_YEAR: 97 case MYSQL_TYPE_SHORT: 98 if (value.isSigned) { 99 appendValue(appender, value.peek!short); 100 } else { 101 appendValue(appender, value.peek!ushort); 102 } 103 break; 104 case MYSQL_TYPE_INT24: 105 case MYSQL_TYPE_LONG: 106 if (value.isSigned) { 107 appendValue(appender, value.peek!int); 108 } else { 109 appendValue(appender, value.peek!uint); 110 } 111 break; 112 case MYSQL_TYPE_LONGLONG: 113 if (value.isSigned) { 114 appendValue(appender, value.peek!long); 115 } else { 116 appendValue(appender, value.peek!ulong); 117 } 118 break; 119 case MYSQL_TYPE_DOUBLE: 120 appendValue(appender, value.peek!double); 121 break; 122 case MYSQL_TYPE_FLOAT: 123 appendValue(appender, value.peek!float); 124 break; 125 case MYSQL_TYPE_SET: 126 case MYSQL_TYPE_ENUM: 127 case MYSQL_TYPE_VARCHAR: 128 case MYSQL_TYPE_VAR_STRING: 129 case MYSQL_TYPE_STRING: 130 case MYSQL_TYPE_JSON: 131 case MYSQL_TYPE_NEWDECIMAL: 132 case MYSQL_TYPE_DECIMAL: 133 appendValue(appender, value.peek!(char[])); 134 break; 135 case MYSQL_TYPE_BIT: 136 case MYSQL_TYPE_TINY_BLOB: 137 case MYSQL_TYPE_MEDIUM_BLOB: 138 case MYSQL_TYPE_LONG_BLOB: 139 case MYSQL_TYPE_BLOB: 140 case MYSQL_TYPE_GEOMETRY: 141 appendValue(appender, value.peek!(ubyte[])); 142 break; 143 case MYSQL_TYPE_TIME: 144 case MYSQL_TYPE_TIME2: 145 appendValue(appender, value.peek!Duration); 146 break; 147 case MYSQL_TYPE_DATE: 148 case MYSQL_TYPE_NEWDATE: 149 case MYSQL_TYPE_DATETIME: 150 case MYSQL_TYPE_DATETIME2: 151 case MYSQL_TYPE_TIMESTAMP: 152 case MYSQL_TYPE_TIMESTAMP2: 153 appendValue(appender, value.peek!SysTime); 154 break; 155 } 156 } 157 158 void appendValue(Appender, T)(ref Appender appender, T value) if (isArray!T && (is(Unqual!(typeof(T.init[0])) == ubyte) || is(Unqual!(typeof(T.init[0])) == char))) { 159 appender.put('\''); 160 auto ptr = value.ptr; 161 auto end = value.ptr + value.length; 162 while (ptr != end) { 163 switch(*ptr) { 164 case '\\': 165 case '\'': 166 appender.put('\\'); 167 goto default; 168 default: 169 appender.put(*ptr++); 170 } 171 } 172 appender.put('\''); 173 }