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 }