From d4c391209c8ae0e225cb15e76aaf3300ed0cf988 Mon Sep 17 00:00:00 2001 From: lukaseder Date: Thu, 13 Jul 2017 12:20:59 +0200 Subject: [PATCH] [#6391] Added API --- jOOQ/src/main/java/org/jooq/ResultOrRows.java | 18 +++++++- jOOQ/src/main/java/org/jooq/Results.java | 43 +++++++++++++++++-- .../main/java/org/jooq/impl/ResultsImpl.java | 37 +++++++++++++--- 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/ResultOrRows.java b/jOOQ/src/main/java/org/jooq/ResultOrRows.java index a1905ff3aa..050999f1ee 100644 --- a/jOOQ/src/main/java/org/jooq/ResultOrRows.java +++ b/jOOQ/src/main/java/org/jooq/ResultOrRows.java @@ -36,8 +36,13 @@ package org.jooq; import java.sql.Statement; +import org.jooq.conf.Settings; +import org.jooq.conf.ThrowExceptions; +import org.jooq.exception.DataAccessException; + /** - * A type that contains either a {@link Result} or an update count. + * A type that contains either a {@link Result}, an update count, or an + * exception. * * @author Lukas Eder */ @@ -57,4 +62,15 @@ public interface ResultOrRows { * @see Statement#getUpdateCount() */ int rows(); + + /** + * The exception if applicable or null if there was no + * exception. + *

+ * Exceptions are made available through this API only if + * {@link Settings#getThrowExceptions()} is set to + * {@link ThrowExceptions#THROW_NONE}. In all other cases, a batch execution + * is aborted and exceptions are thrown as ordinary Java exceptions. + */ + DataAccessException exception(); } diff --git a/jOOQ/src/main/java/org/jooq/Results.java b/jOOQ/src/main/java/org/jooq/Results.java index 11f34c6141..c98b2132b8 100644 --- a/jOOQ/src/main/java/org/jooq/Results.java +++ b/jOOQ/src/main/java/org/jooq/Results.java @@ -34,17 +34,54 @@ */ package org.jooq; +import java.sql.SQLException; import java.util.List; +import org.jooq.conf.Settings; +import org.jooq.conf.ThrowExceptions; + /** * A list of {@link Result} and update counts that can be returned by * {@link ResultQuery#fetchMany()} calls and other calls that produce multiple * cursors and update counts. *

* For backwards-compatibility (e.g. with {@link ResultQuery#fetchMany()}), this - * type extends {@link List} containing only the {@link Result}, not the rows / - * update counts of interleaved updates. In order to get both, call - * {@link #resultsOrRows()}. + * type extends {@link List} containing only the {@link Result}, not the rows, + * update counts, exceptions of interleaved updates. In order to get them all, + * call {@link #resultsOrRows()} upon the results. + *

+ *

Exceptions

+ *

+ * Some databases support raising several errors or exceptions per statement + * batch (e.g. {@link SQLDialect#SQLSERVER}): + *

+ *

+ * INSERT INTO t VALUES (1),(2),(3);
+ * RAISERROR('message 1', 16, 2, 3);
+ * RAISERROR('message 2', 16, 2, 3);
+ * SELECT * FROM t;
+ * RAISERROR('message 3', 16, 2, 3);
+ * 
+ *

+ * The above batch will produce: + *

+ *

+ * By default (or when explicitly specifying {@link ThrowExceptions#THROW_ALL} + * in {@link Settings#getThrowExceptions()}), this particular batch will produce + * a single exception corresponding to "message 1", with additional + * exceptions for "message 2" and "message 3" attached + * to {@link SQLException#getNextException()}, recursively. + *

+ * When specifying {@link ThrowExceptions#THROW_FIRST}, only + * "message 1" is propagated. When specifying + * {@link ThrowExceptions#THROW_NONE}, then all exceptions are collected as + * results and are made available through {@link #resultsOrRows()} in + * {@link ResultOrRows#exception()}. * * @author Lukas Eder */ diff --git a/jOOQ/src/main/java/org/jooq/impl/ResultsImpl.java b/jOOQ/src/main/java/org/jooq/impl/ResultsImpl.java index 7207648818..4fd17ecaa4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ResultsImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ResultsImpl.java @@ -43,6 +43,7 @@ import org.jooq.Record; import org.jooq.Result; import org.jooq.ResultOrRows; import org.jooq.Results; +import org.jooq.exception.DataAccessException; /** * @author Lukas Eder @@ -189,20 +190,22 @@ final class ResultsImpl extends AbstractList> implements Results static final class ResultOrRowsImpl implements ResultOrRows { - private final Result result; - private final int rows; + private final Result result; + private final int rows; + private final DataAccessException exception; ResultOrRowsImpl(Result result) { - this(result, result != null ? result.size() : 0); + this(result, result != null ? result.size() : 0, null); } ResultOrRowsImpl(int rows) { - this(null, rows); + this(null, rows, null); } - private ResultOrRowsImpl(Result result, int rows) { + private ResultOrRowsImpl(Result result, int rows, DataAccessException exception) { this.result = result; this.rows = rows; + this.exception = exception; } @Override @@ -215,11 +218,17 @@ final class ResultsImpl extends AbstractList> implements Results return rows; } + @Override + public final DataAccessException exception() { + return exception; + } + @Override public int hashCode() { final int prime = 31; int r = 1; - r = prime * r + ((this.result == null) ? 0 : this.result.hashCode()); + r = prime * r + ((exception == null) ? 0 : exception.hashCode()); + r = prime * r + ((result == null) ? 0 : result.hashCode()); r = prime * r + rows; return r; } @@ -233,6 +242,12 @@ final class ResultsImpl extends AbstractList> implements Results if (getClass() != obj.getClass()) return false; ResultOrRowsImpl other = (ResultOrRowsImpl) obj; + if (exception == null) { + if (other.exception != null) + return false; + } + else if (!exception.equals(other.exception)) + return false; if (result == null) { if (other.result != null) return false; @@ -243,5 +258,15 @@ final class ResultsImpl extends AbstractList> implements Results return false; return true; } + + @Override + public String toString() { + if (exception != null) + return exception.toString(); + else if (result != null) + return result.toString(); + else + return "" + rows; + } } }