1 /** 2 * HibernateD - Object-Relation Mapping for D programming language, with interface similar to Hibernate. 3 * 4 * Source file hibernated/dialects/sqlitedialect.d. 5 * 6 * This module contains implementation of SQLiteDialect class which provides implementation specific SQL syntax information. 7 * 8 * Copyright: Copyright 2013 9 * License: $(LINK www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 10 * Author: Vadim Lopatin 11 */ 12 module hibernated.dialects.sqlitedialect; 13 14 import std.conv; 15 16 import hibernated.dialect; 17 import hibernated.metadata; 18 import hibernated.type; 19 import ddbc.core; 20 21 22 string[] SQLITE_RESERVED_WORDS = 23 [ 24 "ABORT", 25 "ACTION", 26 "ADD", 27 "AFTER", 28 "ALL", 29 "ALTER", 30 "ANALYZE", 31 "AND", 32 "AS", 33 "ASC", 34 "ATTACH", 35 "AUTOINCREMENT", 36 "BEFORE", 37 "BEGIN", 38 "BETWEEN", 39 "BY", 40 "CASCADE", 41 "CASE", 42 "CAST", 43 "CHECK", 44 "COLLATE", 45 "COLUMN", 46 "COMMIT", 47 "CONFLICT", 48 "CONSTRAINT", 49 "CREATE", 50 "CROSS", 51 "CURRENT_DATE", 52 "CURRENT_TIME", 53 "CURRENT_TIMESTAMP", 54 "DATABASE", 55 "DEFAULT", 56 "DEFERRABLE", 57 "DEFERRED", 58 "DELETE", 59 "DESC", 60 "DETACH", 61 "DISTINCT", 62 "DROP", 63 "EACH", 64 "ELSE", 65 "END", 66 "ESCAPE", 67 "EXCEPT", 68 "EXCLUSIVE", 69 "EXISTS", 70 "EXPLAIN", 71 "FAIL", 72 "FOR", 73 "FOREIGN", 74 "FROM", 75 "FULL", 76 "GLOB", 77 "GROUP", 78 "HAVING", 79 "IF", 80 "IGNORE", 81 "IMMEDIATE", 82 "IN", 83 "INDEX", 84 "INDEXED", 85 "INITIALLY", 86 "INNER", 87 "INSERT", 88 "INSTEAD", 89 "INTERSECT", 90 "INTO", 91 "IS", 92 "ISNULL", 93 "JOIN", 94 "KEY", 95 "LEFT", 96 "LIKE", 97 "LIMIT", 98 "MATCH", 99 "NATURAL", 100 "NO", 101 "NOT", 102 "NOTNULL", 103 "NULL", 104 "OF", 105 "OFFSET", 106 "ON", 107 "OR", 108 "ORDER", 109 "OUTER", 110 "PLAN", 111 "PRAGMA", 112 "PRIMARY", 113 "QUERY", 114 "RAISE", 115 "REFERENCES", 116 "REGEXP", 117 "REINDEX", 118 "RELEASE", 119 "RENAME", 120 "REPLACE", 121 "RESTRICT", 122 "RIGHT", 123 "ROLLBACK", 124 "ROW", 125 "SAVEPOINT", 126 "SELECT", 127 "SET", 128 "TABLE", 129 "TEMP", 130 "TEMPORARY", 131 "THEN", 132 "TO", 133 "TRANSACTION", 134 "TRIGGER", 135 "UNION", 136 "UNIQUE", 137 "UPDATE", 138 "USING", 139 "VACUUM", 140 "VALUES", 141 "VIEW", 142 "VIRTUAL", 143 "WHEN", 144 "WHERE", 145 ]; 146 147 148 class SQLiteDialect : Dialect { 149 ///The character specific to this dialect used to close a quoted identifier. 150 override char closeQuote() const { return '`'; } 151 ///The character specific to this dialect used to begin a quoted identifier. 152 override char openQuote() const { return '`'; } 153 154 // returns string like "BIGINT(20) NOT NULL" or "VARCHAR(255) NULL" 155 override string getColumnTypeDefinition(const PropertyInfo pi, const PropertyInfo overrideTypeFrom = null) { 156 immutable Type type = overrideTypeFrom !is null ? overrideTypeFrom.columnType : pi.columnType; 157 immutable SqlType sqlType = type.getSqlType(); 158 bool fk = pi is null; 159 string nullablility = !fk && pi.nullable ? " NULL" : " NOT NULL"; 160 string pk = !fk && pi.key ? " PRIMARY KEY" : ""; 161 string autoinc = !fk && pi.generated ? " AUTO_INCREMENT" : ""; 162 if (!fk && pi.generated) 163 return "INTEGER PRIMARY KEY"; 164 string def = ""; 165 int len = 0; 166 string unsigned = ""; 167 if (cast(NumberType)type !is null) { 168 len = (cast(NumberType)type).length; 169 unsigned = (cast(NumberType)type).unsigned ? " UNSIGNED" : ""; 170 } 171 if (cast(StringType)type !is null) { 172 len = (cast(StringType)type).length; 173 } 174 string modifiers = unsigned ~ nullablility ~ def ~ pk ~ autoinc; 175 string lenmodifiers = "(" ~ to!string(len > 0 ? len : 255) ~ ")" ~ modifiers; 176 switch (sqlType) { 177 case SqlType.BIGINT: 178 case SqlType.BIT: 179 case SqlType.BOOLEAN: 180 case SqlType.INTEGER: 181 case SqlType.NUMERIC: 182 case SqlType.SMALLINT: 183 case SqlType.TINYINT: 184 return "INT" ~ modifiers; 185 case SqlType.FLOAT: 186 case SqlType.DOUBLE: 187 case SqlType.DECIMAL: 188 return "REAL" ~ modifiers; 189 case SqlType.DATE: 190 case SqlType.DATETIME: 191 case SqlType.TIME: 192 case SqlType.CHAR: 193 case SqlType.CLOB: 194 case SqlType.LONGNVARCHAR: 195 case SqlType.LONGVARBINARY: 196 case SqlType.LONGVARCHAR: 197 case SqlType.NCHAR: 198 case SqlType.NCLOB: 199 case SqlType.VARBINARY: 200 case SqlType.VARCHAR: 201 case SqlType.NVARCHAR: 202 return "TEXT" ~ modifiers; 203 case SqlType.BLOB: 204 return "BLOB"; 205 default: 206 return "TEXT"; 207 } 208 } 209 210 override string getCheckTableExistsSQL(string tableName) { 211 return "SELECT name FROM sqlite_master WHERE type='table' AND name=" ~ quoteSqlString(tableName); 212 } 213 214 override string getUniqueIndexItemSQL(string indexName, string[] columnNames) { 215 return "UNIQUE " ~ createFieldListSQL(columnNames); 216 } 217 218 219 this() { 220 addKeywords(SQLITE_RESERVED_WORDS); 221 } 222 } 223