File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\server\web\DbContextRule.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.server.web;
8
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import org.h2.bnf.BnfVisitor;
12 import org.h2.bnf.Rule;
13 import org.h2.bnf.RuleHead;
14 import org.h2.bnf.Sentence;
15 import org.h2.command.Parser;
16 import org.h2.message.DbException;
17 import org.h2.util.StringUtils;
18
19 /**
20 * A BNF terminal rule that is linked to the database context information.
21 * This class is used by the H2 Console, to support auto-complete.
22 */
23 public class DbContextRule implements Rule {
24
25 static final int COLUMN = 0, TABLE = 1, TABLE_ALIAS = 2;
26 static final int NEW_TABLE_ALIAS = 3;
27 static final int COLUMN_ALIAS = 4, SCHEMA = 5;
28
29 private final DbContents contents;
30 private final int type;
31
32 DbContextRule(DbContents contents, int type) {
33 this.contents = contents;
34 this.type = type;
35 }
36
37 public void setLinks(HashMap<String, RuleHead> ruleMap) {
38 // nothing to do
39 }
40
41 public void accept(BnfVisitor visitor) {
42 // nothing to do
43 }
44
45 public boolean autoComplete(Sentence sentence) {
46 String query = sentence.getQuery(), s = query;
47 String up = sentence.getQueryUpper();
48 switch (type) {
49 case SCHEMA: {
50 DbSchema[] schemas = contents.schemas;
51 String best = null;
52 DbSchema bestSchema = null;
53 for (DbSchema schema: schemas) {
54 String name = StringUtils.toUpperEnglish(schema.name);
55 if (up.startsWith(name)) {
56 if (best == null || name.length() > best.length()) {
57 best = name;
58 bestSchema = schema;
59 }
60 } else if (s.length() == 0 || name.startsWith(up)) {
61 if (s.length() < name.length()) {
62 sentence.add(name, name.substring(s.length()), type);
63 sentence.add(schema.quotedName + ".", schema.quotedName.substring(s.length()) + ".", Sentence.CONTEXT);
64 }
65 }
66 }
67 if (best != null) {
68 sentence.setLastMatchedSchema(bestSchema);
69 s = s.substring(best.length());
70 }
71 break;
72 }
73 case TABLE: {
74 DbSchema schema = sentence.getLastMatchedSchema();
75 if (schema == null) {
76 schema = contents.defaultSchema;
77 }
78 DbTableOrView[] tables = schema.tables;
79 String best = null;
80 DbTableOrView bestTable = null;
81 for (DbTableOrView table : tables) {
82 String compare = up;
83 String name = StringUtils.toUpperEnglish(table.name);
84 if (table.quotedName.length() > name.length()) {
85 name = table.quotedName;
86 compare = query;
87 }
88 if (compare.startsWith(name)) {
89 if (best == null || name.length() > best.length()) {
90 best = name;
91 bestTable = table;
92 }
93 } else if (s.length() == 0 || name.startsWith(compare)) {
94 if (s.length() < name.length()) {
95 sentence.add(table.quotedName, table.quotedName.substring(s.length()), Sentence.CONTEXT);
96 }
97 }
98 }
99 if (best != null) {
100 sentence.setLastMatchedTable(bestTable);
101 sentence.addTable(bestTable);
102 s = s.substring(best.length());
103 }
104 break;
105 }
106 case NEW_TABLE_ALIAS:
107 s = autoCompleteTableAlias(sentence, true);
108 break;
109 case TABLE_ALIAS:
110 s = autoCompleteTableAlias(sentence, false);
111 break;
112 case COLUMN_ALIAS: {
113 int i = 0;
114 if (query.indexOf(' ') < 0) {
115 break;
116 }
117 for (; i < up.length(); i++) {
118 char ch = up.charAt(i);
119 if (ch != '_' && !Character.isLetterOrDigit(ch)) {
120 break;
121 }
122 }
123 if (i == 0) {
124 break;
125 }
126 String alias = up.substring(0, i);
127 if (Parser.isKeyword(alias, true)) {
128 break;
129 }
130 s = s.substring(alias.length());
131 break;
132 }
133 case COLUMN: {
134 HashSet<DbTableOrView> set = sentence.getTables();
135 String best = null;
136 DbTableOrView last = sentence.getLastMatchedTable();
137 if (last != null && last.columns != null) {
138 for (DbColumn column : last.columns) {
139 String compare = up;
140 String name = StringUtils.toUpperEnglish(column.name);
141 if (column.quotedName.length() > name.length()) {
142 name = column.quotedName;
143 compare = query;
144 }
145 if (compare.startsWith(name)) {
146 String b = s.substring(name.length());
147 if (best == null || b.length() < best.length()) {
148 best = b;
149 } else if (s.length() == 0 || name.startsWith(compare)) {
150 if (s.length() < name.length()) {
151 sentence.add(column.name, column.name.substring(s.length()), Sentence.CONTEXT);
152 }
153 }
154 }
155 }
156 }
157 for (DbSchema schema : contents.schemas) {
158 for (DbTableOrView table : schema.tables) {
159 if (table != last && set != null && !set.contains(table)) {
160 continue;
161 }
162 if (table == null || table.columns == null) {
163 continue;
164 }
165 for (DbColumn column : table.columns) {
166 String name = StringUtils.toUpperEnglish(column.name);
167 if (up.startsWith(name)) {
168 String b = s.substring(name.length());
169 if (best == null || b.length() < best.length()) {
170 best = b;
171 }
172 } else if (s.length() == 0 || name.startsWith(up)) {
173 if (s.length() < name.length()) {
174 sentence.add(column.name, column.name.substring(s.length()), Sentence.CONTEXT);
175 }
176 }
177 }
178 }
179 }
180 if (best != null) {
181 s = best;
182 }
183 break;
184 }
185 default:
186 throw DbException.throwInternalError("type=" + type);
187 }
188 if (!s.equals(query)) {
189 while (s.length() > 0 && Character.isSpaceChar(s.charAt(0))) {
190 s = s.substring(1);
191 }
192 sentence.setQuery(s);
193 return true;
194 }
195 return false;
196 }
197
198 private static String autoCompleteTableAlias(Sentence sentence, boolean newAlias) {
199 String s = sentence.getQuery();
200 String up = sentence.getQueryUpper();
201 int i = 0;
202 for (; i < up.length(); i++) {
203 char ch = up.charAt(i);
204 if (ch != '_' && !Character.isLetterOrDigit(ch)) {
205 break;
206 }
207 }
208 if (i == 0) {
209 return s;
210 }
211 String alias = up.substring(0, i);
212 if ("SET".equals(alias) || Parser.isKeyword(alias, true)) {
213 return s;
214 }
215 if (newAlias) {
216 sentence.addAlias(alias, sentence.getLastTable());
217 }
218 HashMap<String, DbTableOrView> map = sentence.getAliases();
219 if ((map != null && map.containsKey(alias)) || (sentence.getLastTable() == null)) {
220 if (newAlias && s.length() == alias.length()) {
221 return s;
222 }
223 s = s.substring(alias.length());
224 if (s.length() == 0) {
225 sentence.add(alias + ".", ".", Sentence.CONTEXT);
226 }
227 return s;
228 }
229 HashSet<DbTableOrView> tables = sentence.getTables();
230 if (tables != null) {
231 String best = null;
232 for (DbTableOrView table : tables) {
233 String tableName = StringUtils.toUpperEnglish(table.name);
234 if (alias.startsWith(tableName) && (best == null || tableName.length() > best.length())) {
235 sentence.setLastMatchedTable(table);
236 best = tableName;
237 } else if (s.length() == 0 || tableName.startsWith(alias)) {
238 sentence.add(tableName + ".", tableName.substring(s.length()) + ".", Sentence.CONTEXT);
239 }
240 }
241 if (best != null) {
242 s = s.substring(best.length());
243 if (s.length() == 0) {
244 sentence.add(alias + ".", ".", Sentence.CONTEXT);
245 }
246 return s;
247 }
248 }
249 return s;
250 }
251
252 }
253