1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.ontotext.ordi.mapper.rdbms;
19
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.eclipse.datatools.modelbase.sql.query.PredicateLike;
26 import org.eclipse.datatools.modelbase.sql.query.QueryExpressionBody;
27 import org.eclipse.datatools.modelbase.sql.query.QuerySearchCondition;
28 import org.eclipse.datatools.modelbase.sql.query.QuerySelect;
29 import org.eclipse.datatools.modelbase.sql.query.QuerySelectStatement;
30 import org.eclipse.datatools.modelbase.sql.query.QueryStatement;
31 import org.eclipse.datatools.modelbase.sql.query.ResultColumn;
32 import org.eclipse.datatools.modelbase.sql.query.SQLQueryModelFactory;
33 import org.eclipse.datatools.modelbase.sql.query.SearchConditionCombined;
34 import org.eclipse.datatools.modelbase.sql.query.SearchConditionCombinedOperator;
35 import org.eclipse.datatools.modelbase.sql.query.ValueExpressionColumn;
36 import org.eclipse.datatools.modelbase.sql.query.ValueExpressionVariable;
37 import org.eclipse.datatools.modelbase.sql.query.helper.StatementHelper;
38 import org.eclipse.datatools.sqltools.parsers.sql.SQLParseErrorInfo;
39 import org.eclipse.datatools.sqltools.parsers.sql.SQLParserException;
40 import org.eclipse.datatools.sqltools.parsers.sql.SQLParserInternalException;
41 import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParseResult;
42 import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParserManager;
43 import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParserManagerProvider;
44 import org.eclipse.emf.common.util.EList;
45
46 import com.ontotext.ordi.exception.ORDIRuntimeException;
47 import com.ontotext.ordi.mapper.exceptions.IllegalQueryFormatException;
48
49 public class SqlGenerator {
50
51 private QuerySelectStatement query;
52 private ResultColumn subjectColumn;
53 private ResultColumn objectColumn;
54 private String sqlQuery;
55 private Map<Integer, String> generatedQueries;
56
57 public SqlGenerator(String sqlQuery) {
58 if (sqlQuery == null) {
59 throw new IllegalArgumentException();
60 }
61 this.sqlQuery = sqlQuery;
62 }
63
64 public String generateSQL(boolean hasSubject, boolean hasObject) {
65 if (query == null) {
66 validate();
67 }
68 if (generatedQueries == null) {
69 generateAllVariations();
70 }
71 int type = 0;
72 if (hasSubject)
73 type = type ^ 1;
74 if (hasObject)
75 type = type << 1 ^ 1;
76 return generatedQueries.get(type);
77 }
78
79 /**
80 * Checks whether the query is valid SQL select query with two columns.
81 */
82 @SuppressWarnings("unchecked")
83 public void validate() {
84 try {
85 SQLQueryParserManager parserManager = SQLQueryParserManagerProvider
86 .getInstance().getParserManager(null, null);
87 SQLQueryParseResult parseResult = parserManager
88 .parseQuery(sqlQuery);
89 QueryStatement queryStatement = parseResult.getQueryStatement();
90 if (queryStatement instanceof QuerySelectStatement) {
91 query = (QuerySelectStatement) queryStatement;
92 } else {
93 throw new IllegalQueryFormatException(String.format(
94 "Only select queries are allowed!\n%s", sqlQuery));
95 }
96 QuerySelect querySelect = null;
97 QueryExpressionBody queryBody = query.getQueryExpr().getQuery();
98 if (queryBody instanceof QuerySelect) {
99 querySelect = (QuerySelect) queryBody;
100 } else {
101 throw new IllegalQueryFormatException(String.format(
102 "Only single select queris are allowed!\n%s", sqlQuery));
103 }
104 EList resultColumns = querySelect.getSelectClause();
105 if (resultColumns.size() != 2) {
106 String msg = resultColumns.size() == 0 ? "Wildcards in select queries are not supported!"
107 : String.format(
108 "The query has only %d result columns:\n%s",
109 resultColumns, query.getSQL());
110 throw new IllegalQueryFormatException(msg);
111 }
112 subjectColumn = (ResultColumn) resultColumns.get(0);
113 objectColumn = (ResultColumn) resultColumns.get(1);
114 } catch (SQLParserException spe) {
115 List syntacticErrors = spe.getErrorInfoList();
116 Iterator itr = syntacticErrors.iterator();
117 StringBuffer buffer = new StringBuffer();
118 while (itr.hasNext()) {
119 SQLParseErrorInfo errorInfo = (SQLParseErrorInfo) itr.next();
120 buffer.append(String.format(
121 "Error at line %d position %d\nError mesage: %s\n",
122 errorInfo.getLineNumberStart(), errorInfo
123 .getColumnNumberStart(), errorInfo
124 .getParserErrorMessage()));
125 }
126 throw new IllegalQueryFormatException(buffer.toString(), spe);
127 } catch (SQLParserInternalException spie) {
128 throw new ORDIRuntimeException("An internal excpetion occured!",
129 spie);
130 }
131 }
132
133 protected PredicateLike generatePredicateLikeWihVariable(
134 ResultColumn resultColumn) {
135 PredicateLike like = SQLQueryModelFactory.eINSTANCE
136 .createPredicateLike();
137 ValueExpressionVariable variable = SQLQueryModelFactory.eINSTANCE
138 .createValueExpressionVariable();
139 ValueExpressionColumn column = StatementHelper
140 .createColumnExpression(resultColumn.getValueExpr().getName());
141 like.setNotLike(false);
142 like.setMatchingValueExpr(column);
143 like.setPatternValueExpr(variable);
144 return like;
145 }
146
147 /**
148 * This method generates all combinations between two independent args:
149 * argument 1: the existence of original where clause argument 2: the
150 * specification of subject or object clause
151 */
152 protected void generateAllVariations() {
153 if (query == null) {
154 validate();
155 }
156 generatedQueries = new HashMap<Integer, String>(5);
157
158
159 QuerySelect querySelect = (QuerySelect) subjectColumn.getContainer();
160 QuerySearchCondition originalWhere = querySelect.getWhereClause();
161 PredicateLike subjecWhere = generatePredicateLikeWihVariable(subjectColumn);
162 PredicateLike objectWhere = generatePredicateLikeWihVariable(objectColumn);
163 SearchConditionCombined combinedWhere = SQLQueryModelFactory.eINSTANCE
164 .createSearchConditionCombined();
165 combinedWhere
166 .setCombinedOperator(SearchConditionCombinedOperator.AND_LITERAL);
167 combinedWhere.setLeftCondition(subjecWhere);
168 combinedWhere
169 .setRightCondition(generatePredicateLikeWihVariable(objectColumn));
170 QuerySearchCondition newWhere = null;
171
172
173
174
175 for (int i = 0; i < 2 * 2; i++) {
176
177 if (i == 0) {
178
179 newWhere = originalWhere;
180
181 } else if (i == 1) {
182
183 if (originalWhere == null) {
184 newWhere = subjecWhere;
185 } else {
186 SearchConditionCombined combined = SQLQueryModelFactory.eINSTANCE
187 .createSearchConditionCombined();
188 combined.setLeftCondition(subjecWhere);
189 combined.setRightCondition(originalWhere);
190 newWhere = combined;
191 }
192
193 } else if (i == 2) {
194
195 if (originalWhere == null) {
196 newWhere = objectWhere;
197 } else {
198 SearchConditionCombined combined = SQLQueryModelFactory.eINSTANCE
199 .createSearchConditionCombined();
200 combined.setLeftCondition(objectWhere);
201 combined.setRightCondition(originalWhere);
202 newWhere = combined;
203 }
204
205 } else if (i == 3) {
206
207 if (originalWhere == null) {
208 SearchConditionCombined combined = SQLQueryModelFactory.eINSTANCE
209 .createSearchConditionCombined();
210 combined.setLeftCondition(subjecWhere);
211 combined.setRightCondition(objectWhere);
212 newWhere = combined;
213 } else {
214 SearchConditionCombined combinedInner = SQLQueryModelFactory.eINSTANCE
215 .createSearchConditionCombined();
216 combinedInner.setLeftCondition(subjecWhere);
217 combinedInner.setRightCondition(objectWhere);
218 SearchConditionCombined combined2 = SQLQueryModelFactory.eINSTANCE
219 .createSearchConditionCombined();
220 combined2.setLeftCondition(combinedInner);
221 combined2.setRightCondition(originalWhere);
222 newWhere = combined2;
223 }
224
225 }
226
227 querySelect.setWhereClause(newWhere);
228 generatedQueries.put(i, querySelect.getSQL());
229 }
230 }
231 }