1 module hunt.entity.dialect.PostgreSQLDialect; 2 3 import hunt.entity.dialect.Dialect; 4 import hunt.database.query.Common; 5 import hunt.Exceptions; 6 7 import std.conv; 8 import std.format; 9 import std.variant; 10 11 12 class PostgreSQLDialect : Dialect 13 { 14 // Database _db; 15 // this(Database db) 16 // { 17 // _db = db; 18 // } 19 this() { 20 21 } 22 23 Variant fromSqlValue(DlangDataType type,Variant value) 24 { 25 if(typeid(type) == typeid(dBoolType)){ 26 if(*value.peek!string == "true") 27 return Variant(true); 28 else 29 return Variant(false); 30 }else if(typeid(type) == typeid(dFloatType)) 31 return Variant(safeConvert!(string,float)(*value.peek!string)); 32 else if(typeid(type) == typeid(dDoubleType)) 33 return Variant(safeConvert!(string,double)(*value.peek!string)); 34 else if(typeid(type) == typeid(dIntType)) 35 return Variant(safeConvert!(string,int)(*value.peek!string)); 36 else if(typeid(type) == typeid(dLongType)) 37 return Variant(safeConvert!(string,long)(*value.peek!string)); 38 else 39 return value; 40 } 41 string toSqlValueImpl(DlangDataType type,Variant value) 42 { 43 if(typeid(type) == typeid(dBoolType)) 44 return value.get!(bool) ? "TRUE" : "FALSE"; 45 else if(typeid(type) == typeid(dFloatType)) 46 return safeConvert!(float,string)(*value.peek!float); 47 else if(typeid(type) == typeid(dDoubleType)) 48 return safeConvert!(double,string)(*value.peek!double); 49 else if(typeid(type) == typeid(dIntType)) 50 return value.toString; 51 else { 52 implementationMissing(false); 53 return value.toString(); 54 // return _db.escapeLiteral(value.toString); 55 } 56 } 57 string getColumnDefinition(ColumnDefinitionInfo info) { 58 if (!(info.dType in DTypeToPropertyType)) 59 throw new Exception("unsupport type %d of %s".format(info.dType,info.name)); 60 SqlSingleTypeInfo sqlInfo = DTypeToSqlInfo[DTypeToPropertyType[info.dType]]; 61 62 string nullable = info.isNullable ? "" : " NOT NULL"; 63 string primaryKey = info.isId ? " PRIMARY KEY" : ""; 64 string autoIncrease; 65 if (info.isAuto) { 66 if (sqlInfo.sqlType == SqlType.SMALLINT || sqlInfo.sqlType == SqlType.TINYINT) 67 autoIncrease = "SERIAL PRIMARY KEY"; 68 if (sqlInfo.sqlType == SqlType.INTEGER) 69 autoIncrease = "SERIAL PRIMARY KEY"; 70 else 71 autoIncrease = "BIGSERIAL PRIMARY KEY"; 72 return autoIncrease; 73 } 74 int len = info.len == 0 ? sqlInfo.len : info.len; 75 string modifiers = nullable ~ primaryKey ~ autoIncrease; 76 string lenmodifiers = "("~to!string(len > 0 ? len : 255)~")"~modifiers; 77 switch (sqlInfo.sqlType) { 78 case SqlType.BIGINT: 79 return "BIGINT" ~ modifiers; 80 case SqlType.BIT: 81 case SqlType.BOOLEAN: 82 return "BOOLEAN" ~ modifiers; 83 case SqlType.INTEGER: 84 return "INT" ~ modifiers; 85 case SqlType.NUMERIC: 86 return "INT" ~ modifiers; 87 case SqlType.SMALLINT: 88 return "SMALLINT" ~ modifiers; 89 case SqlType.TINYINT: 90 return "SMALLINT" ~ modifiers; 91 case SqlType.FLOAT: 92 return "FLOAT(24)" ~ modifiers; 93 case SqlType.DOUBLE: 94 return "FLOAT(53)" ~ modifiers; 95 case SqlType.DECIMAL: 96 return "REAL" ~ modifiers; 97 case SqlType.DATE: 98 return "DATE" ~ modifiers; 99 case SqlType.DATETIME: 100 return "TIMESTAMP" ~ modifiers; 101 case SqlType.TIME: 102 return "TIME" ~ modifiers; 103 case SqlType.CHAR: 104 case SqlType.CLOB: 105 case SqlType.LONGNVARCHAR: 106 case SqlType.LONGVARBINARY: 107 case SqlType.LONGVARCHAR: 108 case SqlType.NCHAR: 109 case SqlType.NCLOB: 110 case SqlType.VARBINARY: 111 case SqlType.VARCHAR: 112 case SqlType.NVARCHAR: 113 return "TEXT" ~ modifiers; 114 case SqlType.BLOB: 115 return "BYTEA"; 116 default: 117 return "TEXT"; 118 } 119 } 120 } 121 122 string[] PGSQL_RESERVED_WORDS = [ 123 "ABORT", 124 "ACTION", 125 "ADD", 126 "AFTER", 127 "ALL", 128 "ALTER", 129 "ANALYZE", 130 "AND", 131 "AS", 132 "ASC", 133 "ATTACH", 134 "AUTOINCREMENT", 135 "BEFORE", 136 "BEGIN", 137 "BETWEEN", 138 "BY", 139 "CASCADE", 140 "CASE", 141 "CAST", 142 "CHECK", 143 "COLLATE", 144 "COLUMN", 145 "COMMIT", 146 "CONFLICT", 147 "CONSTRAINT", 148 "CREATE", 149 "CROSS", 150 "CURRENT_DATE", 151 "CURRENT_TIME", 152 "CURRENT_TIMESTAMP", 153 "DATABASE", 154 "DEFAULT", 155 "DEFERRABLE", 156 "DEFERRED", 157 "DELETE", 158 "DESC", 159 "DETACH", 160 "DISTINCT", 161 "DROP", 162 "EACH", 163 "ELSE", 164 "END", 165 "ESCAPE", 166 "EXCEPT", 167 "EXCLUSIVE", 168 "EXISTS", 169 "EXPLAIN", 170 "FAIL", 171 "FOR", 172 "FOREIGN", 173 "FROM", 174 "FULL", 175 "GLOB", 176 "GROUP", 177 "HAVING", 178 "IF", 179 "IGNORE", 180 "IMMEDIATE", 181 "IN", 182 "INDEX", 183 "INDEXED", 184 "INITIALLY", 185 "INNER", 186 "INSERT", 187 "INSTEAD", 188 "INTERSECT", 189 "INTO", 190 "IS", 191 "ISNULL", 192 "JOIN", 193 "KEY", 194 "LEFT", 195 "LIKE", 196 "LIMIT", 197 "MATCH", 198 "NATURAL", 199 "NO", 200 "NOT", 201 "NOTNULL", 202 "NULL", 203 "OF", 204 "OFFSET", 205 "ON", 206 "OR", 207 "ORDER", 208 "OUTER", 209 "PLAN", 210 "PRAGMA", 211 "PRIMARY", 212 "QUERY", 213 "RAISE", 214 "REFERENCES", 215 "REGEXP", 216 "REINDEX", 217 "RELEASE", 218 "RENAME", 219 "REPLACE", 220 "RESTRICT", 221 "RIGHT", 222 "ROLLBACK", 223 "ROW", 224 "SAVEPOINT", 225 "SELECT", 226 "SET", 227 "TABLE", 228 "TEMP", 229 "TEMPORARY", 230 "THEN", 231 "TO", 232 "TRANSACTION", 233 "TRIGGER", 234 "UNION", 235 "UNIQUE", 236 "UPDATE", 237 "USER", 238 "USING", 239 "VACUUM", 240 "VALUES", 241 "VIEW", 242 "VIRTUAL", 243 "WHEN", 244 "WHERE", 245 ];