Skip to content

Method: setMaxResults(int)

1: /**
2: * Copyright (C) 2016 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jopa.model;
14:
15: import cz.cvut.kbss.jopa.exceptions.NoResultException;
16: import cz.cvut.kbss.jopa.exceptions.NoUniqueResultException;
17: import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
18: import cz.cvut.kbss.jopa.model.query.Parameter;
19: import cz.cvut.kbss.jopa.model.query.Query;
20: import cz.cvut.kbss.jopa.query.QueryHolder;
21: import cz.cvut.kbss.jopa.sessions.ConnectionWrapper;
22: import cz.cvut.kbss.jopa.utils.ErrorUtils;
23: import cz.cvut.kbss.ontodriver.ResultSet;
24: import cz.cvut.kbss.ontodriver.Statement;
25: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
26:
27: import java.net.URI;
28: import java.util.*;
29:
30: public class QueryImpl implements Query {
31:
32: private final QueryHolder query;
33: private final Set<URI> contexts;
34: private final ConnectionWrapper connection;
35:
36: private int maxResults;
37: private boolean useBackupOntology;
38:
39: public QueryImpl(final QueryHolder query, final ConnectionWrapper connection) {
40: this.query = Objects.requireNonNull(query, ErrorUtils.constructNPXMessage("query"));
41: this.connection = Objects.requireNonNull(connection,
42: ErrorUtils.constructNPXMessage("connection"));
43: this.contexts = new HashSet<>();
44: this.useBackupOntology = false;
45: this.maxResults = Integer.MAX_VALUE;
46: }
47:
48: @Override
49: public List getResultList() {
50: try {
51: if (maxResults == 0) {
52: return Collections.emptyList();
53: }
54: return getResultListImpl(maxResults);
55: } catch (OntoDriverException e) {
56: throw queryEvaluationException(e);
57: }
58: }
59:
60: private OWLPersistenceException queryEvaluationException(OntoDriverException e) {
61: final String executedQuery = query.assembleQuery();
62: return new OWLPersistenceException("Exception caught when evaluating query " + executedQuery, e);
63: }
64:
65: @Override
66: public Object getSingleResult() {
67: try {
68: // Call it with maxResults = 2 just to see whether there are more
69: final List<?> list = getResultListImpl(2);
70: if (list.isEmpty()) {
71: throw new NoResultException("No result found for query " + query);
72: }
73: if (list.size() > 1) {
74: throw new NoUniqueResultException("Multiple results found for query " + query);
75: }
76: return list.get(0);
77: } catch (OntoDriverException e) {
78: throw queryEvaluationException(e);
79: }
80: }
81:
82: @Override
83: public int getMaxResults() {
84: return maxResults;
85: }
86:
87: @Override
88: public Parameter<?> getParameter(int position) {
89: return query.getParameter(position);
90: }
91:
92: @Override
93: public Parameter<?> getParameter(String name) {
94: return query.getParameter(name);
95: }
96:
97: @Override
98: public Set<Parameter<?>> getParameters() {
99: return query.getParameters();
100: }
101:
102: @Override
103: public boolean isBound(Parameter<?> parameter) {
104: return query.getParameterValue(parameter) != null;
105: }
106:
107: @Override
108: public Object getParameterValue(int position) {
109: final Parameter<?> param = query.getParameter(position);
110: return getParameterValue(param);
111: }
112:
113: @Override
114: public Object getParameterValue(String name) {
115: final Parameter<?> param = query.getParameter(name);
116: return getParameterValue(param);
117: }
118:
119: private IllegalStateException unboundParam(Object param) {
120: return new IllegalStateException("Parameter " + param + " is not bound.");
121: }
122:
123: @Override
124: public <T> T getParameterValue(Parameter<T> parameter) {
125: if (!isBound(parameter)) {
126: throw unboundParam(parameter);
127: }
128: return (T) query.getParameterValue(parameter);
129: }
130:
131: @Override
132: public Query setParameter(int position, Object value) {
133: query.setParameter(query.getParameter(position), value);
134: return this;
135: }
136:
137: @Override
138: public Query setParameter(int position, String value, String language) {
139: query.setParameter(query.getParameter(position), value, language);
140: return this;
141: }
142:
143: @Override
144: public Query setParameter(String name, Object value) {
145: query.setParameter(query.getParameter(name), value);
146: return this;
147: }
148:
149: @Override
150: public Query setParameter(String name, String value, String language) {
151: query.setParameter(query.getParameter(name), value, language);
152: return this;
153: }
154:
155: @Override
156: public <T> Query setParameter(Parameter<T> parameter, T value) {
157: query.setParameter(parameter, value);
158: return this;
159: }
160:
161: @Override
162: public Query setParameter(Parameter<String> parameter, String value, String language) {
163: query.setParameter(parameter, value, language);
164: return this;
165: }
166:
167: @Override
168: public Query setMaxResults(int maxResults) {
169:• if (maxResults < 0) {
170: throw new IllegalArgumentException(
171: "Cannot set maximum number of results to less than 0.");
172: }
173: this.maxResults = maxResults;
174: return this;
175: }
176:
177: /**
178: * Sets ontology used for processing of this query. </p>
179: *
180: * @param useBackupOntology If true, the backup (central) ontology is used, otherwise the transactional ontology is
181: * used (default)
182: */
183: public void setUseBackupOntology(boolean useBackupOntology) {
184: this.useBackupOntology = useBackupOntology;
185: }
186:
187: private List<?> getResultListImpl(int maxResults) throws OntoDriverException {
188: assert maxResults > 0;
189:
190: final Statement stmt = connection.createStatement();
191: setTargetOntology(stmt);
192: URI[] uris = new URI[contexts.size()];
193: uris = contexts.toArray(uris);
194: try (ResultSet rs = stmt.executeQuery(query.assembleQuery(), uris)) {
195: final int columnCount = rs.getColumnCount();
196: int cnt = 0;
197: final List<Object> res = new ArrayList<>();
198: // TODO register this as observer on the result set so that additional results can be loaded asynchronously
199: while (rs.hasNext() && cnt < maxResults) {
200: rs.next();
201: if (columnCount == 1) {
202: res.add(rs.getObject(0));
203: } else {
204: res.add(extractResultRow(rs, columnCount));
205: }
206: cnt++;
207: }
208: return res;
209: }
210: }
211:
212: private void setTargetOntology(Statement stmt) {
213: if (useBackupOntology) {
214: stmt.useOntology(Statement.StatementOntology.CENTRAL);
215: } else {
216: stmt.useOntology(Statement.StatementOntology.TRANSACTIONAL);
217: }
218: }
219:
220: private Object[] extractResultRow(ResultSet rs, int columnCount) throws OntoDriverException {
221: final Object[] row = new Object[columnCount];
222: for (int i = 0; i < columnCount; i++) {
223: final Object ob = rs.getObject(i);
224: row[i] = ob;
225: }
226: return row;
227: }
228:
229: @Override
230: public Query addContext(URI context) {
231: Objects.requireNonNull(context, ErrorUtils.constructNPXMessage("context"));
232: contexts.add(context);
233: return this;
234: }
235:
236: @Override
237: public Query addContexts(Collection<URI> contexts) {
238: Objects.requireNonNull(contexts, ErrorUtils.constructNPXMessage("contexts"));
239: this.contexts.addAll(contexts);
240: return this;
241: }
242:
243: @Override
244: public Query clearContexts() {
245: contexts.clear();
246: return this;
247: }
248: }