[Libreoffice-commits] core.git: 5 commits - connectivity/source

Lionel Elie Mamane lionel at mamane.lu
Tue Aug 27 09:51:20 PDT 2013


 connectivity/source/drivers/odbcbase/OResultSet.cxx |   81 +++++++++++---------
 1 file changed, 48 insertions(+), 33 deletions(-)

New commits:
commit 4033532e9ffb004ab5864401aa1af0c69fc024ec
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Aug 27 18:28:37 2013 +0200

    release m_aLengthVector even when m_aBindVector is empty
    
    Change-Id: Ia3bd53402d436e296005f4f93113cc08daea2421

diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index a0542a8..0c5de7d 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -195,13 +195,12 @@ void OResultSet::disposing(void)
     OPropertySetHelper::disposing();
 
     ::osl::MutexGuard aGuard(m_aMutex);
-    if(!m_aBindVector.empty())
-        releaseBuffer();
+    releaseBuffer();
     if(m_bFreeHandle)
         m_pStatement->getOwnConnection()->freeStatementHandle(m_aStatementHandle);
 
-m_xStatement.clear();
-m_xMetaData.clear();
+    m_xStatement.clear();
+    m_xMetaData.clear();
 }
 // -------------------------------------------------------------------------
 SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle)
commit 1c7b0b08b2aad12fa2a295198c235d505c44e0f5
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Aug 27 18:27:58 2013 +0200

    the place reserved for bookmark in m_aBindVector is never used
    
    Change-Id: Iae4850739c329a7b04f8eea75047ab75465e3dea

diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index 99c4e57..a0542a8 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -211,9 +211,9 @@ SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle)
     if ( _bUnbindHandle )
         nRet = N3SQLFreeStmt(m_aStatementHandle,SQL_UNBIND);
 
-    if ( m_aBindVector.size() > 1 )
+    if ( m_aBindVector.size() > 0 )
     {
-        TVoidVector::iterator pValue = m_aBindVector.begin() + 1;
+        TVoidVector::iterator pValue = m_aBindVector.begin();
         TVoidVector::iterator pEnd = m_aBindVector.end();
         for(; pValue != pEnd; ++pValue)
         {
@@ -271,7 +271,6 @@ SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle)
             }
         }
         m_aBindVector.clear();
-        m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark
     }
     return nRet;
 }
@@ -344,8 +343,7 @@ void OResultSet::allocBuffer()
     Reference< XResultSetMetaData > xMeta = getMetaData();
     sal_Int32 nLen = xMeta->getColumnCount();
 
-    m_aBindVector.reserve(nLen+1);
-    m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark
+    m_aBindVector.reserve(nLen);
     m_aRow.resize(nLen+1);
 
     m_aRow[0].setTypeKind(DataType::VARBINARY);
commit 89c6e2327fa9fb24bf21231c5b7ab9b76bcd5099
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Aug 27 18:07:14 2013 +0200

    odbc insert: unbind as soon bindings not necessary
    
    SQLFetchScroll uses the bound columns, and writes to them.
    This has two problems:
    1) For non-bookmark columns, this happens in our buffers,
       and at first sight could be innocuous.
       However, it allows the driver to disallow us to use
       SQLGetData on the same columns, which we intend to do...
    2) For bookmark column, the "read bookmark from" and
       "write bookmark to" buffers end up being the same.
       This unnecessarily exposes us to driver bugs in this corner case.
    
    Change-Id: I594d34cf5a64564766f06b49c86f8737961573c0

diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index a35105e..99c4e57 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -896,6 +896,8 @@ void SAL_CALL OResultSet::insertRow(  ) throw(SQLException, RuntimeException)
         throw;
     }
 
+    nRet = unbind();
+    OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
 
     if ( bPositionByBookmark )
     {
@@ -907,8 +909,6 @@ void SAL_CALL OResultSet::insertRow(  ) throw(SQLException, RuntimeException)
         nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0); // OJ 06.03.2004
     // sometimes we got an error but we are not interested in anymore #106047# OJ
     //  OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
-    nRet = unbind();
-    OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
 
     if(m_pSkipDeletedSet)
     {
commit 2939a1fa638f63162f0a9741e139e9439144556b
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Aug 27 18:03:21 2013 +0200

    odbc insert: adjust buffer size *after* it is written to
    
    the buffer (aBookmark) is written to by SQLBulkOperations or
    SQLSetPos, not by SQLBindCol, which merely sets up the instruction
    that the next call should write there. So its finak size is known
    only *after* the call that makes the write, obviously.
    
    Change-Id: I4faaaeffc060433645188f0eda3d9958b087cf6c

diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index d3969a1..a35105e 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -872,7 +872,6 @@ void SAL_CALL OResultSet::insertRow(  ) throw(SQLException, RuntimeException)
                                 &nRealLen
                                 );
 
-    aBookmark.realloc(nRealLen);
     sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
     if ( bPositionByBookmark )
     {
@@ -886,6 +885,7 @@ void SAL_CALL OResultSet::insertRow(  ) throw(SQLException, RuntimeException)
         nRet = N3SQLSetPos( m_aStatementHandle, 1, SQL_ADD, SQL_LOCK_NO_CHANGE );
         fillNeededData( nRet );
     }
+    aBookmark.realloc(nRealLen);
     try
     {
         OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
commit 8f9388c0234f59ef4460512cd3a3e9b4727e6363
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Aug 27 17:59:42 2013 +0200

    fdo#68315 odbc update *reads* a bookmark, not *writes* a bookmark
    
    This code was completely inverted. The row update operation
    *reads* a bookmark (that is, what row to update), not *writes*
    a bookmark.
    
    So we were passing an empty bookmark, and thus the update was failing
    because we were refering to a non-existent row.
    
    Change-Id: I676b1a7727a88e13a3e465bd96cbbaf18dad2fa6

diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index 6f4b6f6..d3969a1 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -938,29 +938,47 @@ void SAL_CALL OResultSet::updateRow(  ) throw(SQLException, RuntimeException)
 
     SQLRETURN nRet;
 
-    sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
-    Sequence<sal_Int8> aBookmark(nMaxBookmarkLen);
-    if ( bPositionByBookmark )
+    try
     {
-        SQLLEN nRealLen = 0;
-        nRet = N3SQLBindCol(m_aStatementHandle,
-                            0,
-                            SQL_C_VARBOOKMARK,
-                            aBookmark.getArray(),
-                            aBookmark.getLength(),
-                            &nRealLen
-                            );
-        fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
-        aBookmark.realloc(nRealLen);
-        m_aRow[0]=aBookmark;
-        m_aRow[0].setBound(true);
+        sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
+        if ( bPositionByBookmark )
+        {
+            getBookmark();
+            assert(m_aRow[0].isBound());
+            Sequence<sal_Int8> aBookmark(m_aRow[0].getSequence());
+            SQLLEN nRealLen = aBookmark.getLength();
+            nRet = N3SQLBindCol(m_aStatementHandle,
+                                0,
+                                SQL_C_VARBOOKMARK,
+                                aBookmark.getArray(),
+                                aBookmark.getLength(),
+                                &nRealLen
+                                );
+            OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
+            fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
+            // the driver should not have touched this
+            // (neither the contents of aBookmark FWIW)
+            assert(nRealLen == aBookmark.getLength());
+        }
+        else
+        {
+            fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
+        }
+        OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
+        // unbind all columns so we can fetch all columns again with SQLGetData
+        // (and also so that our buffers don't clobber anything, and
+        //  so that a subsequent fetch does not overwrite m_aRow[0])
+        invalidateCache();
+        nRet = unbind();
+        OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after success");
+    }
+    catch(...)
+    {
+        // unbind all columns so that a subsequent fetch does not overwrite m_aRow[0]
+        nRet = unbind();
+        OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after failure");
+        throw;
     }
-    else
-        fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
-    OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
-    // now unbind all columns so we can fetch all columns again with SQLGetData
-    nRet = unbind();
-    OSL_ENSURE(nRet == SQL_SUCCESS,"Could not unbind the columns!");
 }
 // -------------------------------------------------------------------------
 void SAL_CALL OResultSet::deleteRow(  ) throw(SQLException, RuntimeException)


More information about the Libreoffice-commits mailing list