1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.bnf; |
7 | |
8 | import java.util.HashMap; |
9 | import java.util.HashSet; |
10 | |
11 | import org.h2.bnf.context.DbSchema; |
12 | import org.h2.bnf.context.DbTableOrView; |
13 | import org.h2.util.New; |
14 | import org.h2.util.StringUtils; |
15 | |
16 | /** |
17 | * A query context object. It contains the list of table and alias objects. |
18 | * Used for autocomplete. |
19 | */ |
20 | public class Sentence { |
21 | |
22 | /** |
23 | * This token type means the possible choices of the item depend on the |
24 | * context. For example the item represents a table name of the current |
25 | * database. |
26 | */ |
27 | public static final int CONTEXT = 0; |
28 | |
29 | /** |
30 | * The token type for a keyword. |
31 | */ |
32 | public static final int KEYWORD = 1; |
33 | |
34 | /** |
35 | * The token type for a function name. |
36 | */ |
37 | public static final int FUNCTION = 2; |
38 | |
39 | private static final long MAX_PROCESSING_TIME = 100; |
40 | |
41 | /** |
42 | * The map of next tokens in the form type#tokenName token. |
43 | */ |
44 | private final HashMap<String, String> next = New.hashMap(); |
45 | |
46 | /** |
47 | * The complete query string. |
48 | */ |
49 | private String query; |
50 | |
51 | /** |
52 | * The uppercase version of the query string. |
53 | */ |
54 | private String queryUpper; |
55 | |
56 | private long stopAt; |
57 | private DbSchema lastMatchedSchema; |
58 | private DbTableOrView lastMatchedTable; |
59 | private DbTableOrView lastTable; |
60 | private HashSet<DbTableOrView> tables; |
61 | private HashMap<String, DbTableOrView> aliases; |
62 | |
63 | /** |
64 | * Start the timer to make sure processing doesn't take too long. |
65 | */ |
66 | public void start() { |
67 | stopAt = System.currentTimeMillis() + MAX_PROCESSING_TIME; |
68 | } |
69 | |
70 | /** |
71 | * Check if it's time to stop processing. |
72 | * Processing auto-complete shouldn't take more than a few milliseconds. |
73 | * If processing is stopped, this methods throws an IllegalStateException |
74 | */ |
75 | public void stopIfRequired() { |
76 | if (System.currentTimeMillis() > stopAt) { |
77 | throw new IllegalStateException(); |
78 | } |
79 | } |
80 | |
81 | /** |
82 | * Add a word to the set of next tokens. |
83 | * |
84 | * @param n the token name |
85 | * @param string an example text |
86 | * @param type the token type |
87 | */ |
88 | public void add(String n, String string, int type) { |
89 | next.put(type+"#"+n, string); |
90 | } |
91 | |
92 | /** |
93 | * Add an alias name and object |
94 | * |
95 | * @param alias the alias name |
96 | * @param table the alias table |
97 | */ |
98 | public void addAlias(String alias, DbTableOrView table) { |
99 | if (aliases == null) { |
100 | aliases = New.hashMap(); |
101 | } |
102 | aliases.put(alias, table); |
103 | } |
104 | |
105 | /** |
106 | * Add a table. |
107 | * |
108 | * @param table the table |
109 | */ |
110 | public void addTable(DbTableOrView table) { |
111 | lastTable = table; |
112 | if (tables == null) { |
113 | tables = New.hashSet(); |
114 | } |
115 | tables.add(table); |
116 | } |
117 | |
118 | /** |
119 | * Get the set of tables. |
120 | * |
121 | * @return the set of tables |
122 | */ |
123 | public HashSet<DbTableOrView> getTables() { |
124 | return tables; |
125 | } |
126 | |
127 | /** |
128 | * Get the alias map. |
129 | * |
130 | * @return the alias map |
131 | */ |
132 | public HashMap<String, DbTableOrView> getAliases() { |
133 | return aliases; |
134 | } |
135 | |
136 | /** |
137 | * Get the last added table. |
138 | * |
139 | * @return the last table |
140 | */ |
141 | public DbTableOrView getLastTable() { |
142 | return lastTable; |
143 | } |
144 | |
145 | /** |
146 | * Get the last matched schema if the last match was a schema. |
147 | * |
148 | * @return the last schema or null |
149 | */ |
150 | public DbSchema getLastMatchedSchema() { |
151 | return lastMatchedSchema; |
152 | } |
153 | |
154 | /** |
155 | * Set the last matched schema if the last match was a schema, |
156 | * or null if it was not. |
157 | * |
158 | * @param schema the last matched schema or null |
159 | */ |
160 | public void setLastMatchedSchema(DbSchema schema) { |
161 | this.lastMatchedSchema = schema; |
162 | } |
163 | |
164 | /** |
165 | * Set the last matched table if the last match was a table. |
166 | * |
167 | * @param table the last matched table or null |
168 | */ |
169 | public void setLastMatchedTable(DbTableOrView table) { |
170 | this.lastMatchedTable = table; |
171 | } |
172 | |
173 | /** |
174 | * Get the last matched table if the last match was a table. |
175 | * |
176 | * @return the last table or null |
177 | */ |
178 | public DbTableOrView getLastMatchedTable() { |
179 | return lastMatchedTable; |
180 | } |
181 | |
182 | /** |
183 | * Set the query string. |
184 | * |
185 | * @param query the query string |
186 | */ |
187 | public void setQuery(String query) { |
188 | if (!StringUtils.equals(this.query, query)) { |
189 | this.query = query; |
190 | this.queryUpper = StringUtils.toUpperEnglish(query); |
191 | } |
192 | } |
193 | |
194 | /** |
195 | * Get the query string. |
196 | * |
197 | * @return the query |
198 | */ |
199 | public String getQuery() { |
200 | return query; |
201 | } |
202 | |
203 | /** |
204 | * Get the uppercase version of the query string. |
205 | * |
206 | * @return the uppercase query |
207 | */ |
208 | public String getQueryUpper() { |
209 | return queryUpper; |
210 | } |
211 | |
212 | /** |
213 | * Get the map of next tokens. |
214 | * |
215 | * @return the next token map |
216 | */ |
217 | public HashMap<String, String> getNext() { |
218 | return next; |
219 | } |
220 | |
221 | } |