db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/src/java/org/apache/ojb/broker/platforms Platform.java PlatformHsqldbImpl.java PlatformSapdbImpl.java
Date Sat, 04 Jun 2005 14:13:43 GMT
arminw      2005/06/04 07:13:43

  Modified:    src/java/org/apache/ojb/broker/accesslayer Tag:
                        OJB_1_0_RELEASE JdbcAccessImpl.java
                        StatementManager.java StatementManagerIF.java
                        StatementsForClassIF.java
                        StatementsForClassImpl.java
               src/java/org/apache/ojb/broker/platforms Tag:
                        OJB_1_0_RELEASE Platform.java
                        PlatformHsqldbImpl.java PlatformSapdbImpl.java
  Log:
  replace Platform#isCallableStatement method and introduce an contract between JdbcAccess
and StatementManager to detect the use of stored procedures.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.22.2.6  +59 -20    db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
  
  Index: JdbcAccessImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java,v
  retrieving revision 1.22.2.5
  retrieving revision 1.22.2.6
  diff -u -r1.22.2.5 -r1.22.2.6
  --- JdbcAccessImpl.java	26 Apr 2005 03:41:35 -0000	1.22.2.5
  +++ JdbcAccessImpl.java	4 Jun 2005 14:13:43 -0000	1.22.2.6
  @@ -177,7 +177,7 @@
           {
               final String sql = this.broker.serviceSqlGenerator().getPreparedDeleteStatement(query,
cld);
               stmt = broker.serviceStatementManager().getPreparedStatement(cld, sql,
  -                    false, StatementManagerIF.FETCH_SIZE_NOT_APPLICABLE);
  +                    false, StatementManagerIF.FETCH_SIZE_NOT_APPLICABLE, cld.getDeleteProcedure()!=null);
   
               broker.serviceStatementManager().bindStatement(stmt, query, cld, 1);
               if (logger.isDebugEnabled())
  @@ -316,12 +316,13 @@
           {
               final int queryFetchSize = query.getFetchSize();
               final String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query,
cld);
  +            final boolean isStoredProcedure = isStoredProcedure(sql);
               final PreparedStatement stmt;
               stmt = broker.serviceStatementManager().getPreparedStatement(cld, sql,
  -                    scrollable, queryFetchSize);
  +                    scrollable, queryFetchSize, isStoredProcedure);
   
               ResultSet rs;
  -            if (getPlatform().isCallableStatement(stmt))
  +            if (isStoredProcedure)
               {
                   // Query implemented as a stored procedure, which must return a result
set.
                   // Query sytax is: { ?= call PROCEDURE_NAME(?,...,?)}
  @@ -404,15 +405,16 @@
           throws PersistenceBrokerException
       {
           if (logger.isDebugEnabled()) logger.debug("executeSQL: " + sqlStatement);
  +        final boolean isStoredprocedure = isStoredProcedure(sqlStatement);
           StatementManagerIF stmtMan = broker.serviceStatementManager();
           ResultSetAndStatement retval = null;
           try
           {
               final PreparedStatement stmt = stmtMan.getPreparedStatement(cld, sqlStatement,
  -                    scrollable, StatementManagerIF.FETCH_SIZE_NOT_EXPLICITLY_SET);
  +                    scrollable, StatementManagerIF.FETCH_SIZE_NOT_EXPLICITLY_SET, isStoredprocedure);
   
               ResultSet rs;
  -            if (getPlatform().isCallableStatement(stmt))
  +            if (isStoredprocedure)
               {
                   // Query implemented as a stored procedure, which must return a result
set.
                   // Query sytax is: { ?= call PROCEDURE_NAME(?,...,?)}
  @@ -492,7 +494,7 @@
           try
           {
               stmt = stmtMan.getPreparedStatement(cld, sqlStatement,
  -                    Query.NOT_SCROLLABLE, StatementManagerIF.FETCH_SIZE_NOT_APPLICABLE);
  +                    Query.NOT_SCROLLABLE, StatementManagerIF.FETCH_SIZE_NOT_APPLICABLE,
isStoredProcedure(sqlStatement));
               index = stmtMan.bindValues(stmt, values1, 1);
               index = stmtMan.bindValues(stmt, values2, index);
               result = stmt.executeUpdate();
  @@ -630,18 +632,12 @@
                   logger.error("getSelectByPKStatement returned a null statement");
                   throw new PersistenceBrokerException("getSelectByPKStatement returned a
null statement");
               }
  -            broker.serviceStatementManager().bindSelect(stmt, oid, cld);
  -
  -            if (getPlatform().isCallableStatement(stmt))
  -            {
  -                // If this is a stored procedure call, first argument is ResultSet
  -                stmt.execute();
  -                rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
  -            }
  -            else
  -            {
  -                rs = stmt.executeQuery();
  -            }
  +            /*
  +            arminw: currently a select by PK could never be a stored procedure,
  +            thus we can always set 'false'. Is this correct??
  +            */
  +            broker.serviceStatementManager().bindSelect(stmt, oid, cld, false);
  +            rs = stmt.executeQuery();
   
               // data available read object, else return null
               if (rs.next())
  @@ -716,7 +712,7 @@
       {
           // If the procedure descriptor is null or has no return values or
           // if the statement is not a callable statment, then we're done.
  -        if ((proc == null) || (!proc.hasReturnValues()) || (!getPlatform().isCallableStatement(stmt)))
  +        if ((proc == null) || (!proc.hasReturnValues()))
           {
               return;
           }
  @@ -800,4 +796,47 @@
               throw new PersistenceBrokerSQLException(msg, e);
           }
       }
  +
  +    /**
  +     * Check if the specified sql-string is a stored procedure
  +     * or not.
  +     * @param sql The sql query to check
  +     * @return <em>True</em> if the query is a stored procedure, else <em>false</em>
is returned.
  +     */
  +    protected boolean isStoredProcedure(String sql)
  +    {
  +        /*
  +        Stored procedures start with
  +        {?= call <procedure-name>[<arg1>,<arg2>, ...]}
  +        or
  +        {call <procedure-name>[<arg1>,<arg2>, ...]}
  +        but also statements with white space like
  +        { ?= call <procedure-name>[<arg1>,<arg2>, ...]}
  +        are possible.
  +        */
  +        int k = 0, i = 0;
  +        char c;
  +        while(k < 3 && i < sql.length())
  +        {
  +            c = sql.charAt(i);
  +            if(c != ' ')
  +            {
  +                switch (k)
  +                {
  +                    case 0:
  +                        if(c != '{') return false;
  +                        break;
  +                    case 1:
  +                        if(c != '?' && c != 'c') return false;
  +                        break;
  +                    case 2:
  +                        if(c != '=' && c != 'a') return false;
  +                        break;
  +                }
  +                k++;
  +            }
  +            i++;
  +        }
  +        return true;
  +    }
   }
  
  
  
  1.47.2.5  +20 -6     db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
  
  Index: StatementManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
  retrieving revision 1.47.2.4
  retrieving revision 1.47.2.5
  diff -u -r1.47.2.4 -r1.47.2.5
  --- StatementManager.java	26 Apr 2005 03:41:35 -0000	1.47.2.4
  +++ StatementManager.java	4 Jun 2005 14:13:43 -0000	1.47.2.5
  @@ -451,7 +451,7 @@
       /**
        * Binds the Identities Primary key values to the statement.
        */
  -    public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws
SQLException
  +    public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld, boolean
callableStmt) throws SQLException
       {
           ValueContainer[] values = null;
           int i = 0;
  @@ -463,7 +463,7 @@
           }
           try
           {
  -            if (m_platform.isCallableStatement(stmt))
  +            if(callableStmt)
               {
                   // First argument is the result set
                   m_platform.registerOutResultSet((CallableStatement) stmt, 1);
  @@ -601,12 +601,12 @@
        * return a generic Statement for the given ClassDescriptor
        */
       public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql,
  -                                                  boolean scrollable, int explicitFetchSizeHint)
  +                                                  boolean scrollable, int explicitFetchSizeHint,
boolean callableStmt)
               throws PersistenceBrokerException
       {
           try
           {
  -            return cds.getStatementsForClass(m_conMan).getPreparedStmt(m_conMan.getConnection(),
sql, scrollable, explicitFetchSizeHint);
  +            return cds.getStatementsForClass(m_conMan).getPreparedStmt(m_conMan.getConnection(),
sql, scrollable, explicitFetchSizeHint, callableStmt);
           }
           catch (LookupException e)
           {
  @@ -709,10 +709,24 @@
           // Figure out if we are using a callable statement.  If we are, then we
           // will need to register one or more output parameters.
           CallableStatement callable = null;
  -        if (m_platform.isCallableStatement(stmt))
  +        try
           {
               callable = (CallableStatement) stmt;
           }
  +        catch(Exception e)
  +        {
  +            m_log.error("Error while bind values for class '" + (cld != null ? cld.getClassNameOfObject()
: null)
  +                    + "', using stored procedure: "+ proc, e);
  +            if(e instanceof SQLException)
  +            {
  +                throw (SQLException) e;
  +            }
  +            else
  +            {
  +                throw new PersistenceBrokerException("Unexpected error while bind values
for class '"
  +                        + (cld != null ? cld.getClassNameOfObject() : null) + "', using
stored procedure: "+ proc);
  +            }
  +        }
   
           // If we have a return value, then register it.
           if ((proc.hasReturnValue()) && (callable != null))
  
  
  
  1.10.2.2  +5 -3      db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManagerIF.java
  
  Index: StatementManagerIF.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManagerIF.java,v
  retrieving revision 1.10.2.1
  retrieving revision 1.10.2.2
  diff -u -r1.10.2.1 -r1.10.2.2
  --- StatementManagerIF.java	26 Apr 2005 03:41:35 -0000	1.10.2.1
  +++ StatementManagerIF.java	4 Jun 2005 14:13:43 -0000	1.10.2.2
  @@ -67,8 +67,10 @@
        * @param stmt
        * @param oid
        * @param cld ClassDescriptor for the Object, if <i>null</i> will be lookup
automatic
  +     * @param callableStmt Indicate if the specified {@link java.sql.PreparedStatement}
  +     * is a {@link java.sql.CallableStatement} supporting stored procedures.
        */
  -    void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException;
  +    void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld, boolean
callableStmt) throws SQLException;
       /**
        * binds the values of the object obj to the statements parameters
        */
  @@ -100,7 +102,7 @@
        * Return a PreparedStatement for selecting against the given ClassDescriptor.
        */
       PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql,
  -                                           boolean scrollable, int explicitFetchSizeHint)
  +                                           boolean scrollable, int explicitFetchSizeHint,
boolean callableStmt)
           throws PersistenceBrokerException;
       /**
        * return a prepared Select Statement for the given ClassDescriptor
  
  
  
  1.10.2.2  +8 -15     db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassIF.java
  
  Index: StatementsForClassIF.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassIF.java,v
  retrieving revision 1.10.2.1
  retrieving revision 1.10.2.2
  diff -u -r1.10.2.1 -r1.10.2.2
  --- StatementsForClassIF.java	26 Apr 2005 03:41:35 -0000	1.10.2.1
  +++ StatementsForClassIF.java	4 Jun 2005 14:13:43 -0000	1.10.2.2
  @@ -33,50 +33,43 @@
   
   public interface StatementsForClassIF
   {
  -    
   	/**
  -     * returns the DELETE Statement used for clazz.
  +     * Returns the DELETE Statement used for clazz.
        * @return java.sql.PreparedStatement
        */
  -
   	PreparedStatement getDeleteStmt(Connection con) throws SQLException;
   
   	/**
  -     * returns a generic unprepared Statement used for clazz.
  +     * Returns a generic unprepared Statement used for clazz.
        * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
        * @return java.sql.Statement
        */
  -
   	Statement getGenericStmt(Connection con, boolean scrollable) throws PersistenceBrokerSQLException;
   
   	/**
  -     * returns the INSERT Statement used for clazz.
  +     * Returns the INSERT Statement used for clazz.
        * @return java.sql.PreparedStatement
        */
   
   	PreparedStatement getInsertStmt(Connection con) throws SQLException;
   
   	/**
  -     * returns a prepared Statement used for clazz.
  +     * Returns a prepared Statement used for clazz.
        * @return java.sql.Statement
        */
  -
   	PreparedStatement getPreparedStmt(Connection con, String sql,
  -                                      boolean scrollable, int explicitFetchSizeHint)
  +                                      boolean scrollable, int explicitFetchSizeHint, boolean
callableStmt)
               throws PersistenceBrokerSQLException;
   
   	/**
  -     * returns the SELECT Statement used for clazz.
  +     * Returns the SELECT Statement used for clazz.
        * @return java.sql.PreparedStatement
        */
  -
   	PreparedStatement getSelectByPKStmt(Connection con) throws SQLException;
   
   	/**
  -     * returns the UPDATE Statement used for clazz.
  +     * Returns the UPDATE Statement used for clazz.
        * @return java.sql.PreparedStatement
        */
  -
   	PreparedStatement getUpdateStmt(Connection con) throws SQLException;
  -
   }
  
  
  
  1.22.2.5  +3 -9      db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassImpl.java
  
  Index: StatementsForClassImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassImpl.java,v
  retrieving revision 1.22.2.4
  retrieving revision 1.22.2.5
  diff -u -r1.22.2.4 -r1.22.2.5
  --- StatementsForClassImpl.java	7 May 2005 16:43:05 -0000	1.22.2.4
  +++ StatementsForClassImpl.java	4 Jun 2005 14:13:43 -0000	1.22.2.5
  @@ -43,11 +43,8 @@
    */
   public class StatementsForClassImpl implements StatementsForClassIF
   {
  -
       private Logger log = LoggerFactory.getLogger(StatementsForClassImpl.class);
   
  -    private static final String CALL = "{ ?= call";
  -
       /**
        * sets the escape processing mode
        */
  @@ -174,17 +171,14 @@
       }
   
       public PreparedStatement getPreparedStmt(Connection con, String sql,
  -                                             boolean scrollable, int explicitFetchSizeHint)
  +                                             boolean scrollable, int explicitFetchSizeHint,
boolean callableStmt)
           throws PersistenceBrokerSQLException
       {
           PreparedStatement stmt = null;
           try
           {
  -            // TODO: Vadim Gritsenko FIXME: Improve check for stored procedure call syntax
  -            final boolean createPreparedStatement;
  -            createPreparedStatement = !sql.toLowerCase().startsWith(CALL);
               stmt = prepareStatement(con, sql, scrollable,
  -                    createPreparedStatement, explicitFetchSizeHint);
  +                    !callableStmt, explicitFetchSizeHint);
           }
           catch (SQLException ex)
           {
  
  
  
  No                   revision
  No                   revision
  1.24.2.3  +9 -8      db-ojb/src/java/org/apache/ojb/broker/platforms/Platform.java
  
  Index: Platform.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/Platform.java,v
  retrieving revision 1.24.2.2
  retrieving revision 1.24.2.3
  diff -u -r1.24.2.2 -r1.24.2.3
  --- Platform.java	26 Apr 2005 03:41:36 -0000	1.24.2.2
  +++ Platform.java	4 Jun 2005 14:13:43 -0000	1.24.2.3
  @@ -230,13 +230,14 @@
        */
       String getEscapeClause(LikeCriteria aCriteria);
   
  -    /**
  -     * Determines whether statement is {@link CallableStatement} or not.
  -     *
  -     * @param stmt the statement
  -     * @return true if statement is {@link CallableStatement}.
  -     */
  -    boolean isCallableStatement(PreparedStatement stmt);
  +// arminw: Check is not necessary any longer
  +//    /**
  +//     * Determines whether statement is {@link CallableStatement} or not.
  +//     *
  +//     * @param stmt the statement
  +//     * @return true if statement is {@link CallableStatement}.
  +//     */
  +//    boolean isCallableStatement(PreparedStatement stmt);
   
       /**
        * Registers call argument at <code>position</code> as returning
  
  
  
  1.7.2.2   +11 -10    db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java
  
  Index: PlatformHsqldbImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java,v
  retrieving revision 1.7.2.1
  retrieving revision 1.7.2.2
  diff -u -r1.7.2.1 -r1.7.2.2
  --- PlatformHsqldbImpl.java	6 Apr 2005 13:29:33 -0000	1.7.2.1
  +++ PlatformHsqldbImpl.java	4 Jun 2005 14:13:43 -0000	1.7.2.2
  @@ -65,14 +65,15 @@
           return true;
       }
   
  -    /**
  -     * HSQLDB does not implement CallableStatement.
  -     *
  -     * @see org.apache.ojb.broker.platforms.Platform#isCallableStatement(java.sql.PreparedStatement)
  -     */
  -    public boolean isCallableStatement(PreparedStatement stmt)
  -    {
  -        return false;
  -    }
  +// arminw: Check is not necessary any longer
  +//    /**
  +//     * HSQLDB does not implement CallableStatement.
  +//     *
  +//     * @see org.apache.ojb.broker.platforms.Platform#isCallableStatement(java.sql.PreparedStatement)
  +//     */
  +//    public boolean isCallableStatement(PreparedStatement stmt)
  +//    {
  +//        return false;
  +//    }
   
   }
  
  
  
  1.10.2.1  +40 -1     db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java
  
  Index: PlatformSapdbImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.10.2.1
  diff -u -r1.10 -r1.10.2.1
  --- PlatformSapdbImpl.java	4 Apr 2004 23:53:35 -0000	1.10
  +++ PlatformSapdbImpl.java	4 Jun 2005 14:13:43 -0000	1.10.2.1
  @@ -27,6 +27,45 @@
    */
   public class PlatformSapdbImpl extends PlatformDefaultImpl
   {
  +// arminw: Check is not necessary any longer
  +//    final String msgCallableStatement = "Can't check maxDB/sapDB driver for CallableStatement,
will return false";
  +//    static final String SAP_FIELD_NAME_1 = "parseinfo";
  +//    static final String SAP_FIELD_NAME_2 = "isDBProc";
  +//
  +//    public boolean isCallableStatement(PreparedStatement stmt)
  +//    {
  +//        if(super.isCallableStatement(stmt))
  +//        {
  +//            /*
  +//            arminw: TODO: this is a really bad hook into the maxDB-driver
  +//            to detect CallableStatement. It's based on two non-public driver-class fields!!
  +//            Thus we can't guarantee that it will work with next/older driver version
(7.6.00.00.3360).
  +//            If a security manager is used this hook could cause problems.
  +//            Recommend to do a redesign of StatementManager interface to avoid this check
  +//            on Platform class.
  +//            */
  +//            try
  +//            {
  +//                Field fld = stmt.getClass().getDeclaredField(SAP_FIELD_NAME_1);
  +//                fld.setAccessible(true);
  +//                Object parseInfo = fld.get(stmt);
  +//                fld = parseInfo.getClass().getDeclaredField(SAP_FIELD_NAME_2);
  +//                fld.setAccessible(true);
  +//                Boolean result = (Boolean) fld.get(parseInfo);
  +//                return result.booleanValue();
  +//            }
  +//            catch(Exception e)
  +//            {
  +//                if(log.isEnabledFor(Logger.WARN)) log.warn(msgCallableStatement, e);
  +//                return false;
  +//            }
  +//        }
  +//        else
  +//        {
  +//            return false;
  +//        }
  +//    }
  +
       public void setObjectForStatement(
               PreparedStatement ps,
               int index,
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message