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(typeof(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 == MySQLRawString)) { 71 appender.put('\''); 72 appender.put(cast(char[])value.data); 73 appender.put('\''); 74 } 75 76 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLBinary)) { 77 appendValue(appender, value.data); 78 } 79 80 void appendValue(Appender, T)(ref Appender appender, T value) if (is(Unqual!T == MySQLValue)) { 81 final switch(value.type) with (ColumnTypes) { 82 case MYSQL_TYPE_NULL: 83 appender.put("null"); 84 break; 85 case MYSQL_TYPE_TINY: 86 if (value.isSigned) { 87 appendValue(appender, value.peek!byte); 88 } else { 89 appendValue(appender, value.peek!ubyte); 90 } 91 break; 92 case MYSQL_TYPE_YEAR: 93 case MYSQL_TYPE_SHORT: 94 if (value.isSigned) { 95 appendValue(appender, value.peek!short); 96 } else { 97 appendValue(appender, value.peek!ushort); 98 } 99 break; 100 case MYSQL_TYPE_INT24: 101 case MYSQL_TYPE_LONG: 102 if (value.isSigned) { 103 appendValue(appender, value.peek!int); 104 } else { 105 appendValue(appender, value.peek!uint); 106 } 107 break; 108 case MYSQL_TYPE_LONGLONG: 109 if (value.isSigned) { 110 appendValue(appender, value.peek!long); 111 } else { 112 appendValue(appender, value.peek!ulong); 113 } 114 break; 115 case MYSQL_TYPE_DOUBLE: 116 appendValue(appender, value.peek!double); 117 break; 118 case MYSQL_TYPE_FLOAT: 119 appendValue(appender, value.peek!float); 120 break; 121 case MYSQL_TYPE_SET: 122 case MYSQL_TYPE_ENUM: 123 case MYSQL_TYPE_VARCHAR: 124 case MYSQL_TYPE_VAR_STRING: 125 case MYSQL_TYPE_STRING: 126 case MYSQL_TYPE_NEWDECIMAL: 127 case MYSQL_TYPE_DECIMAL: 128 appendValue(appender, value.peek!(char[])); 129 break; 130 case MYSQL_TYPE_BIT: 131 case MYSQL_TYPE_TINY_BLOB: 132 case MYSQL_TYPE_MEDIUM_BLOB: 133 case MYSQL_TYPE_LONG_BLOB: 134 case MYSQL_TYPE_BLOB: 135 case MYSQL_TYPE_GEOMETRY: 136 appendValue(appender, value.peek!(ubyte[])); 137 break; 138 case MYSQL_TYPE_TIME: 139 case MYSQL_TYPE_TIME2: 140 appendValue(appender, value.peek!Duration); 141 break; 142 case MYSQL_TYPE_DATE: 143 case MYSQL_TYPE_NEWDATE: 144 case MYSQL_TYPE_DATETIME: 145 case MYSQL_TYPE_DATETIME2: 146 case MYSQL_TYPE_TIMESTAMP: 147 case MYSQL_TYPE_TIMESTAMP2: 148 appendValue(appender, value.peek!SysTime); 149 break; 150 } 151 } 152 153 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))) { 154 appender.put('\''); 155 auto ptr = value.ptr; 156 auto end = value.ptr + value.length; 157 while (ptr != end) { 158 switch(*ptr) { 159 case '\\': 160 case '\'': 161 appender.put('\\'); 162 goto default; 163 default: 164 appender.put(*ptr++); 165 } 166 } 167 appender.put('\''); 168 }