1 module hunt.sql.parser.Keywords; 2 3 import hunt.sql.util.DBType; 4 import hunt.sql.parser.Token; 5 import hunt.sql.util.FnvHash; 6 import hunt.sql.util.Utils; 7 8 import hunt.collection; 9 10 import std.concurrency : initOnce; 11 12 13 public class Keywords { 14 15 private Map!(string, Token) keywords; 16 17 private long[] hashArray; 18 private Token[] tokens; 19 20 static Keywords DEFAULT_KEYWORDS() { 21 __gshared Keywords inst; 22 return initOnce!inst(buildDefaultKeywords()); 23 } 24 25 static Keywords SQLITE_KEYWORDS() { 26 __gshared Keywords inst; 27 return initOnce!inst(buildSqliteKeywords()); 28 } 29 30 private static Keywords buildDefaultKeywords() { 31 Map!(string, Token) map = new HashMap!(string, Token)(); 32 33 map.put("ALL", Token.ALL); 34 map.put("ALTER", Token.ALTER); 35 map.put("AND", Token.AND); 36 map.put("ANY", Token.ANY); 37 map.put("AS", Token.AS); 38 39 map.put("ENABLE", Token.ENABLE); 40 map.put("DISABLE", Token.DISABLE); 41 42 map.put("ASC", Token.ASC); 43 map.put("BETWEEN", Token.BETWEEN); 44 map.put("BY", Token.BY); 45 map.put("CASE", Token.CASE); 46 map.put("CAST", Token.CAST); 47 48 map.put("CHECK", Token.CHECK); 49 map.put("CONSTRAINT", Token.CONSTRAINT); 50 map.put("CREATE", Token.CREATE); 51 map.put("DATABASE", Token.DATABASE); 52 map.put("DEFAULT", Token.DEFAULT); 53 map.put("COLUMN", Token.COLUMN); 54 map.put("TABLESPACE", Token.TABLESPACE); 55 map.put("PROCEDURE", Token.PROCEDURE); 56 map.put("FUNCTION", Token.FUNCTION); 57 58 map.put("DELETE", Token.DELETE); 59 map.put("DESC", Token.DESC); 60 map.put("DISTINCT", Token.DISTINCT); 61 map.put("DROP", Token.DROP); 62 map.put("ELSE", Token.ELSE); 63 map.put("EXPLAIN", Token.EXPLAIN); 64 map.put("EXCEPT", Token.EXCEPT); 65 66 map.put("END", Token.END); 67 map.put("ESCAPE", Token.ESCAPE); 68 map.put("EXISTS", Token.EXISTS); 69 map.put("FOR", Token.FOR); 70 map.put("FOREIGN", Token.FOREIGN); 71 72 map.put("FROM", Token.FROM); 73 map.put("FULL", Token.FULL); 74 map.put("GROUP", Token.GROUP); 75 map.put("HAVING", Token.HAVING); 76 map.put("IN", Token.IN); 77 78 map.put("INDEX", Token.INDEX); 79 map.put("INNER", Token.INNER); 80 map.put("INSERT", Token.INSERT); 81 map.put("INTERSECT", Token.INTERSECT); 82 map.put("INTERVAL", Token.INTERVAL); 83 84 map.put("INTO", Token.INTO); 85 map.put("IS", Token.IS); 86 map.put("JOIN", Token.JOIN); 87 map.put("KEY", Token.KEY); 88 map.put("LEFT", Token.LEFT); 89 90 map.put("LIKE", Token.LIKE); 91 map.put("LOCK", Token.LOCK); 92 map.put("MINUS", Token.MINUS); 93 map.put("NOT", Token.NOT); 94 95 map.put("NULL", Token.NULL); 96 map.put("ON", Token.ON); 97 map.put("OR", Token.OR); 98 map.put("ORDER", Token.ORDER); 99 map.put("OUTER", Token.OUTER); 100 101 map.put("PRIMARY", Token.PRIMARY); 102 map.put("REFERENCES", Token.REFERENCES); 103 map.put("RIGHT", Token.RIGHT); 104 map.put("SCHEMA", Token.SCHEMA); 105 map.put("SELECT", Token.SELECT); 106 107 map.put("SET", Token.SET); 108 map.put("SOME", Token.SOME); 109 map.put("TABLE", Token.TABLE); 110 map.put("THEN", Token.THEN); 111 map.put("TRUNCATE", Token.TRUNCATE); 112 113 map.put("UNION", Token.UNION); 114 map.put("UNIQUE", Token.UNIQUE); 115 map.put("UPDATE", Token.UPDATE); 116 map.put("VALUES", Token.VALUES); 117 map.put("VIEW", Token.VIEW); 118 map.put("SEQUENCE", Token.SEQUENCE); 119 map.put("TRIGGER", Token.TRIGGER); 120 map.put("USER", Token.USER); 121 122 map.put("WHEN", Token.WHEN); 123 map.put("WHERE", Token.WHERE); 124 map.put("XOR", Token.XOR); 125 126 map.put("OVER", Token.OVER); 127 map.put("TO", Token.TO); 128 map.put("USE", Token.USE); 129 130 map.put("REPLACE", Token.REPLACE); 131 132 map.put("COMMENT", Token.COMMENT); 133 map.put("COMPUTE", Token.COMPUTE); 134 map.put("WITH", Token.WITH); 135 map.put("GRANT", Token.GRANT); 136 map.put("REVOKE", Token.REVOKE); 137 138 // MySql procedure: add by zz 139 map.put("WHILE", Token.WHILE); 140 map.put("DO", Token.DO); 141 map.put("DECLARE", Token.DECLARE); 142 map.put("LOOP", Token.LOOP); 143 map.put("LEAVE", Token.LEAVE); 144 map.put("ITERATE", Token.ITERATE); 145 map.put("REPEAT", Token.REPEAT); 146 map.put("UNTIL", Token.UNTIL); 147 map.put("OPEN", Token.OPEN); 148 map.put("CLOSE", Token.CLOSE); 149 map.put("CURSOR", Token.CURSOR); 150 map.put("FETCH", Token.FETCH); 151 map.put("OUT", Token.OUT); 152 map.put("INOUT", Token.INOUT); 153 map.put("LIMIT", Token.LIMIT); 154 155 return new Keywords(map); 156 } 157 158 private static Keywords buildSqliteKeywords() { 159 160 Map!(string, Token) sqlitemap = new HashMap!(string, Token)(); 161 162 sqlitemap.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); 163 164 sqlitemap.put("LIMIT", Token.LIMIT); 165 return new Keywords(sqlitemap); 166 } 167 168 public bool containsValue(Token token) { 169 return this.keywords.containsValue(token); 170 } 171 172 public this(Map!(string, Token) keywords){ 173 this.keywords = keywords; 174 175 this.hashArray = new long[keywords.size()]; 176 this.tokens = new Token[keywords.size()]; 177 178 int index = 0; 179 foreach(string k ; keywords.byKey()) { 180 hashArray[index++] = FnvHash.fnv1a_64_lower(k); 181 } 182 import std.algorithm.sorting; 183 import std.algorithm.searching; 184 185 sort!("a < b")(hashArray); 186 foreach (string key ,Token v ; keywords) { 187 long k = FnvHash.fnv1a_64_lower(key); 188 index = search(hashArray,k); 189 tokens[index] = v; 190 } 191 } 192 193 public Token getKeyword(long hash) { 194 int index = search(hashArray, hash); 195 if (index < 0) { 196 return null; 197 } 198 return tokens[index]; 199 } 200 201 public Token getKeyword(string key) { 202 long k = FnvHash.fnv1a_64_lower(key); 203 int index = search(hashArray, k); 204 if (index < 0) { 205 return null; 206 } 207 return tokens[index]; 208 // return keywords.get(key); 209 } 210 211 public Map!(string, Token) getKeywords() { 212 return keywords; 213 } 214 215 }