You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/04/04 00:01:28 UTC
svn commit: r1464215 [1/3] - in /jena/Experimental/jena-jdbc:
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/
jena-jdbc-core/s...
Author: rvesse
Date: Wed Apr 3 22:01:26 2013
New Revision: 1464215
URL: http://svn.apache.org/r1464215
Log:
Plumb in transactions properly, rename stuff to remove unecessary junk from class names
Added:
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/JenaResultsMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/AbstractJenaDriverTests.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/connections/
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/connections/AbstractJenaConnectionTests.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/connections/
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/connections/DebugMemConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/connections/TestDatasetConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/results/
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/results/AbstractMemResultSetTests.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/results/TestResultSets.java
Removed:
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaJdbcDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaJdbcConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaJdbcMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaJdbcResultSet.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/JenaJdbcResultsMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/AbstractJenaJdbcConnectionTests.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/AbstractJenaJdbcDriverTests.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/AbstractMemResultSetTests.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/DebugMemConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestJenaJdbcDatasetConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestJenaJdbcMemDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestResultSets.java
Modified:
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/DatasetMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/QueryExecutionResults.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaJdbcStatement.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/MemDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/test/java/org/apache/jena/jdbc/remote/TestRemoteEndpointConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/test/java/org/apache/jena/jdbc/remote/TestRemoteEndpointDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/test/java/org/apache/jena/jdbc/remote/results/TestRemoteEndpointResults.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/pom.xml
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/TDBDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/test/java/org/apache/jena/jdbc/tdb/DebugTdbConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/test/java/org/apache/jena/jdbc/tdb/TestJenaJdbcTdbDiskConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/test/java/org/apache/jena/jdbc/tdb/TestJenaJdbcTdbDriver.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/test/java/org/apache/jena/jdbc/tdb/TestJenaJdbcTdbMemConnection.java
Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java?rev=1464215&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java Wed Apr 3 22:01:26 2013
@@ -0,0 +1,201 @@
+/**
+ * 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.jena.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+/**
+ * Abstract implementation of a Jena JDBC driver
+ *
+ */
+public abstract class JenaDriver implements Driver {
+
+ /**
+ * Constant for the primary Jena JDBC Driver prefix, implementations supply
+ * an additional prefix which will form the next portion of the JDBC URL
+ */
+ public static final String DRIVER_PREFIX = "jdbc:jena:";
+
+ private int majorVer, minorVer;
+ private String implPrefix;
+
+ /**
+ * Creates a new driver
+ *
+ * @param majorVer
+ * Major Version
+ * @param minorVer
+ * Minor Version
+ * @param prefix
+ * Implementation specific prefix
+ */
+ public JenaDriver(int majorVer, int minorVer, String prefix) {
+ this.majorVer = majorVer;
+ this.minorVer = minorVer;
+
+ if (prefix == null)
+ throw new IllegalArgumentException("Implementation specific prefix cannot be null");
+ if (!prefix.endsWith(":"))
+ throw new IllegalArgumentException("Implementation specific prefix must end with a :");
+ // Validate that implPrefix is a valid scheme i.e. [A-Za-z\d\-_]+
+ if (!prefix.matches("[A-Za-z\\d\\-_]+:"))
+ throw new IllegalArgumentException(
+ "Implementation specific prefix must conform to the regular expression [A-Za-z\\d\\-_]+:");
+ this.implPrefix = prefix;
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ if (url.startsWith(DRIVER_PREFIX + this.implPrefix)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Connection connect(String url, Properties props) throws SQLException {
+ // Create new empty properties if necessary
+ Properties ps = new Properties();
+
+ // Parse out the key value pairs from the connection URL
+ url = url.substring(DRIVER_PREFIX.length() + this.implPrefix.length());
+ String[] kvps = url.split("&|;");
+ for (int i = 0; i < kvps.length; i++) {
+ String kvp = kvps[i];
+ if (kvp.length() == 0)
+ continue;
+
+ // Try to split into key and value
+ String key, value;
+ if (kvp.contains("=")) {
+ String[] temp = kvp.split("=", 2);
+ key = temp[0];
+ value = temp[1];
+ } else {
+ key = kvp;
+ value = null;
+ }
+
+ // All keys are normalized to lower case using the English Locale
+ key = key.toLowerCase(Locale.ENGLISH);
+
+ // Put into properties appropriately
+ if (!ps.containsKey(key)) {
+ // Doesn't yet exist, add a string/list as appropriate
+ if (this.allowsMultipleValues(key)) {
+ List<String> values = new ArrayList<String>();
+ values.add(value);
+ ps.put(key, values);
+ } else {
+ ps.put(key, value);
+ }
+ } else if (this.allowsMultipleValues(key)) {
+ // If it allows multiple values append to those existing
+ Object currValue = ps.get(key);
+ if (currValue instanceof List<?>) {
+ // Can just append to existing list
+ ((List<Object>) currValue).add(value);
+ } else {
+ // Convert to list
+ List<String> values = new ArrayList<String>();
+ values.add(currValue.toString());
+ values.add(value);
+ ps.put(key, values);
+ }
+ }
+ }
+
+ // Overwrite connection URL parameters with code provided parameters
+ // if applicable
+ if (props != null) {
+ // Copy across normalizing keys to lower case in the English Locale
+ for (Entry<Object, Object> e : props.entrySet()) {
+ ps.put(e.getKey().toString().toLowerCase(Locale.ENGLISH), e.getValue());
+ }
+ }
+
+ // Try to create the connection
+ return this.connect(ps);
+ }
+
+ /**
+ * Gets whether a parameter is allowed to have multiple values
+ *
+ * @param key
+ * Key
+ * @return True if multiple values are allowed, false otherwise
+ */
+ protected boolean allowsMultipleValues(String key) {
+ return false;
+ }
+
+ /**
+ * Method which derived classes must implement to create their actual
+ * connections
+ * <p>
+ * The driver will already have parsed the connection URL to extract out any
+ * connection parameters and has added them to the parameters provided in
+ * the Properties object. Parameters which the implementation has indicated
+ * allow multiple values will be present as {@link List} in the properties,
+ * all other parameters will be either strings or the original values as
+ * injected by the calling code. Properties specified in the
+ * {@link Properties} object by the calling code have precedence over the
+ * connection URL parameters.
+ * </p>
+ *
+ * @param props
+ * Properties
+ * @return Connection
+ * @throws SQLException
+ * Thrown if a connection cannot be created for any reason
+ */
+ protected abstract Connection connect(Properties props) throws SQLException;
+
+ public int getMajorVersion() {
+ return this.minorVer;
+ }
+
+ public int getMinorVersion() {
+ return this.majorVer;
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException {
+ return new DriverPropertyInfo[0];
+ }
+
+ /**
+ * Returns that a Jena JDBC driver is not JDBC compliant since strict JDBC
+ * compliance requires support for SQL-92 and since we are using SPARQL we
+ * don't meet that criteria
+ */
+ public final boolean jdbcCompliant() {
+ // This has to be false since we are not JDBC compliant in that
+ // we use SPARQL in place of SQL-92
+ return false;
+ }
+
+}
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java?rev=1464215&r1=1464214&r2=1464215&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java Wed Apr 3 22:01:26 2013
@@ -31,7 +31,7 @@ import com.hp.hpl.jena.query.Dataset;
* Represents a connection to a {@link Dataset} instance
*
*/
-public abstract class DatasetConnection extends JenaJdbcConnection {
+public abstract class DatasetConnection extends JenaConnection {
protected Dataset ds;
private boolean readonly = false;
@@ -75,7 +75,7 @@ public abstract class DatasetConnection
throws SQLException {
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) throw new SQLException("Dataset backed connections currently only supports forward-only result sets");
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) throw new SQLException("Database backed connections currently only supports read-only result sets");
- return new DatasetStatement(this);
+ return new DatasetStatement(this, ResultSet.FETCH_FORWARD, 0, resultSetHoldability, this.getAutoCommit(), this.getTransactionIsolation());
}
@Override
@@ -135,9 +135,11 @@ public abstract class DatasetConnection
protected void checkTransactionIsolation(int level) throws SQLException {
switch (level) {
case TRANSACTION_NONE:
- case TRANSACTION_SERIALIZABLE:
- // No transactions or serializable are the only supported transaction levels
return;
+ case TRANSACTION_SERIALIZABLE:
+ // Serializable is supported if the dataset supports transactions
+ if (this.ds.supportsTransactions()) return;
+ // Otherwise we'll drop through and throw the error
default:
throw new SQLException(String.format("The Transaction level %d is not supported by this connection", level));
}
Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java?rev=1464215&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java Wed Apr 3 22:01:26 2013
@@ -0,0 +1,406 @@
+/**
+ * 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.jena.jdbc.connections;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLRecoverableException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.jena.jdbc.metadata.JenaMetadata;
+
+/**
+ * Abstract base implementation of a Jena JDBC connection
+ *
+ */
+public abstract class JenaConnection implements Connection {
+
+ /**
+ * Constant for default cursor holdability for Jena JDBC connections
+ */
+ public static final int DEFAULT_HOLDABILITY = ResultSet.CLOSE_CURSORS_AT_COMMIT;
+ /**
+ * Constant for default auto-commit for Jena JDBC connections
+ */
+ public final static boolean DEFAULT_AUTO_COMMIT = true;
+ /**
+ * Constant for default transaction isolation level for Jena JDBC
+ * connections
+ */
+ public final static int DEFAULT_ISOLATION_LEVEL = TRANSACTION_NONE;
+
+ private Properties clientInfo = new Properties();
+ private int holdability = DEFAULT_HOLDABILITY;
+ private SQLWarning warnings = null;
+ private boolean autoCommit = DEFAULT_AUTO_COMMIT;
+ private int isolationLevel = DEFAULT_ISOLATION_LEVEL;
+ private List<Statement> statements = new ArrayList<Statement>();
+
+ /**
+ * Creates a new connection
+ *
+ * @throws SQLException
+ * Thrown if the arguments are invalid
+ */
+ public JenaConnection() throws SQLException {
+ this(DEFAULT_HOLDABILITY);
+ }
+
+ /**
+ * Creates a new connection
+ *
+ * @param holdability
+ * Cursor holdability
+ * @throws SQLException
+ * Thrown if the arguments are invalid
+ */
+ public JenaConnection(int holdability) throws SQLException {
+ this.checkHoldability(holdability);
+ this.holdability = holdability;
+ }
+
+ public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public <T> T unwrap(Class<T> arg0) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public void clearWarnings() throws SQLException {
+ this.warnings = null;
+ }
+
+ public final void close() throws SQLException {
+ try {
+ // Close any open statements
+ this.closeStatements();
+ } finally {
+ this.closeInternal();
+ }
+ }
+
+ private void closeStatements() throws SQLException {
+
+ for (Statement stmt : this.statements) {
+ stmt.close();
+ }
+ this.statements.clear();
+ }
+
+ protected abstract void closeInternal() throws SQLException;
+
+ public void commit() throws SQLException {
+ if (this.isClosed())
+ throw new SQLException("Cannot commit on a closed connection");
+ try {
+ // Get the implementation to do the actual commit
+ this.commitInternal();
+
+ // If applicable close cursors
+ if (this.holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT) {
+ this.closeStatements();
+ }
+ } catch (SQLException e) {
+ // Throw as-is
+ throw e;
+ } catch (Exception e) {
+ // Wrap as SQLException
+ throw new SQLException("Unexpected error committing transaction", e);
+ }
+ }
+
+ protected abstract void commitInternal() throws SQLException;
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public Blob createBlob() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public Clob createClob() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public NClob createNClob() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public final Statement createStatement() throws SQLException {
+ if (this.isClosed())
+ throw new SQLException("Cannot create a statement after the connection was closed");
+ return this.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ }
+
+ public final Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ if (this.isClosed())
+ throw new SQLException("Cannot create a statement after the connection was closed");
+ return this.createStatement(resultSetType, resultSetConcurrency, this.getHoldability());
+ }
+
+ public final Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ if (this.isClosed())
+ throw new SQLException("Cannot create a statement after the connection was closed");
+ Statement stmt = this.createStatementInternal(resultSetType, resultSetConcurrency, resultSetHoldability);
+ this.statements.add(stmt);
+ return stmt;
+ }
+
+ protected abstract Statement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException;
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return this.autoCommit;
+ }
+
+ public String getCatalog() throws SQLException {
+ return JenaMetadata.DEFAULT_CATALOG;
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return this.clientInfo;
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return this.clientInfo.getProperty(name);
+ }
+
+ public int getHoldability() throws SQLException {
+ return this.holdability;
+ }
+
+ public abstract DatabaseMetaData getMetaData() throws SQLException;
+
+ public int getTransactionIsolation() throws SQLException {
+ return this.isolationLevel;
+ }
+
+ public Map<String, Class<?>> getTypeMap() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return this.warnings;
+ }
+
+ public abstract boolean isClosed() throws SQLException;
+
+ public abstract boolean isReadOnly() throws SQLException;
+
+ public abstract boolean isValid(int timeout) throws SQLException;
+
+ public String nativeSQL(String sql) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public abstract PreparedStatement prepareStatement(String sql) throws SQLException;
+
+ public abstract PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException;
+
+ public abstract PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException;
+
+ public abstract PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException;
+
+ public abstract PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException;
+
+ public abstract PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException;
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public void rollback() throws SQLException {
+ if (this.isClosed())
+ throw new SQLException("Cannot rollback on a closed connection");
+ try {
+ // Get the implementation to do the actual rollback
+ this.rollbackInternal();
+
+ // Close any open statements if applicable
+ if (this.holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT) {
+ this.closeStatements();
+ }
+ } catch (SQLException e) {
+ // Throw as-is
+ throw e;
+ } catch (Exception e) {
+ throw new SQLException("Unexpected error rolling back transaction", e);
+ }
+ }
+
+ protected abstract void rollbackInternal() throws SQLException;
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ this.autoCommit = autoCommit;
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ this.clientInfo = properties;
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ this.clientInfo.put(name, value);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ this.checkHoldability(holdability);
+ this.holdability = holdability;
+ }
+
+ /**
+ * Helper method that checks whether the given holdability setting is valid,
+ * throws an error if it is not
+ *
+ * @param h
+ * Holdability Setting
+ * @throws SQLException
+ * Thrown if the setting is not valid
+ */
+ protected void checkHoldability(int h) throws SQLException {
+ switch (h) {
+ case ResultSet.CLOSE_CURSORS_AT_COMMIT:
+ case ResultSet.HOLD_CURSORS_OVER_COMMIT:
+ return;
+ default:
+ throw new SQLRecoverableException(String.format("%d is not a valid holdability setting", h));
+ }
+ }
+
+ public abstract void setReadOnly(boolean readOnly) throws SQLException;
+
+ public Savepoint setSavepoint() throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ this.checkTransactionIsolation(level);
+ this.isolationLevel = level;
+ }
+
+ /**
+ * Helper method which checks that a transaction isolation level is valid,
+ * should throw an exception if the given level is not valid for the
+ * connection
+ *
+ * @param level
+ * Isolation Level
+ * @throws SQLException
+ * Thrown if the isolation level is not valid
+ */
+ protected abstract void checkTransactionIsolation(int level) throws SQLException;
+
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ /**
+ * Helper method that derived classes may use to set warnings
+ *
+ * @param warning
+ * Warning
+ */
+ protected void setWarning(SQLWarning warning) {
+ if (this.warnings == null) {
+ this.warnings = warning;
+ } else {
+ // Chain with existing warnings
+ warning.setNextWarning(this.warnings);
+ this.warnings = warning;
+ }
+ }
+
+ /**
+ * Helper method that derived classes may use to set warnings
+ *
+ * @param warning
+ * Warning
+ */
+ protected void setWarning(String warning) {
+ this.setWarning(new SQLWarning(warning));
+ }
+
+ /**
+ * Helper method that derived classes may use to set warnings
+ *
+ * @param warning
+ * Warning
+ * @param cause
+ * Cause
+ */
+ protected void setWarning(String warning, Throwable cause) {
+ this.setWarning(new SQLWarning(warning, cause));
+ }
+
+}
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/DatasetMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/DatasetMetadata.java?rev=1464215&r1=1464214&r2=1464215&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/DatasetMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/DatasetMetadata.java Wed Apr 3 22:01:26 2013
@@ -26,7 +26,7 @@ import org.apache.jena.jdbc.connections.
* Abstract implementation of metadata for dataset connections
*
*/
-public abstract class DatasetMetadata extends JenaJdbcMetadata {
+public abstract class DatasetMetadata extends JenaMetadata {
/**
* Creates new metadata
Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaMetadata.java?rev=1464215&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaMetadata.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/metadata/JenaMetadata.java Wed Apr 3 22:01:26 2013
@@ -0,0 +1,944 @@
+/**
+ * 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.jena.jdbc.metadata;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+import org.apache.jena.jdbc.connections.JenaConnection;
+
+/**
+ * Database metadata for Jena JDBC connections
+ */
+public abstract class JenaMetadata implements DatabaseMetaData {
+
+ /**
+ * Constant for the term used for catalogues
+ */
+ public static final String CATALOG_TERM = "RDF Store";
+
+ /**
+ * Constant for the term used for schemas
+ */
+ public static final String SCHEMA_TERM = "Dataset";
+
+ /**
+ * Constant for the default catalog which is the only catalog we report as
+ * existing by default
+ */
+ public static final String DEFAULT_CATALOG = "RDF";
+
+ /**
+ * Constant for the default schema which is the only schema we report as
+ * existing by default
+ */
+ public static final String DEFAULT_SCHEMA = "Dataset";
+
+ protected static final int NO_LIMIT = 0;
+
+ protected static final int UNKNOWN_LIMIT = 0;
+
+ private JenaConnection connection;
+
+ /**
+ * Creates new connection metadata
+ *
+ * @param connection
+ * Connection
+ * @throws SQLException
+ */
+ public JenaMetadata(JenaConnection connection) throws SQLException {
+ if (connection == null)
+ throw new SQLException("Connection cannot be null");
+ this.connection = connection;
+ }
+
+ public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public <T> T unwrap(Class<T> arg0) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ public boolean allProceduresAreCallable() throws SQLException {
+ // Callable procedures not supported in SPARQL
+ return false;
+ }
+
+ public boolean allTablesAreSelectable() throws SQLException {
+ // There is a single table in RDF (the quads table) and it is selectable
+ return true;
+ }
+
+ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+ // Auto-commit failure does not close all result sets
+ return false;
+ }
+
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ // SPARQL Update causes a commit by default for non-transactional
+ // connections
+ return true;
+ }
+
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ // SPARQL Update is not ignored for non-transactional connections
+ return false;
+ }
+
+ public boolean deletesAreDetected(int arg0) throws SQLException {
+ // Since modification of result sets is not supported we can report
+ // true for the ability to detect row deletes
+ return true;
+ }
+
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ // There is no max row size in RDF/SPARQL
+ return true;
+ }
+
+ public ResultSet getAttributes(String arg0, String arg1, String arg2, String arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getBestRowIdentifier(String arg0, String arg1, String arg2, int arg3, boolean arg4) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getCatalogSeparator() throws SQLException {
+ // Use a . since that's what SQL would use AFAIK
+ return ".";
+ }
+
+ public String getCatalogTerm() throws SQLException {
+ return CATALOG_TERM;
+ }
+
+ public ResultSet getCatalogs() throws SQLException {
+ // TODO Requires a result set implementation that can be appropriately
+ // configured
+
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getClientInfoProperties() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getColumnPrivileges(String arg0, String arg1, String arg2, String arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getColumns(String arg0, String arg1, String arg2, String arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public final Connection getConnection() throws SQLException {
+ return this.connection;
+ }
+
+ public ResultSet getCrossReference(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5)
+ throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public abstract int getDatabaseMajorVersion() throws SQLException;
+
+ public abstract int getDatabaseMinorVersion() throws SQLException;
+
+ public abstract String getDatabaseProductName() throws SQLException;
+
+ public abstract String getDatabaseProductVersion() throws SQLException;
+
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return Connection.TRANSACTION_NONE;
+ }
+
+ public abstract int getDriverMajorVersion();
+
+ public abstract int getDriverMinorVersion();
+
+ public abstract String getDriverName() throws SQLException;
+
+ public abstract String getDriverVersion() throws SQLException;
+
+ public ResultSet getExportedKeys(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getExtraNameCharacters() throws SQLException {
+ // Since SPARQL doesn't really have a notion of identifiers like SQL
+ // does
+ // we return that there are no extra name characters
+ return "";
+ }
+
+ public ResultSet getFunctionColumns(String arg0, String arg1, String arg2, String arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getFunctions(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getIdentifierQuoteString() throws SQLException {
+ // Not supported in SPARQL so return space per the JDBC javadoc
+ return " ";
+ }
+
+ public ResultSet getImportedKeys(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getIndexInfo(String arg0, String arg1, String arg2, boolean arg3, boolean arg4) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public final int getJDBCMajorVersion() throws SQLException {
+ return 4;
+ }
+
+ public final int getJDBCMinorVersion() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ // No limit on RDF term sizes
+ return NO_LIMIT;
+ }
+
+ public int getMaxCatalogNameLength() throws SQLException {
+ // No limit on catalog name lengths because we don't
+ // really support catalogs
+ return NO_LIMIT;
+ }
+
+ public int getMaxCharLiteralLength() throws SQLException {
+ // No limit on RDF term sizes
+ return NO_LIMIT;
+ }
+
+ public int getMaxColumnNameLength() throws SQLException {
+ // No limit on column name lengths
+ return NO_LIMIT;
+ }
+
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ // SPARQL allows arbitrarily many columns in a GROUP BY
+ return NO_LIMIT;
+ }
+
+ public int getMaxColumnsInIndex() throws SQLException {
+ // RDF stores typically index on up to 3 columns since there are only 4
+ // columns
+ return 3;
+ }
+
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ // SPARQL allows arbitrarily many columns in ORDER BY
+ return NO_LIMIT;
+ }
+
+ public int getMaxColumnsInSelect() throws SQLException {
+ // SPARQL allows arbitrarily many columns in SELECT clause
+ return NO_LIMIT;
+ }
+
+ public int getMaxColumnsInTable() throws SQLException {
+ // RDF stores have up to 4 columns
+ return 4;
+ }
+
+ public int getMaxConnections() throws SQLException {
+ // Max connections will typically be unlimited
+ return NO_LIMIT;
+ }
+
+ public int getMaxCursorNameLength() throws SQLException {
+ // Named cursors aren't supported so there is no limit
+ return UNKNOWN_LIMIT;
+ }
+
+ public int getMaxIndexLength() throws SQLException {
+ // RDF stores typically have no limit on index size, they are as big as
+ // they need to be
+ return NO_LIMIT;
+ }
+
+ public int getMaxProcedureNameLength() throws SQLException {
+ // Procedures aren't supported so unknown
+ return UNKNOWN_LIMIT;
+ }
+
+ public int getMaxRowSize() throws SQLException {
+ // No limit on triple size
+ return NO_LIMIT;
+ }
+
+ public int getMaxSchemaNameLength() throws SQLException {
+ // We don't really support schemas so there is no limit
+ return NO_LIMIT;
+ }
+
+ public int getMaxStatementLength() throws SQLException {
+ // SPARQL Queries/Updates may be arbitrarily large
+ return NO_LIMIT;
+ }
+
+ public int getMaxStatements() throws SQLException {
+ // We don't impose any limit on this
+ return NO_LIMIT;
+ }
+
+ public int getMaxTableNameLength() throws SQLException {
+ // We don't support tables so there is no limit
+ return NO_LIMIT;
+ }
+
+ public int getMaxTablesInSelect() throws SQLException {
+ // No limit
+ return NO_LIMIT;
+ }
+
+ public int getMaxUserNameLength() throws SQLException {
+ // Authentication is an implementation specific detail so unknown
+ return UNKNOWN_LIMIT;
+ }
+
+ public String getNumericFunctions() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getPrimaryKeys(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getProcedureColumns(String arg0, String arg1, String arg2, String arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getProcedureTerm() throws SQLException {
+ // Not supported
+ return null;
+ }
+
+ public ResultSet getProcedures(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return JenaConnection.DEFAULT_HOLDABILITY;
+ }
+
+ public RowIdLifetime getRowIdLifetime() throws SQLException {
+ // Not supported
+ return RowIdLifetime.ROWID_UNSUPPORTED;
+ }
+
+ public String getSQLKeywords() throws SQLException {
+ // TODO Use http://developer.mimer.com/validator/sql-reserved-words.tml
+ // as a reference to implement this
+ return null;
+ }
+
+ public int getSQLStateType() throws SQLException {
+ return sqlStateXOpen;
+ }
+
+ public String getSchemaTerm() throws SQLException {
+ return SCHEMA_TERM;
+ }
+
+ public ResultSet getSchemas() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getSchemas(String arg0, String arg1) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getSearchStringEscape() throws SQLException {
+ // Does not apply to SPARQL
+ return "";
+ }
+
+ public String getStringFunctions() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getSuperTables(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getSuperTypes(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getSystemFunctions() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getTablePrivileges(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getTableTypes() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getTables(String arg0, String arg1, String arg2, String[] arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getTimeDateFunctions() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getTypeInfo() throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ResultSet getUDTs(String arg0, String arg1, String arg2, int[] arg3) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public abstract String getURL() throws SQLException;
+
+ public String getUserName() throws SQLException {
+ // No authentication used by default
+ return null;
+ }
+
+ public ResultSet getVersionColumns(String arg0, String arg1, String arg2) throws SQLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean insertsAreDetected(int arg0) throws SQLException {
+ // We can't detect inserts that happen while streaming results
+ return false;
+ }
+
+ public boolean isCatalogAtStart() throws SQLException {
+ // We don't really support catalogs so we'll say yes
+ return true;
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return this.connection.isReadOnly();
+ }
+
+ public boolean locatorsUpdateCopy() throws SQLException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ // Concatenating nulls (i.e. unbound/type error) in SPARQL results
+ // leads to nulls
+ return true;
+ }
+
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ // SPARQL sort order puts nulls (i.e. unbound) first
+ return false;
+ }
+
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ // SPARQL sort order puts nulls (i.e. unbound) first
+ return true;
+ }
+
+ public boolean nullsAreSortedHigh() throws SQLException {
+ // SPARQL sort order puts nulls (i.e. unbound) first
+ return false;
+ }
+
+ public boolean nullsAreSortedLow() throws SQLException {
+ // SPARQL sort order puts nulls (i.e. unbound) first
+ return true;
+ }
+
+ public boolean othersDeletesAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see deletes from
+ // others depending on the underlying implementation
+ return true;
+ }
+
+ public boolean othersInsertsAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see inserts from
+ // others depending on the underlying implementation
+ return true;
+ }
+
+ public boolean othersUpdatesAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see updates from
+ // others depending on the underlying implementation
+ return true;
+ }
+
+ public boolean ownDeletesAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see deletes from
+ // ourselves depending on the underlying implementation
+ return true;
+ }
+
+ public boolean ownInsertsAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see inserts from
+ // ourselves depending on the underlying implementation
+ return true;
+ }
+
+ public boolean ownUpdatesAreVisible(int arg0) throws SQLException {
+ // Since results are streamed it may be possible to see deletes from
+ // others depending on the underlying implementation
+ return true;
+ }
+
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ // We don't support identifiers in the way that JDBC means so we say
+ // false
+ return false;
+ }
+
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ // Schema alteration is not supported
+ return false;
+ }
+
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ // Schema alteration is not supported
+ return false;
+ }
+
+ public boolean supportsBatchUpdates() throws SQLException {
+ // Batch updates are implemented
+ return true;
+ }
+
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ // We don't really support catalogs so using them in SPARQL Update is
+ // not permitted
+ return false;
+ }
+
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ // Custom indexes are not supported
+ return false;
+ }
+
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ // SPARQL has no privilege definition statements
+ return false;
+ }
+
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ // SPARQL has no procedure calls
+ return false;
+ }
+
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ // SPARQL has no table definition statements
+ return false;
+ }
+
+ public boolean supportsColumnAliasing() throws SQLException {
+ // SPARQL requires aliasing for computed columns
+ return true;
+ }
+
+ public boolean supportsConvert() throws SQLException {
+ // JDBC convert is not supported
+ return false;
+ }
+
+ public boolean supportsConvert(int arg0, int arg1) throws SQLException {
+ // JDBC convert is not supported
+ return false;
+ }
+
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ // SPARQL supports sub-queries
+ return true;
+ }
+
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+ // SPARQL update may be used within a transaction
+ return true;
+ }
+
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ // Transactions may consist only of SPARQL updates
+ return true;
+ }
+
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ // We don't support tables as such so no
+ return false;
+ }
+
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ // SPARQL allows expressions in ORDER BY
+ return true;
+ }
+
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsFullOuterJoins() throws SQLException {
+ // SPARQL supports all sorts of joins
+ return true;
+ }
+
+ public boolean supportsGetGeneratedKeys() throws SQLException {
+ // SPARQL has no notion of auto-generated keys (you can argue that
+ // UUID() counts) but we certainly can't return them
+ return true;
+ }
+
+ public boolean supportsGroupBy() throws SQLException {
+ // SPARQL supports GROUP BY
+ return true;
+ }
+
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ // You can GROUP BY a column that you don't select in SPARQL
+ return true;
+ }
+
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ // You can GROUP BY a column that you don't select in SPARQL
+ return true;
+ }
+
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ // Integrity Enhancement SQL is not supported
+ return false;
+ }
+
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ // No LIKE in SPARQL
+ return false;
+ }
+
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ // SPARQL supports all kinds of joins
+ return true;
+ }
+
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ // We don't support SQL
+ return false;
+ }
+
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ // We have no direct equivalent to SQL identifiers
+ return false;
+ }
+
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ // We have no direct equivalent to SQL identifiers
+ return false;
+ }
+
+ public boolean supportsMultipleOpenResults() throws SQLException {
+ // We support multiple open results
+ return true;
+ }
+
+ public boolean supportsMultipleResultSets() throws SQLException {
+ // We don't support multiple result sets from a single execute() call,
+ // we do support this from executeBatch()
+ return false;
+ }
+
+ public boolean supportsMultipleTransactions() throws SQLException {
+ // In principle yes this is possible though exact behaviour may vary by
+ // underlying implementation
+ return true;
+ }
+
+ public boolean supportsNamedParameters() throws SQLException {
+ // We don't support callable statements
+ return false;
+ }
+
+ public boolean supportsNonNullableColumns() throws SQLException {
+ // All columns in a RDF store are non-nullable
+ return true;
+ }
+
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ // Cursors may be closed depending on the type of commit
+ return false;
+ }
+
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ // Cursors may be closed depending on the type of commit
+ return false;
+ }
+
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ // Statements remain open across commits
+ return true;
+ }
+
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ // Statements remain open across rollbacks
+ return true;
+ }
+
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ // SPARQL allows ORDER BY on a column that you don't SELECT
+ return true;
+ }
+
+ public boolean supportsOuterJoins() throws SQLException {
+ // SPARQL supports all kinds of joins
+ return true;
+ }
+
+ public boolean supportsPositionedDelete() throws SQLException {
+ // We don't support deleting from result set
+ return false;
+ }
+
+ public boolean supportsPositionedUpdate() throws SQLException {
+ // We don't support updating from result set
+ return false;
+ }
+
+ public boolean supportsResultSetConcurrency(int arg0, int arg1) throws SQLException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean supportsResultSetHoldability(int arg0) throws SQLException {
+ // Both kinds of holdability are supported
+ return true;
+ }
+
+ public boolean supportsResultSetType(int arg0) throws SQLException {
+ // Currently only FORWARD_ONLY is supported
+ switch (arg0) {
+ case ResultSet.TYPE_FORWARD_ONLY:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean supportsSavepoints() throws SQLException {
+ // No notion of savepoints
+ return false;
+ }
+
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ // We don't really support schemas
+ return false;
+ }
+
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ // RDF stores don't allow custom indices
+ return false;
+ }
+
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ // SPARQL has no privilege definition statements
+ return false;
+ }
+
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ // SPARQL has no procedure calls
+ return false;
+ }
+
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ // We don't really support schemas
+ return false;
+ }
+
+ public boolean supportsSelectForUpdate() throws SQLException {
+ // No SPARQL equivalent
+ return false;
+ }
+
+ public boolean supportsStatementPooling() throws SQLException {
+ // We don't do pooling
+ return false;
+ }
+
+ public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+ // Stored procedures are not supported in SPARQL
+ return false;
+ }
+
+ public boolean supportsStoredProcedures() throws SQLException {
+ // Stored procedures are not supported in SPARQL
+ return false;
+ }
+
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ // Can't use subqueries in this way in SPARQL
+ return false;
+ }
+
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ // SPARQL does allow sub-queries in EXISTS though strictly speaking our
+ // EXISTS has no relation to the SQL equivalent
+ return true;
+ }
+
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ // Can't use subqueries in this way in SPARQL
+ return false;
+ }
+
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ // I have no idea what this mean so assume we can't use sub-queries this
+ // way in SPARQL
+ return false;
+ }
+
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ // We don't really support tables
+ return false;
+ }
+
+ public boolean supportsTransactionIsolationLevel(int arg0) throws SQLException {
+ // Currently only None or Serializable is supported
+ switch (arg0) {
+ case Connection.TRANSACTION_NONE:
+ case Connection.TRANSACTION_SERIALIZABLE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean supportsTransactions() throws SQLException {
+ // Currently transactions are not supported
+ return false;
+ }
+
+ public boolean supportsUnion() throws SQLException {
+ // SPARQL supports UNION
+ return true;
+ }
+
+ public boolean supportsUnionAll() throws SQLException {
+ // No SPARQL equivalent of UNION ALL
+ return false;
+ }
+
+ public boolean updatesAreDetected(int arg0) throws SQLException {
+ // Updates are never detectable
+ return false;
+ }
+
+ public abstract boolean usesLocalFilePerTable() throws SQLException;
+
+ public abstract boolean usesLocalFiles() throws SQLException;
+
+}
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java?rev=1464215&r1=1464214&r2=1464215&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java Wed Apr 3 22:01:26 2013
@@ -34,20 +34,23 @@ import com.hp.hpl.jena.graph.NodeFactory
* Represents an ASK result
*
*/
-public class AskResults extends JenaJdbcResultSet {
+public class AskResults extends JenaResultSet {
private boolean result, closed = false;
private int currRow = 0;
+ private boolean needsCommit = false;
/**
* Creates a new ASK result
* @param statement Statement
* @param result Boolean result
+ * @param commit Whether a commit is required when the results are closed
* @throws SQLException Thrown if the arguments are invalid
*/
- public AskResults(Statement statement, boolean result) throws SQLException {
+ public AskResults(Statement statement, boolean result, boolean commit) throws SQLException {
super(statement);
this.result = result;
+ this.needsCommit = commit;
}
public boolean absolute(int row) throws SQLException {
@@ -75,7 +78,11 @@ public class AskResults extends JenaJdbc
}
public void close() throws SQLException {
+ if (this.closed) return;
this.closed = true;
+ if (this.needsCommit) {
+ this.getStatement().getConnection().commit();
+ }
}
public int findColumn(String columnLabel) throws SQLException {