This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new 3eb1814  [Java] Update Java to be consistent with C (#115)
3eb1814 is described below

commit 3eb1814d0af1a8d602d5c31017dcd794d3ffcc5d
Author: David Li <[email protected]>
AuthorDate: Thu Sep 8 13:58:06 2022 -0400

    [Java] Update Java to be consistent with C (#115)
---
 adbc.h                                             |  6 +-
 .../org/apache/arrow/adbc/core/AdbcConnection.java | 29 ++++++++-
 .../org/apache/arrow/adbc/core/IsolationLevel.java | 70 +++++++++++++++++++++
 .../arrow/adbc/driver/jdbc/JdbcConnection.java     | 71 ++++++++++++++++++++++
 .../driver/testsuite/AbstractConnectionTest.java   | 12 ++++
 5 files changed, 182 insertions(+), 6 deletions(-)

diff --git a/adbc.h b/adbc.h
index dc1af3e..14488c9 100644
--- a/adbc.h
+++ b/adbc.h
@@ -661,14 +661,14 @@ AdbcStatusCode AdbcConnectionReadPartition(struct 
AdbcConnection* connection,
 /// \brief The name of the canonical option for setting the isolation
 ///   level of a transaction.
 ///
-/// Should only be used in conjunction with autocommit and
+/// Should only be used in conjunction with autocommit disabled and
 /// AdbcConnectionCommit / AdbcConnectionRollback. If the desired
-/// isolation level is not supported by a driver, it should return
+/// isolation level is not supported by a driver, it should return an
 /// appropriate error.
 #define ADBC_CONNECTION_OPTION_ISOLATION_LEVEL \
   "adbc.connection.transaction.isolation_level"
 
-/// \brief Use database or driver default Isolation level
+/// \brief Use database or driver default isolation level
 #define ADBC_OPTION_ISOLATION_LEVEL_DEFAULT \
   "adbc.connection.transaction.isolation.default"
 /// \brief The lowest isolation level. Dirty reads are allowed, so one
diff --git 
a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java 
b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
index ee4399f..4f38c28 100644
--- a/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/AdbcConnection.java
@@ -39,7 +39,7 @@ public interface AdbcConnection extends AutoCloseable {
   /**
    * Create a new statement to bulk insert a {@link VectorSchemaRoot} into a 
table.
    *
-   * <p>Bind data to the statement, then call {@link AdbcStatement#execute()}. 
See {@link
+   * <p>Bind data to the statement, then call {@link 
AdbcStatement#executeUpdate()}. See {@link
    * BulkIngestMode} for description of behavior around creating tables.
    */
   default AdbcStatement bulkIngest(String targetTableName, BulkIngestMode mode)
@@ -203,8 +203,7 @@ public interface AdbcConnection extends AutoCloseable {
       String[] tableTypes,
       String columnNamePattern)
       throws AdbcException {
-    throw AdbcException.notImplemented(
-        "Connection does not support getTableSchema(String, String, String)");
+    throw AdbcException.notImplemented("Connection does not support 
getObjects()");
   }
 
   /**
@@ -278,4 +277,28 @@ public interface AdbcConnection extends AutoCloseable {
   default void setAutoCommit(boolean enableAutoCommit) throws AdbcException {
     throw AdbcException.notImplemented("Connection does not support 
transactions");
   }
+
+  /**
+   * Get whether the connection is read-only.
+   *
+   * <p>Connections are not read-only by default.
+   */
+  default boolean getReadOnly() throws AdbcException {
+    return false;
+  }
+
+  /** Toggle whether the connection is read-only. */
+  default void setReadOnly(boolean isReadOnly) throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support read-only 
mode");
+  }
+
+  /** Get the isolation level used by transactions. */
+  default IsolationLevel getIsolationLevel() throws AdbcException {
+    return IsolationLevel.DEFAULT;
+  }
+
+  /** Change the isolation level used by transactions. */
+  default void setIsolationLevel(IsolationLevel level) throws AdbcException {
+    throw AdbcException.notImplemented("Connection does not support setting 
isolation level");
+  }
 }
diff --git 
a/java/core/src/main/java/org/apache/arrow/adbc/core/IsolationLevel.java 
b/java/core/src/main/java/org/apache/arrow/adbc/core/IsolationLevel.java
new file mode 100644
index 0000000..aad1490
--- /dev/null
+++ b/java/core/src/main/java/org/apache/arrow/adbc/core/IsolationLevel.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.arrow.adbc.core;
+
+/** The isolation level to use for transactions when autocommit is disabled. */
+public enum IsolationLevel {
+  /** The database or driver default isolation level. */
+  DEFAULT,
+  /**
+   * The lowest isolation level. Dirty reads are allowed, so one transaction 
may see
+   * not-yet-committed changes made by others.
+   */
+  READ_UNCOMMITTED,
+  /**
+   * Lock-based concurrency control keeps write locks until the end of the 
transaction, but read
+   * locks are released as soon as a SELECT is performed. Non-repeatable reads 
can occur in this
+   * isolation level.
+   *
+   * <p>More simply put, Read Committed is an isolation level that guarantees 
that any data read is
+   * committed at the moment it is read. It simply restricts the reader from 
seeing any
+   * intermediate, uncommitted, 'dirty' reads. It makes no promise whatsoever 
that if the
+   * transaction re-issues the read, it will find the same data; data is free 
to change after it is
+   * read.
+   */
+  READ_COMMITTED,
+  /**
+   * Lock-based concurrency control keeps read AND write locks (acquired on 
selection data) until
+   * the end of the transaction.
+   *
+   * <p>However, range-locks are not managed, so phantom reads can occur. 
Write skew is possible at
+   * this isolation level in some systems.
+   */
+  REPEATABLE_READ,
+  /**
+   * This isolation guarantees that all reads in the transaction will see a 
consistent snapshot of
+   * the database and the transaction should only successfully commit if no 
updates conflict with
+   * any concurrent updates made since that snapshot.
+   */
+  SNAPSHOT,
+  /**
+   * Serializability requires read and write locks to be released only at the 
end of the
+   * transaction. This includes acquiring range- locks when a select query 
uses a ranged WHERE
+   * clause to avoid phantom reads.
+   */
+  SERIALIZABLE,
+  /**
+   * The central distinction between serializability and linearizability is 
that serializability is
+   * a global property; a property of an entire history of operations and 
transactions.
+   * Linearizability is a local property; a property of a single 
operation/transaction.
+   *
+   * <p>Linearizability can be viewed as a special case of strict 
serializability where transactions
+   * are restricted to consist of a single operation applied to a single 
object.
+   */
+  LINEARIZABLE,
+}
diff --git 
a/java/driver/jdbc/src/main/java/org/apache/arrow/adbc/driver/jdbc/JdbcConnection.java
 
b/java/driver/jdbc/src/main/java/org/apache/arrow/adbc/driver/jdbc/JdbcConnection.java
index 53cd7cb..e5f4a6a 100644
--- 
a/java/driver/jdbc/src/main/java/org/apache/arrow/adbc/driver/jdbc/JdbcConnection.java
+++ 
b/java/driver/jdbc/src/main/java/org/apache/arrow/adbc/driver/jdbc/JdbcConnection.java
@@ -28,6 +28,7 @@ import org.apache.arrow.adbc.core.AdbcConnection;
 import org.apache.arrow.adbc.core.AdbcException;
 import org.apache.arrow.adbc.core.AdbcStatement;
 import org.apache.arrow.adbc.core.BulkIngestMode;
+import org.apache.arrow.adbc.core.IsolationLevel;
 import org.apache.arrow.adbc.core.StandardSchemas;
 import org.apache.arrow.adbc.sql.SqlQuirks;
 import org.apache.arrow.memory.BufferAllocator;
@@ -180,6 +181,76 @@ public class JdbcConnection implements AdbcConnection {
     }
   }
 
+  @Override
+  public boolean getReadOnly() throws AdbcException {
+    try {
+      return connection.isReadOnly();
+    } catch (SQLException e) {
+      throw JdbcDriverUtil.fromSqlException(e);
+    }
+  }
+
+  @Override
+  public void setReadOnly(boolean isReadOnly) throws AdbcException {
+    try {
+      connection.setReadOnly(isReadOnly);
+    } catch (SQLException e) {
+      throw JdbcDriverUtil.fromSqlException(e);
+    }
+  }
+
+  @Override
+  public IsolationLevel getIsolationLevel() throws AdbcException {
+    try {
+      final int transactionIsolation = connection.getTransactionIsolation();
+      switch (transactionIsolation) {
+        case Connection.TRANSACTION_NONE:
+          return IsolationLevel.DEFAULT;
+        case Connection.TRANSACTION_READ_UNCOMMITTED:
+          return IsolationLevel.READ_UNCOMMITTED;
+        case Connection.TRANSACTION_READ_COMMITTED:
+          return IsolationLevel.READ_COMMITTED;
+        case Connection.TRANSACTION_REPEATABLE_READ:
+          return IsolationLevel.REPEATABLE_READ;
+        case Connection.TRANSACTION_SERIALIZABLE:
+          return IsolationLevel.SERIALIZABLE;
+        default:
+          throw AdbcException.notImplemented(
+              JdbcDriverUtil.prefixExceptionMessage(
+                  "JDBC isolation level not recognized: " + 
transactionIsolation));
+      }
+    } catch (SQLException e) {
+      throw JdbcDriverUtil.fromSqlException(e);
+    }
+  }
+
+  @Override
+  public void setIsolationLevel(IsolationLevel level) throws AdbcException {
+    try {
+      switch (level) {
+        case READ_UNCOMMITTED:
+          
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+          break;
+        case READ_COMMITTED:
+          
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
+          break;
+        case REPEATABLE_READ:
+          
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
+          break;
+        case SERIALIZABLE:
+          
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+          break;
+        case DEFAULT:
+        case SNAPSHOT:
+        case LINEARIZABLE:
+          throw AdbcException.notImplemented(
+              JdbcDriverUtil.prefixExceptionMessage("Isolation level not 
supported: " + level));
+      }
+    } catch (SQLException e) {
+      throw JdbcDriverUtil.fromSqlException(e);
+    }
+  }
+
   @Override
   public void close() throws Exception {
     connection.close();
diff --git 
a/java/driver/validation/src/main/java/org/apache/arrow/adbc/driver/testsuite/AbstractConnectionTest.java
 
b/java/driver/validation/src/main/java/org/apache/arrow/adbc/driver/testsuite/AbstractConnectionTest.java
index 4b6944e..80efac2 100644
--- 
a/java/driver/validation/src/main/java/org/apache/arrow/adbc/driver/testsuite/AbstractConnectionTest.java
+++ 
b/java/driver/validation/src/main/java/org/apache/arrow/adbc/driver/testsuite/AbstractConnectionTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.arrow.adbc.driver.testsuite;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import org.apache.arrow.adbc.core.AdbcConnection;
 import org.apache.arrow.adbc.core.AdbcDatabase;
 import org.apache.arrow.util.AutoCloseables;
@@ -46,4 +48,14 @@ public abstract class AbstractConnectionTest {
   void multipleConnections() throws Exception {
     try (final AdbcConnection ignored = database.connect()) {}
   }
+
+  @Test
+  void readOnly() throws Exception {
+    assertThat(connection.getReadOnly()).isFalse();
+  }
+
+  @Test
+  void isolationLevel() throws Exception {
+    connection.getIsolationLevel();
+  }
 }

Reply via email to