You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/11/22 10:49:11 UTC

[08/10] ignite git commit: IGNITE-4227: ODBC: Implemented SQLError. This closes #1237.

IGNITE-4227: ODBC: Implemented SQLError. This closes #1237.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bc695f8e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bc695f8e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bc695f8e

Branch: refs/heads/ignite-4259
Commit: bc695f8e3306c6d74d4fe53d9a98adedd43ad8f0
Parents: f2dc1d7
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Nov 22 12:05:15 2016 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Nov 22 12:05:15 2016 +0300

----------------------------------------------------------------------
 .../cpp/odbc-test/src/api_robustness_test.cpp   | 45 +++++++++++++++
 .../platforms/cpp/odbc/include/ignite/odbc.h    | 12 +++-
 .../ignite/odbc/diagnostic/diagnosable.h        |  7 +++
 .../odbc/diagnostic/diagnosable_adapter.h       | 10 ++++
 .../ignite/odbc/diagnostic/diagnostic_record.h  | 19 +++++++
 .../odbc/diagnostic/diagnostic_record_storage.h | 16 ++++++
 .../odbc/os/win/src/system/socket_client.cpp    |  4 +-
 .../odbc/src/diagnostic/diagnostic_record.cpp   | 16 +++++-
 .../diagnostic/diagnostic_record_storage.cpp    | 18 ++++++
 modules/platforms/cpp/odbc/src/entry_points.cpp | 26 ++++-----
 modules/platforms/cpp/odbc/src/odbc.cpp         | 59 ++++++++++++++++++++
 11 files changed, 214 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
index fbd5f12..13a5ea6 100644
--- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
@@ -1066,4 +1066,49 @@ BOOST_AUTO_TEST_CASE(TestFetchScrollFirst)
     CheckFetchScrollUnsupportedOrientation(SQL_FETCH_FIRST);
 }
 
+BOOST_AUTO_TEST_CASE(TestSQLError)
+{
+    // There are no checks because we do not really care what is the result of these
+    // calls as long as they do not cause segmentation fault.
+
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;cache=cache");
+
+    SQLCHAR state[6] = { 0 };
+    SQLINTEGER nativeCode = 0;
+    SQLCHAR message[ODBC_BUFFER_SIZE] = { 0 };
+    SQLSMALLINT messageLen = 0;
+
+    // Everything is ok.
+    SQLRETURN ret = SQLError(env, 0, 0, state, &nativeCode, message, sizeof(message), &messageLen);
+
+    if (ret != SQL_SUCCESS && ret != SQL_NO_DATA)
+        BOOST_FAIL("Unexpected error");
+
+    ret = SQLError(0, dbc, 0, state, &nativeCode, message, sizeof(message), &messageLen);
+
+    if (ret != SQL_SUCCESS && ret != SQL_NO_DATA)
+        BOOST_FAIL("Unexpected error");
+
+    ret = SQLError(0, 0, stmt, state, &nativeCode, message, sizeof(message), &messageLen);
+
+    if (ret != SQL_SUCCESS && ret != SQL_NO_DATA)
+        BOOST_FAIL("Unexpected error");
+
+    SQLError(0, 0, 0, state, &nativeCode, message, sizeof(message), &messageLen);
+
+    SQLError(0, 0, stmt, 0, &nativeCode, message, sizeof(message), &messageLen);
+
+    SQLError(0, 0, stmt, state, 0, message, sizeof(message), &messageLen);
+
+    SQLError(0, 0, stmt, state, &nativeCode, 0, sizeof(message), &messageLen);
+
+    SQLError(0, 0, stmt, state, &nativeCode, message, 0, &messageLen);
+
+    SQLError(0, 0, stmt, state, &nativeCode, message, sizeof(message), 0);
+
+    SQLError(0, 0, stmt, 0, 0, 0, 0, 0);
+
+    SQLError(0, 0, 0, 0, 0, 0, 0, 0);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/include/ignite/odbc.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc.h b/modules/platforms/cpp/odbc/include/ignite/odbc.h
index ec0861c..345cdb8 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc.h
@@ -255,6 +255,16 @@ namespace ignite
     SQLRETURN SQLParamData(SQLHSTMT stmt, SQLPOINTER* value);
 
     SQLRETURN SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN strLengthOrIndicator);
+
+    SQLRETURN SQLError(SQLHENV      env,
+                       SQLHDBC      conn,
+                       SQLHSTMT     stmt,
+                       SQLCHAR*     state,
+                       SQLINTEGER*  error,
+                       SQLCHAR*     msgBuf,
+                       SQLSMALLINT  msgBufLen,
+                       SQLSMALLINT* msgResLen);
+
 } // namespace ignite
 
-#endif //_IGNITE_ODBC
+#endif //_IGNITE_ODBC
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
index 909fe01..6937fcc 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
@@ -48,6 +48,13 @@ namespace ignite
                 virtual const diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords() const = 0;
 
                 /**
+                 * Get diagnostic record.
+                 *
+                 * @return Diagnostic record.
+                 */
+                virtual diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords() = 0;
+
+                /**
                  * Add new status record.
                  *
                  * @param sqlState SQL state.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
index 63d26ca..548eecd 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
@@ -62,6 +62,16 @@ namespace ignite
                 }
 
                 /**
+                 * Get diagnostic record.
+                 *
+                 * @return Diagnostic record.
+                 */
+                virtual diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords()
+                {
+                    return diagnosticRecords;
+                }
+
+                /**
                  * Add new status record.
                  *
                  * @param sqlState SQL state.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h
index 670e0aa..80d5090 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h
@@ -127,6 +127,19 @@ namespace ignite
                  */
                 int32_t GetColumnNumber() const;
 
+                /**
+                 * Check if the record was retrieved with the SQLError previously.
+                 *
+                 * return True if the record was retrieved with the SQLError
+                 *  previously.
+                 */
+                bool IsRetrieved() const;
+
+                /**
+                 * Mark record as retrieved with the SQLError.
+                 */
+                void MarkRetrieved();
+
             private:
                 /** SQL state diagnostic code. */
                 SqlState sqlState;
@@ -157,6 +170,12 @@ namespace ignite
                  * result set or the parameter number in the set of parameters.
                  */
                 int32_t columnNum;
+
+                /**
+                 * Flag that shows if the record was retrieved with the 
+                 * SQLError previously.
+                 */
+                bool retrieved;
             };
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h
index 4cc3576..b45bb7d 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h
@@ -139,6 +139,22 @@ namespace ignite
                 const DiagnosticRecord& GetStatusRecord(int32_t idx) const;
 
                 /**
+                 * Get specified status record.
+                 *
+                 * @param idx Status record index.
+                 * @return Status record instance reference.
+                 */
+                DiagnosticRecord& GetStatusRecord(int32_t idx);
+
+                /**
+                 * Get last non-retrieved status record index.
+                 *
+                 * @return Index of the last non-retrieved status record or zero
+                 *  if nothing was found.
+                 */
+                int32_t GetLastNonRetrieved() const;
+
+                /**
                  * Check if the record is in the success state.
                  *
                  * @return True if the record is in the success state.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp b/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
index bc4cdc0..e248323 100644
--- a/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
+++ b/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
@@ -83,8 +83,8 @@ namespace ignite
                 // Attempt to connect to an address until one succeeds
                 for (addrinfo *it = result; it != NULL; it = it->ai_next)
                 {
-                    LOG_MSG("Addr: %u.%u.%u.%u\n", it->ai_addr->sa_data[2], it->ai_addr->sa_data[3],
-                                                   it->ai_addr->sa_data[4], it->ai_addr->sa_data[5]);
+                    LOG_MSG("Addr: %u.%u.%u.%u\n", it->ai_addr->sa_data[2] & 0xFF, it->ai_addr->sa_data[3] & 0xFF,
+                                                   it->ai_addr->sa_data[4] & 0xFF, it->ai_addr->sa_data[5] & 0xFF);
 
                     // Create a SOCKET for connecting to server
                     socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
index 1b654d2..215d77f 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
@@ -89,7 +89,8 @@ namespace ignite
                 connectionName(),
                 serverName(),
                 rowNum(0),
-                columnNum(0)
+                columnNum(0),
+                retrieved(false)
             {
                 // No-op.
             }
@@ -102,7 +103,8 @@ namespace ignite
                 connectionName(connectionName),
                 serverName(serverName),
                 rowNum(rowNum),
-                columnNum(columnNum)
+                columnNum(columnNum),
+                retrieved(false)
             {
                 // No-op.
             }
@@ -260,6 +262,16 @@ namespace ignite
             {
                 return columnNum;
             }
+
+            bool DiagnosticRecord::IsRetrieved() const
+            {
+                return retrieved;
+            }
+
+            void DiagnosticRecord::MarkRetrieved()
+            {
+                retrieved = true;
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
index 99ef292..c075567 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
@@ -102,6 +102,24 @@ namespace ignite
                 return statusRecords[idx - 1];
             }
 
+            DiagnosticRecord& DiagnosticRecordStorage::GetStatusRecord(int32_t idx)
+            {
+                return statusRecords[idx - 1];
+            }
+
+            int32_t DiagnosticRecordStorage::GetLastNonRetrieved() const
+            {
+                for (size_t i = 0; i < statusRecords.size(); ++i)
+                {
+                    const DiagnosticRecord& record = statusRecords[i];
+
+                    if (!record.IsRetrieved())
+                        return static_cast<int32_t>(i + 1);
+                }
+
+                return 0;
+            }
+
             bool DiagnosticRecordStorage::IsSuccessful() const
             {
                 return result == SQL_RESULT_SUCCESS || 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/src/entry_points.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/entry_points.cpp b/modules/platforms/cpp/odbc/src/entry_points.cpp
index 08016cc..a85b3cf 100644
--- a/modules/platforms/cpp/odbc/src/entry_points.cpp
+++ b/modules/platforms/cpp/odbc/src/entry_points.cpp
@@ -412,6 +412,19 @@ SQLRETURN SQL_API SQLPutData(SQLHSTMT     stmt,
     return ignite::SQLPutData(stmt, data, strLengthOrIndicator);
 }
 
+SQLRETURN SQL_API SQLError(SQLHENV      env,
+                           SQLHDBC      conn,
+                           SQLHSTMT     stmt,
+                           SQLCHAR*     state,
+                           SQLINTEGER*  error,
+                           SQLCHAR*     msgBuf,
+                           SQLSMALLINT  msgBufLen,
+                           SQLSMALLINT* msgResLen)
+{
+    return ignite::SQLError(env, conn, stmt, state,
+        error, msgBuf, msgBufLen, msgResLen);
+}
+
 //
 // ==== Not implemented ====
 //
@@ -434,19 +447,6 @@ SQLRETURN SQL_API SQLColAttributes(SQLHSTMT     stmt,
     return SQL_SUCCESS;
 }
 
-SQLRETURN SQL_API SQLError(SQLHENV      env,
-                           SQLHDBC      conn,
-                           SQLHSTMT     stmt,
-                           SQLCHAR*     state,
-                           SQLINTEGER*  error,
-                           SQLCHAR*     msgBuf,
-                           SQLSMALLINT  msgBufLen,
-                           SQLSMALLINT* msgResLen)
-{
-    LOG_MSG("SQLError called\n");
-    return SQL_ERROR;
-}
-
 SQLRETURN SQL_API SQLGetCursorName(SQLHSTMT     stmt,
                                    SQLCHAR*     nameBuf,
                                    SQLSMALLINT  nameBufLen,

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc695f8e/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 79036eb..684ed08 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -1255,4 +1255,63 @@ namespace ignite
         return statement->GetDiagnosticRecords().GetReturnCode();
     }
 
+    SQLRETURN SQLError(SQLHENV      env,
+                       SQLHDBC      conn,
+                       SQLHSTMT     stmt,
+                       SQLCHAR*     state,
+                       SQLINTEGER*  error,
+                       SQLCHAR*     msgBuf,
+                       SQLSMALLINT  msgBufLen,
+                       SQLSMALLINT* msgResLen)
+    {
+        using namespace ignite::utility;
+        using namespace ignite::odbc;
+        using namespace ignite::odbc::diagnostic;
+        using namespace ignite::odbc::type_traits;
+
+        using ignite::odbc::app::ApplicationDataBuffer;
+
+        LOG_MSG("SQLError called\n");
+
+        SQLHANDLE handle = 0;
+
+        if (env != 0)
+            handle = static_cast<SQLHANDLE>(env);
+        else if (conn != 0)
+            handle = static_cast<SQLHANDLE>(conn);
+        else if (stmt != 0)
+            handle = static_cast<SQLHANDLE>(stmt);
+        else
+            return SQL_INVALID_HANDLE;
+
+        Diagnosable *diag = reinterpret_cast<Diagnosable*>(handle);
+
+        DiagnosticRecordStorage& records = diag->GetDiagnosticRecords();
+
+        int32_t recNum = records.GetLastNonRetrieved();
+
+        if (recNum < 1 || recNum > records.GetStatusRecordsNumber())
+            return SQL_NO_DATA;
+
+        DiagnosticRecord& record = records.GetStatusRecord(recNum);
+
+        record.MarkRetrieved();
+
+        if (state)
+            CopyStringToBuffer(record.GetSqlState(), reinterpret_cast<char*>(state), 6);
+
+        if (error)
+            *error = 0;
+
+        SqlLen outResLen;
+        ApplicationDataBuffer outBuffer(IGNITE_ODBC_C_TYPE_CHAR, msgBuf, msgBufLen, &outResLen);
+
+        outBuffer.PutString(record.GetMessageText());
+
+        if (msgResLen)
+            *msgResLen = static_cast<SQLSMALLINT>(outResLen);
+
+        return SQL_SUCCESS;
+    }
+
 } // namespace ignite;