@Override public <P> void fetchOne(Query query, Function<JsonObject, P> mapper, Handler<AsyncResult<P>> resultHandler) { getConnection().setHandler(sqlConnectionResult->{ if(sqlConnectionResult.succeeded()){ log("Fetch one", ()-> query.getSQL(ParamType.INLINED)); sqlConnectionResult.result().queryWithParams( query.getSQL(), getBindValues(query), executeAndClose(rs -> { if(rs.getRows().size() > 1){ throw new TooManyRowsException(String.format("Got more than one row: %d",rs.getRows().size())); } Optional<P> optional = rs.getRows().stream().findFirst().map(mapper); return (optional.orElseGet(() -> null)); }, sqlConnectionResult.result(), resultHandler) ); }else{ resultHandler.handle(Future.failedFuture(sqlConnectionResult.cause())); } }); }
@Test public void fetchOneByConditionWithMultipleMatchesShouldFail() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); CompletableFuture<Integer> insertFuture1 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L)); CompletableFuture<Integer> insertFuture2 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L)); CompletableFuture.allOf(insertFuture1, insertFuture2). thenCompose(v->dao.fetchOneAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L))). exceptionally((x) -> { Assert.assertNotNull(x); //cursor fetched more than one row Assert.assertEquals(TooManyRowsException.class, x.getCause().getClass()); return null;}). thenCompose(v -> dao.deleteExecAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L))). whenComplete(failOrCountDown(latch)); await(latch); }
@Test public void fetchOneByConditionWithMultipleMatchesShouldFail() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); Single<Integer> insert1 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L)); Single<Integer> insert2 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L)); Single.zip(insert1, insert2, (i1, i2) -> i1) .flatMap(i -> dao.fetchOneAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L))) .onErrorReturn(x -> { Assert.assertNotNull(x); Assert.assertEquals(TooManyRowsException.class, x.getClass()); return null; }) .flatMap(n -> dao.deleteExecAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L))) .subscribe(failOrCountDownSingleObserver(latch)); await(latch); }
@Test public void fetchOneByConditionWithMultipleMatchesShouldFail() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); Future<Integer> insertFuture1 = Future.future(); Future<Integer> insertFuture2 = Future.future(); Something someNewObject = createSomething(); dao.insertReturningPrimaryAsync(someNewObject,insertFuture1); dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(someNewObject.getSomehugenumber()),insertFuture2); CompositeFuture.all(insertFuture1,insertFuture2). setHandler(consumeOrFailHandler(v->{ dao.fetchOneAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(someNewObject.getSomehugenumber()),h->{ Assert.assertNotNull(h.cause()); //cursor fetched more than one row Assert.assertEquals(TooManyRowsException.class, h.cause().getClass()); dao.deleteExecAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(someNewObject.getSomehugenumber()),countdownLatchHandler(latch)); }); })); await(latch); }
@Test public void fetchOneByConditionWithMultipleMatchesShouldFail() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); long num = NUMBERS.incrementAndGet(); Single<Integer> insert1 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(num)); Single<Integer> insert2 = dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(num)); Single.zip(insert1, insert2, (i1, i2) -> i1) .flatMap(i -> dao.fetchOneAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(num))) .onErrorReturn(x -> { Assert.assertNotNull(x); Assert.assertEquals(TooManyRowsException.class, x.getClass()); //must return a non-null value... return createSomething(); }) .flatMap(n -> dao.deleteExecAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(num))) .subscribe(failOrCountDownSingleObserver(latch)); await(latch); }
@Test public void fetchOneByConditionWithMultipleMatchesShouldFail() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); Future<Integer> insertFuture1 = Future.future(); Future<Integer> insertFuture2 = Future.future(); dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L),insertFuture1); dao.insertReturningPrimaryAsync(createSomething().setSomehugenumber(1L),insertFuture2); CompositeFuture.all(insertFuture1,insertFuture2). setHandler(consumeOrFailHandler(v->{ dao.fetchOneAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L),h->{ Assert.assertNotNull(h.cause()); //cursor fetched more than one row Assert.assertEquals(TooManyRowsException.class, h.cause().getClass()); dao.deleteExecAsync(Tables.SOMETHING.SOMEHUGENUMBER.eq(1L),countdownLatchHandler(latch)); }); })); await(latch); }
private boolean checkPermission(List<Agency> agencies, Relationship permission, UUID intrinsic) throws DataAccessException, TooManyRowsException { if (intrinsic == null) { return true; } List<UUID> roles = agencies.stream() .map(r -> r.getId()) .collect(Collectors.toList()); ExistentialNetwork membership = EXISTENTIAL_NETWORK.as(MEMBERSHIP); CommonTableExpression<Record1<UUID>> groups = name(GROUPS).fields(AGENCY) .as(create.select(membership.field(membership.CHILD)) .from(membership) .where(membership.field(membership.PARENT) .in(roles)) .and(membership.field(membership.RELATIONSHIP) .equal(WellKnownRelationship.MEMBER_OF.id()))); return ZERO.equals(create.with(groups) .selectCount() .from(EXISTENTIAL) .where(EXISTENTIAL.ID.equal(intrinsic)) .andNotExists(create.select(EXISTENTIAL_NETWORK.CHILD) .from(EXISTENTIAL_NETWORK) .where(EXISTENTIAL_NETWORK.PARENT.in(create.selectFrom(groups)) .or(EXISTENTIAL_NETWORK.PARENT.in(roles))) .and(EXISTENTIAL_NETWORK.RELATIONSHIP.equal(permission.getId())) .and(EXISTENTIAL_NETWORK.CHILD.eq(EXISTENTIAL.ID))) .fetchOne() .value1()); }