All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.modeshape.jdbc.JcrStatement Maven / Gradle / Ivy

Go to download

JDBC driver to allow clients to use JCR-SQL2 to query a ModeShape JCR repository within the same JVM process.

There is a newer version: 5.4.1.Final
Show newest version
/*
 * ModeShape (http://www.modeshape.org)
 *
 * Licensed 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.modeshape.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
import javax.jcr.RepositoryException;
import javax.jcr.query.QueryResult;
import org.modeshape.jdbc.delegate.RepositoryDelegate;

class JcrStatement implements Statement {

    private final JcrConnection connection;
    private ResultSet results;
    private boolean closed;
    private SQLWarning warning;
    private int rowLimit = -1;
    private int fetchDirection = ResultSet.FETCH_FORWARD;
    private boolean poolable;
    private int moreResults = 0;

    private String sqlLanguage = JcrConnection.JCR_SQL2;

    JcrStatement( JcrConnection connection ) {
        this.connection = connection;
        assert this.connection != null;
    }

    JcrConnection connection() {
        return this.connection;
    }

    public void setJcrSqlLanguage( String jcrSQL ) {
        this.sqlLanguage = (jcrSQL != null ? jcrSQL : JcrConnection.JCR_SQL2);
    }

    /**
     * {@inheritDoc}
     * 

* This driver doesn't have a way to set the fetch size, so this method always returns 0. *

* * @see java.sql.Statement#getFetchSize() */ @Override public int getFetchSize() throws SQLException { notClosed(); return 0; } /** * {@inheritDoc} *

* This driver doesn't have a way to set the fetch size, so this method is ignored and does nothing. *

* * @see java.sql.Statement#setFetchSize(int) */ @Override public void setFetchSize( int rows ) throws SQLException { notClosed(); } @Override public int getFetchDirection() throws SQLException { notClosed(); return fetchDirection; } @Override public void setFetchDirection( int direction ) throws SQLException { notClosed(); if (direction != ResultSet.FETCH_FORWARD && direction != ResultSet.FETCH_REVERSE && direction != ResultSet.FETCH_UNKNOWN) { throw new SQLException(JdbcLocalI18n.invalidArgument.text(direction, "" + ResultSet.FETCH_FORWARD + ", " + ResultSet.FETCH_REVERSE + ", " + ResultSet.FETCH_UNKNOWN)); } fetchDirection = direction; } /** * {@inheritDoc} *

* This driver does not support limiting the field size, and always returns 0. *

* * @see java.sql.Statement#getMaxFieldSize() */ @Override public int getMaxFieldSize() throws SQLException { notClosed(); return 0; } @Override public void setMaxFieldSize( int max ) throws SQLException { notClosed(); if (max < 0) { throw new SQLException(JdbcLocalI18n.argumentMayNotBeNegative.text("max", max)); } // ignored otherwise } @Override public int getMaxRows() throws SQLException { notClosed(); // need to map ModeShapes -1 rowLimit to 0 // because the jdbc spec indicate maxRows must be >= 0 // or an exception should be thrown. return (rowLimit == -1 ? 0 : rowLimit); } @Override public void setMaxRows( int max ) throws SQLException { notClosed(); if (max < 0) { throw new SQLException(JdbcLocalI18n.argumentMayNotBeNegative.text("max", max)); } rowLimit = max; } /** * {@inheritDoc} *

* This method returns 0 since there is currently no timeout with JCR 1.0 or JCR 2.0. *

* * @see java.sql.Statement#getQueryTimeout() */ @Override public int getQueryTimeout() throws SQLException { notClosed(); return 0; } @Override public void setQueryTimeout( int seconds ) throws SQLException { notClosed(); if (seconds < 0) { throw new SQLException(JdbcLocalI18n.argumentMayNotBeNegative.text("seconds", seconds)); } // Otherwise ignore } @Override public boolean isPoolable() throws SQLException { notClosed(); return poolable; } @Override public void setPoolable( boolean poolable ) throws SQLException { notClosed(); this.poolable = poolable; } @Override public Connection getConnection() throws SQLException { notClosed(); return connection; } @Override public void cancel() throws SQLException { notClosed(); close(); // Unable to cancel a JCR query ... } @Override public void clearWarnings() throws SQLException { notClosed(); warning = null; } @Override public SQLWarning getWarnings() throws SQLException { notClosed(); return warning; } @Override public boolean isClosed() { return closed || connection.isClosed(); } @Override public void close() { if (!closed) { closed = true; connection.getRepositoryDelegate().closeStatement(); } } protected final void notClosed() throws SQLException { if (isClosed()) throw new SQLException(JdbcLocalI18n.statementIsClosed.text()); } protected final void noUpdates() throws SQLException { throw new SQLException(JdbcLocalI18n.updatesNotSupported.text()); } // ---------------------------------------------------------------------------------------------------------------- // Updates // ---------------------------------------------------------------------------------------------------------------- @Override public int executeUpdate( String sql ) throws SQLException { notClosed(); noUpdates(); return 0; } @Override public int executeUpdate( String sql, int autoGeneratedKeys ) throws SQLException { notClosed(); noUpdates(); return 0; } @Override public int executeUpdate( String sql, int[] columnIndexes ) throws SQLException { notClosed(); noUpdates(); return 0; } @Override public int executeUpdate( String sql, String[] columnNames ) throws SQLException { notClosed(); noUpdates(); return 0; } @Override public void setCursorName( String name ) throws SQLException { notClosed(); noUpdates(); } @Override public int getUpdateCount() throws SQLException { notClosed(); return -1; } @Override public void addBatch( String sql ) throws SQLException { notClosed(); noUpdates(); } @Override public void clearBatch() throws SQLException { notClosed(); noUpdates(); } @Override public int[] executeBatch() throws SQLException { notClosed(); noUpdates(); return null; } // ---------------------------------------------------------------------------------------------------------------- // Queries // ---------------------------------------------------------------------------------------------------------------- @Override public boolean execute( String sql ) throws SQLException { notClosed(); warning = null; moreResults = 0; try { // Convert the supplied SQL into JCR-SQL2 ... String jcrSql2 = connection.nativeSQL(sql); // Create the query ... final QueryResult jcrResults = getJcrRepositoryDelegate().execute(jcrSql2, this.sqlLanguage); results = new JcrResultSet(this, jcrResults, null); moreResults = 1; } catch (RepositoryException e) { throw new SQLException(e.getLocalizedMessage(), e); } return true; // always a ResultSet } protected RepositoryDelegate getJcrRepositoryDelegate() { return this.connection.getRepositoryDelegate(); } @Override public boolean execute( String sql, int autoGeneratedKeys ) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override public boolean execute( String sql, int[] columnIndexes ) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override public boolean execute( String sql, String[] columnNames ) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override public ResultSet executeQuery( String sql ) throws SQLException { execute(sql); return getResultSet(); } @Override public ResultSet getGeneratedKeys() /*throws SQLException*/{ // TODO: if and when ModeShape supports providing key information // then a result set containing the metadata will need to be created. return new JcrResultSet(); } @Override public boolean getMoreResults() throws SQLException { notClosed(); return moreResults > 0; } @Override public boolean getMoreResults( int current ) throws SQLException { notClosed(); if (current != CLOSE_ALL_RESULTS && current != CLOSE_CURRENT_RESULT && current != KEEP_CURRENT_RESULT) { throw new SQLException(JdbcLocalI18n.invalidArgument.text(current, "" + CLOSE_ALL_RESULTS + ", " + CLOSE_CURRENT_RESULT + ", " + KEEP_CURRENT_RESULT)); } if (KEEP_CURRENT_RESULT != current) { // Close (by nulling) the results ... // jcrResults = null; results = null; } if (moreResults > 0) --moreResults; return moreResults > 0; } @Override public ResultSet getResultSet() throws SQLException { notClosed(); return results; // may be null } @Override public int getResultSetConcurrency() throws SQLException { notClosed(); return ResultSet.CONCUR_READ_ONLY; } @Override public int getResultSetHoldability() throws SQLException { notClosed(); return ResultSet.CLOSE_CURSORS_AT_COMMIT; } @Override public int getResultSetType() throws SQLException { notClosed(); return ResultSet.TYPE_SCROLL_INSENSITIVE; } @Override public void setEscapeProcessing( boolean enable ) throws SQLException { notClosed(); // Ignore for now } @Override public boolean isWrapperFor( Class iface ) /*throws SQLException*/{ return iface.isInstance(this); } @Override public T unwrap( Class iface ) throws SQLException { if (!isWrapperFor(iface)) { throw new SQLException(JdbcLocalI18n.classDoesNotImplementInterface.text(Statement.class.getSimpleName(), iface.getName())); } return iface.cast(this); } @Override public void closeOnCompletion() { } @Override public boolean isCloseOnCompletion() { return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy