1 package de.fhdw.wtf.persistence.facade;
2
3 import java.math.BigDecimal;
4 import java.math.BigInteger;
5 import java.sql.CallableStatement;
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.sql.Timestamp;
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.Date;
12 import java.util.HashSet;
13
14 import oracle.jdbc.OracleCallableStatement;
15 import oracle.jdbc.OracleTypes;
16 import de.fhdw.wtf.persistence.exception.BaseTypeNotFoundException;
17 import de.fhdw.wtf.persistence.exception.DuplicateEntryException;
18 import de.fhdw.wtf.persistence.exception.InvalidLinkException;
19 import de.fhdw.wtf.persistence.exception.NoValidTransactionException;
20 import de.fhdw.wtf.persistence.exception.NotInScopeException;
21 import de.fhdw.wtf.persistence.exception.NotInstantiatableException;
22 import de.fhdw.wtf.persistence.exception.ObjectNotFoundException;
23 import de.fhdw.wtf.persistence.exception.OtherSQLException;
24 import de.fhdw.wtf.persistence.exception.PersistenceException;
25 import de.fhdw.wtf.persistence.exception.ToManyObjectsException;
26 import de.fhdw.wtf.persistence.meta.AdhocTransaction;
27 import de.fhdw.wtf.persistence.meta.Association;
28 import de.fhdw.wtf.persistence.meta.IntegerValue;
29 import de.fhdw.wtf.persistence.meta.Link;
30 import de.fhdw.wtf.persistence.meta.MapAssociation;
31 import de.fhdw.wtf.persistence.meta.MapLink;
32 import de.fhdw.wtf.persistence.meta.Object;
33 import de.fhdw.wtf.persistence.meta.StringValue;
34 import de.fhdw.wtf.persistence.meta.Transaction;
35 import de.fhdw.wtf.persistence.meta.UnidirectionalAssociation;
36 import de.fhdw.wtf.persistence.meta.UnidirectionalLink;
37 import de.fhdw.wtf.persistence.meta.UserObject;
38 import de.fhdw.wtf.persistence.meta.UserType;
39 import de.fhdw.wtf.persistence.utils.DBConnectionIntegerHandler;
40 import de.fhdw.wtf.persistence.utils.DBConnectionObjectHandler;
41 import de.fhdw.wtf.persistence.utils.DBConnectionStringHandler;
42 import de.fhdw.wtf.persistence.utils.DBConnectionUserObjectHandler;
43 import de.fhdw.wtf.persistence.utils.IntegerConstants;
44 import de.fhdw.wtf.persistence.utils.StringConstants;
45 import de.fhdw.wtf.persistence.utils.Tuple;
46
47
48
49
50
51 public class OracleObjectFacadeImplementation implements ObjectFacade {
52
53 private static final String CALL_SUFFIX = " end;";
54
55 private static final String STORED_PROCEDURE_PREFIX = "begin ";
56
57 private static final String STORED_FUNCTION_PREFIX = "begin ? := ";
58
59
60
61
62 private final OracleDatabaseManager database;
63
64
65
66
67 private final TypeManager typeManager;
68
69
70
71
72
73
74
75
76
77 public OracleObjectFacadeImplementation(final OracleDatabaseManager database, final TypeManager typeManager) {
78 super();
79 this.database = database;
80 this.typeManager = typeManager;
81 IntegerValue.setObjectFacade(this);
82 StringValue.setObjectFacade(this);
83 }
84
85 @Override
86 public Collection<UserObject> find(final Association association, final String string, final Date date)
87 throws PersistenceException {
88 try (final CallableStatement call =
89 this.database.getConnection().prepareCall(
90 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.findString(?,?,?);"
91 + CALL_SUFFIX)) {
92 call.registerOutParameter(1, OracleTypes.CURSOR);
93 call.setLong(IntegerConstants.TWO, association.getId());
94 call.setString(IntegerConstants.THREE, string);
95 call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
96 call.execute();
97
98 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
99 final Collection<UserObject> result = new HashSet<>();
100 while (resultSet.next()) {
101 result.add(UserObject.init(
102 resultSet.getLong(1),
103 this.typeManager.getTypeForId(resultSet.getLong(2))));
104 }
105 return result;
106 }
107 } catch (final SQLException e) {
108 throw new OtherSQLException(e);
109 }
110 }
111
112 @Override
113 public Collection<UserObject> find(final Association association, final BigInteger integer, final Date date)
114 throws PersistenceException {
115 try (final CallableStatement call =
116 this.database.getConnection().prepareCall(
117 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.findInteger(?,?,?);"
118 + CALL_SUFFIX)) {
119 call.registerOutParameter(1, OracleTypes.CURSOR);
120 call.setLong(2, association.getId());
121 final BigDecimal wrapper = new BigDecimal(integer);
122 call.setBigDecimal(IntegerConstants.THREE, wrapper);
123 call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
124 call.execute();
125
126 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
127 final Collection<UserObject> result = new HashSet<>();
128 while (resultSet.next()) {
129 result.add(UserObject.init(
130 resultSet.getLong(1),
131 this.typeManager.getTypeForId(resultSet.getLong(2))));
132 }
133 return result;
134 }
135 } catch (final SQLException e) {
136 throw new OtherSQLException(e);
137 }
138 }
139
140 @Override
141 public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
142 final UnidirectionalAssociation association,
143 final Date date) throws PersistenceException {
144 try (final CallableStatement call =
145 this.database.getConnection().prepareCall(
146 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.get(?,?,?);"
147 + CALL_SUFFIX)) {
148 call.registerOutParameter(1, OracleTypes.CURSOR);
149 call.setLong(2, owner.getId());
150 call.setLong(IntegerConstants.THREE, association.getId());
151 call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
152 call.execute();
153
154 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
155 final Collection<Tuple<UnidirectionalLink, Object>> result = new ArrayList<>();
156 while (resultSet.next()) {
157 final Object target =
158 Object.checkForBaseTypes(
159 resultSet.getLong(3),
160 this.typeManager.getTypeForId(resultSet.getLong(4)));
161 result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
162 .getUnidirectionalAssociationForId(resultSet.getLong(2))), target));
163 }
164 return result;
165 }
166 } catch (final SQLException e) {
167 throw new OtherSQLException(e);
168 }
169 }
170
171 private Collection<Object> getWithKeyHelper(final UserObject owner,
172 final MapAssociation association,
173 final DBConnectionObjectHandler keyHandler,
174 final Date date) throws PersistenceException {
175 try (final CallableStatement call =
176 this.database.getConnection().prepareCall(
177 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + StringConstants.OBJECTFACADEGETMAP
178 + keyHandler.getObjectTypeString() + StringConstants.FOURQUESTIONMARKS + CALL_SUFFIX)) {
179 call.registerOutParameter(1, OracleTypes.CURSOR);
180 call.setLong(2, owner.getId());
181 call.setLong(IntegerConstants.THREE, association.getId());
182 keyHandler.handleCall(call, IntegerConstants.FOUR);
183 call.setTimestamp(IntegerConstants.FIVE, new Timestamp(date.getTime()));
184 call.execute();
185
186 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
187 final Collection<Object> result = new ArrayList<>();
188 while (resultSet.next()) {
189 if (!result.isEmpty()) {
190 throw new ToManyObjectsException();
191 }
192 final Object target =
193 Object.checkForBaseTypes(
194 resultSet.getLong(1),
195 this.typeManager.getTypeForId(resultSet.getLong(2)));
196 result.add(target);
197 }
198 if (result.isEmpty()) {
199 throw new ObjectNotFoundException();
200 }
201 return result;
202 }
203 } catch (final SQLException e) {
204 throw new OtherSQLException(e);
205 }
206 }
207
208 @Override
209 public Collection<Object> get(final UserObject owner,
210 final MapAssociation association,
211 final String key,
212 final Date date) throws PersistenceException {
213 return this.getWithKeyHelper(owner, association, new DBConnectionStringHandler(key), date);
214 }
215
216 @Override
217 public Collection<Object> get(final UserObject owner,
218 final MapAssociation association,
219 final BigInteger key,
220 final Date date) throws PersistenceException {
221 return this.getWithKeyHelper(owner, association, new DBConnectionIntegerHandler(key), date);
222 }
223
224 @Override
225 public Collection<Object> get(final UserObject owner,
226 final MapAssociation association,
227 final UserObject key,
228 final Date date) throws PersistenceException {
229 return this.getWithKeyHelper(owner, association, new DBConnectionUserObjectHandler(key), date);
230 }
231
232 @Override
233 public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
234 final UnidirectionalAssociation association,
235 final Date date) throws PersistenceException {
236 try (final CallableStatement call =
237 this.database.getConnection().prepareCall(
238 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.inverseGet(?,?,?);"
239 + CALL_SUFFIX)) {
240 call.registerOutParameter(1, OracleTypes.CURSOR);
241 call.setLong(2, target.getId());
242 call.setLong(IntegerConstants.THREE, association.getId());
243 call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
244 call.execute();
245
246 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
247 final Collection<Tuple<UnidirectionalLink, UserObject>> result = new ArrayList<>();
248 while (resultSet.next()) {
249 final UserObject owner =
250 UserObject.init(resultSet.getLong(3), this.typeManager.getTypeForId(resultSet.getLong(4)));
251 result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
252 .getUnidirectionalAssociationForId(resultSet.getLong(2))), owner));
253 }
254 return result;
255 }
256 } catch (final SQLException e) {
257 throw new OtherSQLException(e);
258 }
259 }
260
261 private Collection<Tuple<UserObject, Object>> inverseGetWithKeyHelper(final DBConnectionObjectHandler targetHandler,
262 final MapAssociation association,
263 final Date date) throws PersistenceException {
264 try (final CallableStatement call =
265 this.database.getConnection().prepareCall(
266 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
267 + StringConstants.OBJECTFACADEINVERSEGETMAP + targetHandler.getObjectTypeString()
268 + "(?,?,?);" + CALL_SUFFIX)) {
269 call.registerOutParameter(1, OracleTypes.CURSOR);
270 targetHandler.handleCall(call, 2);
271 call.setLong(IntegerConstants.THREE, association.getId());
272 call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
273 call.execute();
274
275 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
276 final Collection<Tuple<UserObject, Object>> owners = new ArrayList<>();
277 while (resultSet.next()) {
278 owners.add(new Tuple<>(UserObject.init(
279 resultSet.getLong(1),
280 this.typeManager.getTypeForId(resultSet.getLong(2))), Object.checkForBaseTypes(
281 resultSet.getLong(IntegerConstants.THREE),
282 this.typeManager.getTypeForId(resultSet.getLong(IntegerConstants.FOUR)))));
283 }
284 return owners;
285 }
286 } catch (final SQLException e) {
287 throw new OtherSQLException(e);
288 }
289 }
290
291 @Override
292 public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
293 final MapAssociation association,
294 final Date date) throws PersistenceException {
295 return this.inverseGetWithKeyHelper(new DBConnectionUserObjectHandler(target), association, date);
296 }
297
298 @Override
299 public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
300 final MapAssociation association,
301 final Date date) throws PersistenceException {
302 return this.inverseGetWithKeyHelper(new DBConnectionStringHandler(target), association, date);
303 }
304
305 @Override
306 public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
307 final MapAssociation association,
308 final Date date) throws PersistenceException {
309 return this.inverseGetWithKeyHelper(new DBConnectionIntegerHandler(target), association, date);
310 }
311
312 @Override
313 public Collection<UserObject> find(final Association association, final String string, final Transaction transaction)
314 throws PersistenceException {
315 this.checkTransaction(transaction);
316 try (final CallableStatement call =
317 this.database.getConnection().prepareCall(
318 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
319 + ".objectfacade.findStringTransaction(?,?,?);" + CALL_SUFFIX)) {
320 call.registerOutParameter(1, OracleTypes.CURSOR);
321 call.setLong(2, association.getId());
322 call.setString(IntegerConstants.THREE, string);
323 call.setLong(IntegerConstants.FOUR, transaction.getId());
324 call.execute();
325
326 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
327 final Collection<UserObject> result = new HashSet<>();
328 while (resultSet.next()) {
329 result.add(UserObject.init(
330 resultSet.getLong(1),
331 this.typeManager.getTypeForId(resultSet.getLong(2))));
332 }
333 return result;
334 }
335 } catch (final SQLException e) {
336 throw new OtherSQLException(e);
337 }
338 }
339
340
341
342
343
344
345
346
347
348
349
350 private void checkTransaction(final Transaction transaction) throws PersistenceException,
351 NoValidTransactionException {
352 if (!this.isOpenTransaction(transaction)) {
353 throw new NoValidTransactionException();
354 }
355 }
356
357 @Override
358 public Collection<UserObject> find(final Association association,
359 final BigInteger integer,
360 final Transaction transaction) throws PersistenceException {
361 this.checkTransaction(transaction);
362 try (final CallableStatement call =
363 this.database.getConnection().prepareCall(
364 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
365 + ".objectfacade.findIntegerTransaction(?,?,?);" + CALL_SUFFIX)) {
366 call.registerOutParameter(1, OracleTypes.CURSOR);
367 call.setLong(2, association.getId());
368 final BigDecimal wrapper = new BigDecimal(integer);
369 call.setBigDecimal(IntegerConstants.THREE, wrapper);
370 call.setLong(IntegerConstants.FOUR, transaction.getId());
371 call.execute();
372
373 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
374 final Collection<UserObject> result = new HashSet<>();
375 while (resultSet.next()) {
376 result.add(UserObject.init(
377 resultSet.getLong(1),
378 this.typeManager.getTypeForId(resultSet.getLong(2))));
379 }
380 return result;
381 }
382 } catch (final SQLException e) {
383 throw new OtherSQLException(e);
384 }
385 }
386
387 @Override
388 public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
389 final UnidirectionalAssociation association,
390 final Transaction transaction) throws PersistenceException {
391 this.checkTransaction(transaction);
392 try (final CallableStatement call =
393 this.database.getConnection().prepareCall(
394 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getTransaction(?,?,?);"
395 + CALL_SUFFIX)) {
396 call.registerOutParameter(1, OracleTypes.CURSOR);
397 call.setLong(2, owner.getId());
398 call.setLong(IntegerConstants.THREE, association.getId());
399 call.setLong(IntegerConstants.FOUR, transaction.getId());
400 call.execute();
401
402 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
403 final Collection<Tuple<UnidirectionalLink, Object>> result = new ArrayList<>();
404 while (resultSet.next()) {
405 final Object target =
406 Object.checkForBaseTypes(
407 resultSet.getLong(3),
408 this.typeManager.getTypeForId(resultSet.getLong(4)));
409 result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
410 .getUnidirectionalAssociationForId(resultSet.getLong(2))), target));
411 }
412 return result;
413 }
414 } catch (final SQLException e) {
415 throw new OtherSQLException(e);
416 }
417 }
418
419 private Collection<Tuple<MapLink, Object>> getWithKeyHelper(final UserObject owner,
420 final MapAssociation a,
421 final DBConnectionObjectHandler keyHandler,
422 final Transaction transaction) throws PersistenceException {
423 this.checkTransaction(transaction);
424 try (final CallableStatement call =
425 this.database.getConnection().prepareCall(
426 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getMap"
427 + keyHandler.getObjectTypeString() + "Transaction(?,?,?,?);" + CALL_SUFFIX)) {
428 call.registerOutParameter(1, OracleTypes.CURSOR);
429 call.setLong(2, owner.getId());
430 call.setLong(IntegerConstants.THREE, a.getId());
431 keyHandler.handleCall(call, IntegerConstants.FOUR);
432 call.setLong(IntegerConstants.FIVE, transaction.getId());
433 call.execute();
434
435 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
436 final Collection<Tuple<MapLink, Object>> result = new ArrayList<>();
437 while (resultSet.next()) {
438 if (!result.isEmpty()) {
439 throw new ToManyObjectsException();
440 }
441 final Object target =
442 Object.checkForBaseTypes(
443 resultSet.getLong(1),
444 this.typeManager.getTypeForId(resultSet.getLong(2)));
445 final MapLink link =
446 new MapLink(resultSet.getLong(IntegerConstants.FIVE), owner, target,
447 keyHandler.getObject(), a);
448 result.add(new Tuple<>(link, target));
449 }
450 if (result.isEmpty()) {
451 throw new ObjectNotFoundException();
452 }
453 return result;
454 }
455 } catch (final SQLException e) {
456 throw new OtherSQLException(e);
457 }
458 }
459
460 @Override
461 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
462 final MapAssociation association,
463 final String key,
464 final Transaction transaction) throws PersistenceException {
465 return this.getWithKeyHelper(owner, association, new DBConnectionStringHandler(key), transaction);
466 }
467
468 @Override
469 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
470 final MapAssociation association,
471 final BigInteger key,
472 final Transaction transaction) throws PersistenceException {
473 return this.getWithKeyHelper(owner, association, new DBConnectionIntegerHandler(key), transaction);
474 }
475
476 @Override
477 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
478 final MapAssociation association,
479 final UserObject key,
480 final Transaction transaction) throws PersistenceException {
481 return this.getWithKeyHelper(owner, association, new DBConnectionUserObjectHandler(key), transaction);
482 }
483
484 @Override
485 public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
486 final UnidirectionalAssociation association,
487 final Transaction transaction) throws PersistenceException {
488 this.checkTransaction(transaction);
489 try (final CallableStatement call =
490 this.database.getConnection().prepareCall(
491 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
492 + ".objectfacade.inverseGetTransaction(?,?,?);" + CALL_SUFFIX)) {
493 call.registerOutParameter(1, OracleTypes.CURSOR);
494 call.setLong(2, target.getId());
495 call.setLong(IntegerConstants.THREE, association.getId());
496 call.setLong(IntegerConstants.FOUR, transaction.getId());
497 call.execute();
498
499 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
500 final Collection<Tuple<UnidirectionalLink, UserObject>> result = new ArrayList<>();
501 while (resultSet.next()) {
502 final UserObject owner =
503 UserObject.init(resultSet.getLong(3), this.typeManager.getTypeForId(resultSet.getLong(4)));
504 result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
505 .getUnidirectionalAssociationForId(resultSet.getLong(2))), owner));
506 }
507 return result;
508 }
509 } catch (final SQLException e) {
510 throw new OtherSQLException(e);
511 }
512 }
513
514 private Collection<Tuple<UserObject, Object>> inverseGetWithKeyHelper(final DBConnectionObjectHandler targetHandler,
515 final MapAssociation association,
516 final Transaction transaction) throws PersistenceException {
517 this.checkTransaction(transaction);
518 try (final CallableStatement call =
519 this.database.getConnection().prepareCall(
520 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.inverseGetMap"
521 + targetHandler.getObjectTypeString() + "Transaction(?,?,?);" + CALL_SUFFIX)) {
522 call.registerOutParameter(1, OracleTypes.CURSOR);
523 targetHandler.handleCall(call, 2);
524 call.setLong(IntegerConstants.THREE, association.getId());
525 call.setLong(IntegerConstants.FOUR, transaction.getId());
526 call.execute();
527
528 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
529 final Collection<Tuple<UserObject, Object>> owners = new ArrayList<>();
530 while (resultSet.next()) {
531 owners.add(new Tuple<>(UserObject.init(
532 resultSet.getLong(1),
533 this.typeManager.getTypeForId(resultSet.getLong(2))), Object.checkForBaseTypes(
534 resultSet.getLong(IntegerConstants.THREE),
535 this.typeManager.getTypeForId(resultSet.getLong(IntegerConstants.FOUR)))));
536 }
537 return owners;
538 }
539 } catch (final SQLException e) {
540 throw new OtherSQLException(e);
541 }
542 }
543
544 @Override
545 public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
546 final MapAssociation association,
547 final Transaction transaction) throws PersistenceException {
548 return this.inverseGetWithKeyHelper(new DBConnectionUserObjectHandler(target), association, transaction);
549 }
550
551 @Override
552 public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
553 final MapAssociation association,
554 final Transaction transaction) throws PersistenceException {
555 return this.inverseGetWithKeyHelper(new DBConnectionStringHandler(target), association, transaction);
556 }
557
558 @Override
559 public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
560 final MapAssociation association,
561 final Transaction transaction) throws PersistenceException {
562 return this.inverseGetWithKeyHelper(new DBConnectionIntegerHandler(target), association, transaction);
563 }
564
565 @Override
566 public boolean isInConflict(final Transaction transaction1, final Transaction transaction2)
567 throws PersistenceException {
568 this.checkTransaction(transaction1);
569 this.checkTransaction(transaction2);
570 try (final CallableStatement call =
571 this.database.getConnection().prepareCall(
572 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
573 + ".objectfacade.getConflictingTransactions(?);" + CALL_SUFFIX)) {
574 call.registerOutParameter(1, OracleTypes.CURSOR);
575 call.setLong(2, transaction1.getId());
576 call.execute();
577
578 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
579 while (resultSet.next()) {
580 if (transaction2.getId() == resultSet.getLong(1)) {
581 return true;
582 }
583 }
584 return false;
585 }
586 } catch (final SQLException e) {
587 throw new OtherSQLException(e);
588 }
589 }
590
591 @Override
592 public boolean isOpenTransaction(final Transaction transaction) throws PersistenceException {
593 try (final CallableStatement call =
594 this.database.getConnection().prepareCall(
595 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.isTransactionOpen(?);"
596 + CALL_SUFFIX)) {
597 call.registerOutParameter(1, OracleTypes.NUMBER);
598 call.setLong(2, transaction.getId());
599 call.execute();
600 return call.getInt(1) == 1 ? true : false;
601 } catch (final SQLException e) {
602 throw new OtherSQLException(e);
603 }
604 }
605
606 @Override
607 public UserObject create(final UserType type, final Transaction transaction) throws PersistenceException {
608 this.checkTransaction(transaction);
609 try (final CallableStatement call =
610 this.database.getConnection().prepareCall(
611 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.createUserObject(?,?);"
612 + CALL_SUFFIX)) {
613 call.registerOutParameter(1, OracleTypes.NUMBER);
614 call.setLong(2, type.getId());
615 call.setLong(IntegerConstants.THREE, transaction.getId());
616 call.execute();
617 return UserObject.init(call.getLong(1), type);
618 } catch (final SQLException e) {
619 if (e.getErrorCode() == NotInstantiatableException.ERRORCODE) {
620 throw new NotInstantiatableException(e);
621 }
622 e.printStackTrace();
623 throw new OtherSQLException(e);
624 }
625 }
626
627 @Override
628 public void delete(final UserObject object, final Transaction transaction) throws PersistenceException {
629 this.checkTransaction(transaction);
630 try (final CallableStatement call =
631 this.database.getConnection().prepareCall(
632 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
633 + ".objectfacade.deleteUserObject(?,?);" + CALL_SUFFIX)) {
634 call.setLong(1, object.getId());
635 call.setLong(2, transaction.getId());
636 call.execute();
637 } catch (final SQLException e) {
638 if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
639 throw new InvalidLinkException(e);
640 }
641 throw new OtherSQLException(e);
642 }
643 }
644
645 private UnidirectionalLink setHelper(final UserObject owner,
646 final UnidirectionalAssociation association,
647 final DBConnectionObjectHandler targetHandler,
648 final Transaction transaction) throws PersistenceException {
649 this.checkTransaction(transaction);
650 try (final CallableStatement call =
651 this.database.getConnection().prepareCall(
652 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.set"
653 + targetHandler.getObjectTypeString() + "(?,?,?,?);" + CALL_SUFFIX)) {
654 call.registerOutParameter(1, OracleTypes.NUMBER);
655 call.setLong(2, owner.getId());
656 call.setLong(IntegerConstants.THREE, association.getId());
657 targetHandler.handleCall(call, IntegerConstants.FOUR);
658 call.setLong(IntegerConstants.FIVE, transaction.getId());
659 call.execute();
660 return new UnidirectionalLink(call.getLong(1), owner, targetHandler.getObject(), association);
661 } catch (final SQLException e) {
662 if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
663 throw new InvalidLinkException(e);
664 }
665 if (e.getErrorCode() == NotInScopeException.ERRORCODE) {
666 throw new NotInScopeException(e);
667 }
668 throw new OtherSQLException(e);
669 }
670 }
671
672 @Override
673 public UnidirectionalLink set(final UserObject owner,
674 final UnidirectionalAssociation association,
675 final UserObject target,
676 final Transaction transaction) throws PersistenceException {
677 return this.setHelper(owner, association, new DBConnectionUserObjectHandler(target), transaction);
678 }
679
680 @Override
681 public UnidirectionalLink set(final UserObject owner,
682 final UnidirectionalAssociation association,
683 final BigInteger target,
684 final Transaction transaction) throws PersistenceException {
685 return this.setHelper(owner, association, new DBConnectionIntegerHandler(target), transaction);
686 }
687
688 @Override
689 public UnidirectionalLink set(final UserObject owner,
690 final UnidirectionalAssociation association,
691 final String target,
692 final Transaction transaction) throws PersistenceException {
693 return this.setHelper(owner, association, new DBConnectionStringHandler(target), transaction);
694 }
695
696 private MapLink putHelper(final UserObject owner,
697 final MapAssociation association,
698 final DBConnectionObjectHandler targetHandler,
699 final DBConnectionObjectHandler keyHandler,
700 final Transaction transaction) throws PersistenceException {
701 try (final CallableStatement call =
702 this.database.getConnection().prepareCall(
703 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.put"
704 + targetHandler.getObjectTypeString() + keyHandler.getObjectTypeString()
705 + "(?,?,?,?,?);" + CALL_SUFFIX)) {
706 call.registerOutParameter(1, OracleTypes.NUMBER);
707 call.setLong(2, owner.getId());
708 call.setLong(IntegerConstants.THREE, association.getId());
709 targetHandler.handleCall(call, IntegerConstants.FOUR);
710 keyHandler.handleCall(call, IntegerConstants.FIVE);
711 call.setLong(IntegerConstants.SIX, transaction.getId());
712 call.execute();
713 return new MapLink(call.getLong(1), owner, targetHandler.getObject(), keyHandler.getObject(), association);
714 } catch (final SQLException e) {
715 if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
716 throw new InvalidLinkException(e);
717 }
718 if (e.getErrorCode() == NotInScopeException.ERRORCODE) {
719 throw new NotInScopeException(e);
720 }
721 if (e.getErrorCode() == DuplicateEntryException.ERRORCODE) {
722 throw new DuplicateEntryException(e);
723 }
724 throw new OtherSQLException(e);
725 }
726 }
727
728 @Override
729 public MapLink put(final UserObject owner,
730 final MapAssociation association,
731 final UserObject target,
732 final String key,
733 final Transaction transaction) throws PersistenceException {
734 return this.putHelper(
735 owner,
736 association,
737 new DBConnectionUserObjectHandler(target),
738 new DBConnectionStringHandler(key),
739 transaction);
740 }
741
742 @Override
743 public MapLink put(final UserObject owner,
744 final MapAssociation association,
745 final BigInteger target,
746 final String key,
747 final Transaction transaction) throws PersistenceException {
748 return this.putHelper(
749 owner,
750 association,
751 new DBConnectionIntegerHandler(target),
752 new DBConnectionStringHandler(key),
753 transaction);
754 }
755
756 @Override
757 public MapLink put(final UserObject owner,
758 final MapAssociation association,
759 final String target,
760 final String key,
761 final Transaction transaction) throws PersistenceException {
762 return this.putHelper(owner, association, new DBConnectionStringHandler(target), new DBConnectionStringHandler(
763 key), transaction);
764 }
765
766 @Override
767 public MapLink put(final UserObject owner,
768 final MapAssociation association,
769 final UserObject target,
770 final BigInteger key,
771 final Transaction transaction) throws PersistenceException {
772 return this.putHelper(
773 owner,
774 association,
775 new DBConnectionUserObjectHandler(target),
776 new DBConnectionIntegerHandler(key),
777 transaction);
778 }
779
780 @Override
781 public MapLink put(final UserObject owner,
782 final MapAssociation association,
783 final BigInteger target,
784 final BigInteger key,
785 final Transaction transaction) throws PersistenceException {
786 return this.putHelper(
787 owner,
788 association,
789 new DBConnectionIntegerHandler(target),
790 new DBConnectionIntegerHandler(key),
791 transaction);
792 }
793
794 @Override
795 public MapLink put(final UserObject owner,
796 final MapAssociation association,
797 final String target,
798 final BigInteger key,
799 final Transaction transaction) throws PersistenceException {
800 return this.putHelper(
801 owner,
802 association,
803 new DBConnectionStringHandler(target),
804 new DBConnectionIntegerHandler(key),
805 transaction);
806 }
807
808 @Override
809 public MapLink put(final UserObject owner,
810 final MapAssociation association,
811 final UserObject target,
812 final UserObject key,
813 final Transaction transaction) throws PersistenceException {
814 return this.putHelper(
815 owner,
816 association,
817 new DBConnectionUserObjectHandler(target),
818 new DBConnectionUserObjectHandler(key),
819 transaction);
820 }
821
822 @Override
823 public MapLink put(final UserObject owner,
824 final MapAssociation association,
825 final BigInteger target,
826 final UserObject key,
827 final Transaction transaction) throws PersistenceException {
828 return this.putHelper(
829 owner,
830 association,
831 new DBConnectionIntegerHandler(target),
832 new DBConnectionUserObjectHandler(key),
833 transaction);
834 }
835
836 @Override
837 public MapLink put(final UserObject owner,
838 final MapAssociation association,
839 final String target,
840 final UserObject key,
841 final Transaction transaction) throws PersistenceException {
842 return this.putHelper(
843 owner,
844 association,
845 new DBConnectionStringHandler(target),
846 new DBConnectionUserObjectHandler(key),
847 transaction);
848 }
849
850 @Override
851 public void unset(final Link link, final Transaction transaction) throws PersistenceException {
852 this.checkTransaction(transaction);
853 try (final CallableStatement call =
854 this.database.getConnection().prepareCall(
855 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.unset(?,?);"
856 + CALL_SUFFIX)) {
857 call.setLong(1, link.getId());
858 call.setLong(2, transaction.getId());
859 call.execute();
860 } catch (final SQLException e) {
861 throw new OtherSQLException(e);
862 }
863 }
864
865 @Override
866 public void commit(final Transaction transaction) throws PersistenceException {
867 this.checkTransaction(transaction);
868 try (final CallableStatement call =
869 this.database.getConnection().prepareCall(
870 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.commitTransaction(?);"
871 + CALL_SUFFIX)) {
872 call.setLong(1, transaction.getId());
873 call.execute();
874 } catch (final SQLException e) {
875 throw new OtherSQLException(e);
876 }
877 }
878
879 @Override
880 public void rollback(final Transaction transaction) throws PersistenceException {
881 this.checkTransaction(transaction);
882 try (final CallableStatement call =
883 this.database.getConnection().prepareCall(
884 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
885 + ".objectfacade.rollbackTransaction(?);" + CALL_SUFFIX)) {
886 call.setLong(1, transaction.getId());
887 call.execute();
888 } catch (final SQLException e) {
889 throw new OtherSQLException(e);
890 }
891 }
892
893 @Override
894 public void savePoint(final Transaction transaction) throws PersistenceException {
895 this.checkTransaction(transaction);
896 try (final CallableStatement call =
897 this.database.getConnection().prepareCall(
898 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.makeSavePoint(?);"
899 + CALL_SUFFIX)) {
900 call.setLong(1, transaction.getId());
901 call.execute();
902 } catch (final SQLException e) {
903 throw new OtherSQLException(e);
904 }
905 }
906
907 @Override
908 public void rollbackToSavePoint(final Transaction transaction) throws PersistenceException {
909 this.checkTransaction(transaction);
910 try (final CallableStatement call =
911 this.database.getConnection().prepareCall(
912 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
913 + ".objectfacade.rollbackToSavePoint(?);" + CALL_SUFFIX)) {
914 call.setLong(1, transaction.getId());
915 call.execute();
916 } catch (final SQLException e) {
917 throw new OtherSQLException(e);
918 }
919 }
920
921 @Override
922 public BigInteger getIntForId(final long id) throws PersistenceException {
923 try (final CallableStatement call =
924 this.database.getConnection().prepareCall(
925 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getInteger(?);"
926 + CALL_SUFFIX)) {
927 call.registerOutParameter(1, OracleTypes.NUMBER);
928 call.setLong(2, id);
929 call.execute();
930 return BigInteger.valueOf(call.getLong(1));
931 } catch (final SQLException e) {
932 if (e.getErrorCode() == BaseTypeNotFoundException.ERRORCODE) {
933 throw new BaseTypeNotFoundException();
934 }
935 throw new OtherSQLException(e);
936 }
937 }
938
939 @Override
940 public String getStringForId(final long id) throws PersistenceException {
941 try (final CallableStatement call =
942 this.database.getConnection().prepareCall(
943 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getString(?);"
944 + CALL_SUFFIX)) {
945 call.registerOutParameter(1, OracleTypes.VARCHAR);
946 call.setLong(2, id);
947 call.execute();
948 return call.getString(1);
949 } catch (final SQLException e) {
950 if (e.getErrorCode() == BaseTypeNotFoundException.ERRORCODE) {
951 throw new BaseTypeNotFoundException();
952 }
953 throw new OtherSQLException(e);
954 }
955 }
956
957 @Override
958 public long getIdForString(final String string) throws PersistenceException {
959 try (final CallableStatement call =
960 this.database.getConnection().prepareCall(
961 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getStringObject(?);"
962 + CALL_SUFFIX)) {
963 call.registerOutParameter(1, OracleTypes.NUMBER);
964 call.setString(2, string);
965 call.execute();
966 return call.getLong(1);
967 } catch (final SQLException e) {
968 throw new OtherSQLException(e);
969 }
970 }
971
972 @Override
973 public long getIdForInteger(final BigInteger integer) throws PersistenceException {
974 try (final CallableStatement call =
975 this.database.getConnection().prepareCall(
976 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getIntegerObject(?);"
977 + CALL_SUFFIX)) {
978 call.registerOutParameter(1, OracleTypes.NUMBER);
979 final BigDecimal wrapper = new BigDecimal(integer);
980 call.setBigDecimal(2, wrapper);
981 call.execute();
982 return call.getLong(1);
983 } catch (final SQLException e) {
984 throw new OtherSQLException(e);
985 }
986 }
987
988 @Override
989 public Transaction provideAdhocTransaction() throws PersistenceException {
990 try (final CallableStatement call =
991 this.database.getConnection().prepareCall(
992 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
993 + ".objectfacade.provideAdhocTransaction;" + CALL_SUFFIX)) {
994 call.registerOutParameter(1, OracleTypes.NUMBER);
995 call.execute();
996 return new AdhocTransaction(call.getLong(1));
997 } catch (final SQLException e) {
998 throw new OtherSQLException(e);
999 }
1000 }
1001
1002 @Override
1003 public TypeManager getTypeManager() {
1004 return this.typeManager;
1005 }
1006
1007 @Override
1008 public void clear() throws PersistenceException {
1009 try (final CallableStatement call =
1010 this.database.getConnection().prepareCall(
1011 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.clear;" + CALL_SUFFIX)) {
1012 call.execute();
1013 } catch (final SQLException e) {
1014 e.printStackTrace();
1015 throw new OtherSQLException(e);
1016 }
1017 }
1018
1019 @Override
1020 public Collection<UserObject> findAllObjects(final UserType type, final Transaction transaction)
1021 throws PersistenceException {
1022 final Collection<UserObject> result = new HashSet<>();
1023 try (final CallableStatement call =
1024 this.database.getConnection().prepareCall(
1025 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
1026 + ".objectfacade.findUserObjectByType(?,?);" + CALL_SUFFIX)) {
1027 call.registerOutParameter(1, OracleTypes.CURSOR);
1028 call.setLong(2, type.getId());
1029 call.setLong(IntegerConstants.THREE, transaction.getId());
1030 call.execute();
1031 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
1032 while (resultSet.next()) {
1033 result.add(UserObject.init(
1034 resultSet.getLong(1),
1035 this.typeManager.getTypeForId(resultSet.getLong(2))));
1036 }
1037 }
1038 } catch (final SQLException e) {
1039 throw new OtherSQLException(e);
1040 }
1041 return result;
1042 }
1043
1044 @Override
1045 public UserObject checkUserObjectOut(final long id, final Transaction transaction) throws PersistenceException {
1046 try (final CallableStatement call =
1047 this.database.getConnection().prepareCall(
1048 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
1049 + ".objectfacade.checkUserObjectOut(?,?);" + CALL_SUFFIX)) {
1050 call.registerOutParameter(1, OracleTypes.CURSOR);
1051 call.setLong(2, id);
1052 call.setLong(IntegerConstants.THREE, transaction.getId());
1053 call.execute();
1054 try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
1055 if (resultSet.next()) {
1056 return UserObject.init(resultSet.getLong(1), this.typeManager.getTypeForId(resultSet.getLong(2)));
1057 } else {
1058 throw new ObjectNotFoundException();
1059 }
1060 }
1061 } catch (final SQLException e) {
1062 throw new OtherSQLException(e);
1063 }
1064 }
1065 }