blob: 9f2f70a4a0a0e5f582a1d4cee2a513f56fca23d6 [file] [log] [blame]
margarethab097fb02021-02-22 19:28:33 +01001package de.ids_mannheim.korap.dao;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.HashSet;
6import java.util.List;
7import java.util.Set;
8
margaretha340d06a2024-07-25 12:14:42 +02009import org.springframework.stereotype.Repository;
10import org.springframework.transaction.annotation.Transactional;
11
margaretha340d06a2024-07-25 12:14:42 +020012import de.ids_mannheim.korap.constant.QueryType;
13import de.ids_mannheim.korap.constant.ResourceType;
margaretha340d06a2024-07-25 12:14:42 +020014import de.ids_mannheim.korap.entity.QueryDO;
15import de.ids_mannheim.korap.entity.QueryDO_;
16import de.ids_mannheim.korap.entity.Role;
17import de.ids_mannheim.korap.entity.Role_;
margaretha340d06a2024-07-25 12:14:42 +020018import de.ids_mannheim.korap.entity.UserGroupMember;
19import de.ids_mannheim.korap.entity.UserGroupMember_;
20import de.ids_mannheim.korap.entity.UserGroup_;
21import de.ids_mannheim.korap.exceptions.KustvaktException;
22import de.ids_mannheim.korap.exceptions.StatusCodes;
23import de.ids_mannheim.korap.user.User.CorpusAccess;
24import de.ids_mannheim.korap.utils.ParameterChecker;
margaretha6e796842023-08-17 15:10:45 +020025import jakarta.persistence.EntityManager;
26import jakarta.persistence.NoResultException;
27import jakarta.persistence.NonUniqueResultException;
28import jakarta.persistence.PersistenceContext;
29import jakarta.persistence.Query;
30import jakarta.persistence.TypedQuery;
31import jakarta.persistence.criteria.CriteriaBuilder;
32import jakarta.persistence.criteria.CriteriaQuery;
33import jakarta.persistence.criteria.Join;
34import jakarta.persistence.criteria.Predicate;
35import jakarta.persistence.criteria.Root;
margarethab097fb02021-02-22 19:28:33 +010036
margarethab097fb02021-02-22 19:28:33 +010037/**
38 * QueryDao manages database queries and transactions
margaretha89bd8f52021-02-26 17:08:01 +010039 * regarding virtual corpus and KorAP queries.
margarethab097fb02021-02-22 19:28:33 +010040 *
41 * @author margaretha
42 *
43 */
44@Transactional
45@Repository
46public class QueryDao {
47
48 @PersistenceContext
49 private EntityManager entityManager;
50
margaretha35e1ca22023-11-16 22:00:01 +010051 public int createQuery (String name, ResourceType type, QueryType queryType,
52 CorpusAccess requiredAccess, String koralQuery, String definition,
53 String description, String status, boolean isCached,
54 String createdBy, String query, String queryLanguage)
55 throws KustvaktException {
margarethab097fb02021-02-22 19:28:33 +010056
57 QueryDO q = new QueryDO();
58 q.setName(name);
59 q.setType(type);
60 q.setQueryType(queryType);
61 q.setRequiredAccess(requiredAccess);
62 q.setKoralQuery(koralQuery);
63 q.setDefinition(definition);
64 q.setDescription(description);
65 q.setStatus(status);
66 q.setCreatedBy(createdBy);
67 q.setCached(isCached);
68 q.setQuery(query);
69 q.setQueryLanguage(queryLanguage);
70
71 entityManager.persist(q);
72 return q.getId();
73 }
74
margaretha1703c162021-08-13 17:13:42 +020075 public void editQuery (QueryDO queryDO, String name, ResourceType type,
76 CorpusAccess requiredAccess, String koralQuery, String definition,
77 String description, String status, boolean isCached,
78 String queryStr, String queryLanguage) throws KustvaktException {
margarethab097fb02021-02-22 19:28:33 +010079
80 if (name != null && !name.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +020081 queryDO.setName(name);
margarethab097fb02021-02-22 19:28:33 +010082 }
83 if (type != null) {
margaretha1703c162021-08-13 17:13:42 +020084 queryDO.setType(type);
margarethab097fb02021-02-22 19:28:33 +010085 }
86 if (requiredAccess != null) {
margaretha1703c162021-08-13 17:13:42 +020087 queryDO.setRequiredAccess(requiredAccess);
margarethab097fb02021-02-22 19:28:33 +010088 }
89 if (koralQuery != null) {
margaretha1703c162021-08-13 17:13:42 +020090 queryDO.setKoralQuery(koralQuery);
margarethab097fb02021-02-22 19:28:33 +010091 }
92 if (definition != null && !definition.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +020093 queryDO.setDefinition(definition);
margarethab097fb02021-02-22 19:28:33 +010094 }
95 if (description != null && !description.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +020096 queryDO.setDescription(description);
margarethab097fb02021-02-22 19:28:33 +010097 }
98 if (status != null && !status.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +020099 queryDO.setStatus(status);
margarethab097fb02021-02-22 19:28:33 +0100100 }
margaretha35e1ca22023-11-16 22:00:01 +0100101 if (queryStr != null && !queryStr.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +0200102 queryDO.setQuery(queryStr);
103 }
margaretha35e1ca22023-11-16 22:00:01 +0100104 if (queryLanguage != null && !queryLanguage.isEmpty()) {
margaretha1703c162021-08-13 17:13:42 +0200105 queryDO.setQueryLanguage(queryLanguage);
106 }
107 queryDO.setCached(isCached);
108 entityManager.merge(queryDO);
margarethab097fb02021-02-22 19:28:33 +0100109 }
110
margaretha35e1ca22023-11-16 22:00:01 +0100111 public void deleteQuery (QueryDO query) throws KustvaktException {
margarethab097fb02021-02-22 19:28:33 +0100112 if (!entityManager.contains(query)) {
113 query = entityManager.merge(query);
114 }
115 entityManager.remove(query);
116
117 }
118
119 /**
120 * System admin function.
121 *
122 * Retrieves queries by creator and type. If type is not
123 * specified, retrieves queries of all types. If createdBy is not
124 * specified, retrieves queries of all users.
125 *
126 * @param type
127 * {@link ResourceType}
128 * @param createdBy
129 * username of the query creator
130 * @return a list of {@link Query}
131 * @throws KustvaktException
132 */
133 @SuppressWarnings("unchecked")
134 public List<QueryDO> retrieveQueryByType (ResourceType type,
135 String createdBy, QueryType queryType) throws KustvaktException {
136
137 CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100138 CriteriaQuery<QueryDO> criteriaQuery = criteriaBuilder
139 .createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100140 Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
141
142 Predicate conditions = criteriaBuilder
143 .equal(query.get(QueryDO_.queryType), queryType);
144 if (createdBy != null && !createdBy.isEmpty()) {
margaretha35e1ca22023-11-16 22:00:01 +0100145 conditions = criteriaBuilder.and(conditions, criteriaBuilder
146 .equal(query.get(QueryDO_.createdBy), createdBy));
margarethab097fb02021-02-22 19:28:33 +0100147 if (type != null) {
margaretha35e1ca22023-11-16 22:00:01 +0100148 conditions = criteriaBuilder.and(conditions,
149 criteriaBuilder.equal(query.get(QueryDO_.type), type));
margarethab097fb02021-02-22 19:28:33 +0100150 }
151 }
152 else if (type != null) {
margaretha35e1ca22023-11-16 22:00:01 +0100153 conditions = criteriaBuilder.and(conditions,
154 criteriaBuilder.equal(query.get(QueryDO_.type), type));
margarethab097fb02021-02-22 19:28:33 +0100155 }
156
157 criteriaQuery.select(query);
158 criteriaQuery.where(conditions);
159 Query q = entityManager.createQuery(criteriaQuery);
160 return q.getResultList();
161 }
162
163 public QueryDO retrieveQueryById (int id) throws KustvaktException {
164 ParameterChecker.checkIntegerValue(id, "id");
165
166 CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100167 CriteriaQuery<QueryDO> criteriaQuery = criteriaBuilder
168 .createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100169 Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
170 criteriaQuery.select(query);
margaretha35e1ca22023-11-16 22:00:01 +0100171 criteriaQuery.where(criteriaBuilder.equal(query.get(QueryDO_.id), id));
margarethab097fb02021-02-22 19:28:33 +0100172
173 QueryDO qe = null;
174 try {
175 Query q = entityManager.createQuery(criteriaQuery);
176 qe = (QueryDO) q.getSingleResult();
177 }
178 catch (NoResultException e) {
179 throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
180 "Query with id: " + id + " is not found",
181 String.valueOf(id), e);
182 }
183 return qe;
184 }
185
186 public QueryDO retrieveQueryByName (String queryName, String createdBy)
187 throws KustvaktException {
188 ParameterChecker.checkStringValue(createdBy, "createdBy");
189 ParameterChecker.checkStringValue(queryName, "queryName");
190
191 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100192 CriteriaQuery<QueryDO> criteriaQuery = builder
193 .createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100194
195 Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
196
197 Predicate condition = builder.and(
margaretha35e1ca22023-11-16 22:00:01 +0100198 builder.equal(query.get(QueryDO_.createdBy), createdBy),
margarethab097fb02021-02-22 19:28:33 +0100199 builder.equal(query.get(QueryDO_.name), queryName));
200
201 criteriaQuery.select(query);
202 criteriaQuery.where(condition);
203
204 Query q = entityManager.createQuery(criteriaQuery);
205 QueryDO qe = null;
206 try {
207 qe = (QueryDO) q.getSingleResult();
208 }
209 catch (NoResultException e) {
210 return null;
211 }
212 catch (NonUniqueResultException e) {
213 String code = createdBy + "/" + queryName;
214 throw new KustvaktException(StatusCodes.NON_UNIQUE_RESULT_FOUND,
215 "Non unique result found for query: retrieve query by name "
216 + code,
217 String.valueOf(code), e);
218 }
219 return qe;
220 }
221
222 @SuppressWarnings("unchecked")
margaretha35e1ca22023-11-16 22:00:01 +0100223 public List<QueryDO> retrieveOwnerQuery (String userId, QueryType queryType)
224 throws KustvaktException {
margarethab097fb02021-02-22 19:28:33 +0100225 ParameterChecker.checkStringValue(userId, "userId");
226
227 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100228 CriteriaQuery<QueryDO> cq = builder.createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100229
230 Root<QueryDO> query = cq.from(QueryDO.class);
231 Predicate conditions = builder.and(
margaretha35e1ca22023-11-16 22:00:01 +0100232 builder.equal(query.get(QueryDO_.createdBy), userId),
233 builder.equal(query.get(QueryDO_.queryType), queryType));
margarethab097fb02021-02-22 19:28:33 +0100234
235 cq.select(query);
236 cq.where(conditions);
237
238 Query q = entityManager.createQuery(cq);
239 return q.getResultList();
240 }
241
242 @SuppressWarnings("unchecked")
243 public List<QueryDO> retrieveOwnerQueryByType (String userId,
244 ResourceType type) throws KustvaktException {
245 ParameterChecker.checkStringValue(userId, "userId");
246
247 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100248 CriteriaQuery<QueryDO> cq = builder.createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100249
250 Root<QueryDO> query = cq.from(QueryDO.class);
251 cq.select(query);
252
253 Predicate p = builder.and(
margaretha35e1ca22023-11-16 22:00:01 +0100254 builder.equal(query.get(QueryDO_.createdBy), userId),
margarethab097fb02021-02-22 19:28:33 +0100255 builder.equal(query.get(QueryDO_.type), type));
256 cq.where(p);
257
258 Query q = entityManager.createQuery(cq);
259 return q.getResultList();
260 }
261
262 @SuppressWarnings("unchecked")
margaretha35e1ca22023-11-16 22:00:01 +0100263 public List<QueryDO> retrieveGroupQueryByUser (String userId,
264 QueryType queryType) throws KustvaktException {
margarethab097fb02021-02-22 19:28:33 +0100265 ParameterChecker.checkStringValue(userId, "userId");
266
267 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100268 CriteriaQuery<QueryDO> cq = builder.createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100269
270 Root<QueryDO> query = cq.from(QueryDO.class);
margaretha340d06a2024-07-25 12:14:42 +0200271 Join<QueryDO, Role> roles = query.join(QueryDO_.roles);
272 Join<Role, UserGroupMember> members = roles
273 .join(Role_.userGroupMembers);
274
margaretha35e1ca22023-11-16 22:00:01 +0100275 Predicate type = builder.equal(query.get(QueryDO_.queryType),
276 queryType);
margaretha35e1ca22023-11-16 22:00:01 +0100277 Predicate user = builder.equal(members.get(UserGroupMember_.userId),
278 userId);
margarethab097fb02021-02-22 19:28:33 +0100279
280 cq.select(query);
margarethaeb328d72024-08-16 11:11:44 +0200281 cq.where(builder.and(type, user));
margarethab097fb02021-02-22 19:28:33 +0100282
283 Query q = entityManager.createQuery(cq);
284 return q.getResultList();
285 }
286
287 public List<QueryDO> retrieveQueryByUser (String userId,
288 QueryType queryType) throws KustvaktException {
289 ParameterChecker.checkStringValue(userId, "userId");
290 ParameterChecker.checkObjectValue(queryType, "queryType");
291
292 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100293 CriteriaQuery<QueryDO> criteriaQuery = builder
294 .createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100295
296 Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
297 Predicate predicate = builder.and(
margaretha35e1ca22023-11-16 22:00:01 +0100298 builder.equal(query.get(QueryDO_.queryType), queryType),
299 builder.or(builder.equal(query.get(QueryDO_.createdBy), userId),
margarethab097fb02021-02-22 19:28:33 +0100300 builder.equal(query.get(QueryDO_.type),
301 ResourceType.SYSTEM)));
302
303 criteriaQuery.select(query);
304 criteriaQuery.where(predicate);
305 criteriaQuery.distinct(true);
306 Query q = entityManager.createQuery(criteriaQuery);
307
308 @SuppressWarnings("unchecked")
309 List<QueryDO> queryList = q.getResultList();
310 List<QueryDO> groupQuery = retrieveGroupQueryByUser(userId, queryType);
311 Set<QueryDO> querySet = new HashSet<QueryDO>();
312 querySet.addAll(queryList);
313 querySet.addAll(groupQuery);
314
315 List<QueryDO> merger = new ArrayList<QueryDO>(querySet.size());
316 merger.addAll(querySet);
317 Collections.sort(merger);
318 return merger;
319 }
320
321 // for admins
322 @SuppressWarnings("unchecked")
323 public List<QueryDO> retrieveQueryByGroup (int groupId)
324 throws KustvaktException {
325 ParameterChecker.checkIntegerValue(groupId, "groupId");
326
327 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
margaretha35e1ca22023-11-16 22:00:01 +0100328 CriteriaQuery<QueryDO> criteriaQuery = builder
329 .createQuery(QueryDO.class);
margarethab097fb02021-02-22 19:28:33 +0100330
331 Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
margaretha340d06a2024-07-25 12:14:42 +0200332 Join<QueryDO, Role> query_role = query
333 .join(QueryDO_.roles);
margarethab097fb02021-02-22 19:28:33 +0100334
335 criteriaQuery.select(query);
margaretha340d06a2024-07-25 12:14:42 +0200336 criteriaQuery.where(builder.equal(
337 query_role.get(Role_.userGroup).get(UserGroup_.id), groupId));
margarethab097fb02021-02-22 19:28:33 +0100338 Query q = entityManager.createQuery(criteriaQuery);
339 return q.getResultList();
340 }
341
margaretha9e73c0e2023-05-05 16:51:49 +0200342 public Long countNumberOfQuery (String userId, QueryType queryType)
343 throws KustvaktException {
344 ParameterChecker.checkStringValue(userId, "userId");
345 ParameterChecker.checkObjectValue(queryType, "queryType");
346
347 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
348 CriteriaQuery<Long> cq = builder.createQuery(Long.class);
349
350 Root<QueryDO> query = cq.from(QueryDO.class);
351 Predicate conditions = builder.and(
352 builder.equal(query.get(QueryDO_.createdBy), userId),
353 builder.equal(query.get(QueryDO_.queryType), queryType));
354
355 cq.select(builder.count(query));
356 cq.where(conditions);
357
358 TypedQuery<Long> q = entityManager.createQuery(cq);
359 return q.getSingleResult();
360 }
361
margarethab097fb02021-02-22 19:28:33 +0100362}