40 memset(buffer, 0, sizeof (buffer)); |
40 memset(buffer, 0, sizeof (buffer)); |
41 memset(sqlstate, 0, sizeof (sqlstate)); |
41 memset(sqlstate, 0, sizeof (sqlstate)); |
42 SQLINTEGER sqlcode; |
42 SQLINTEGER sqlcode; |
43 SQLSMALLINT length; |
43 SQLSMALLINT length; |
44 for (SQLSMALLINT i = 1; SQLGetDiagRec(handleType, handle, i, sqlstate, &sqlcode, buffer, SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS; i++) { |
44 for (SQLSMALLINT i = 1; SQLGetDiagRec(handleType, handle, i, sqlstate, &sqlcode, buffer, SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS; i++) { |
|
45 for (size_t i = 0; i < sizeof (buffer); i++) if (buffer[i] > 126 || buffer[i] == '\r') buffer[i] = '?'; // keep only ASCII characters and avoid CR which breaks the output |
45 diagnostics.push_back({convertor.from_bytes((char*) sqlstate), sqlcode, convertor.from_bytes((char*) buffer)}); |
46 diagnostics.push_back({convertor.from_bytes((char*) sqlstate), sqlcode, convertor.from_bytes((char*) buffer)}); |
|
47 // FIXME: decoding fails is error message contains unicode characters – exception is thrown: |
|
48 // terminate called after throwing an instance of 'std::range_error' |
|
49 // what(): wstring_convert::from_bytes |
|
50 // Exception can be avoided by: |
|
51 // std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor("", L"XXX Unable to decode error message from SQLGetDiagRec()"); |
|
52 // but actual error message is then lost. |
|
53 // So as a workaround we keep only ASCII characters. |
|
54 // It seems that we sometimes get valid ISO-8859-2 or ISO-8859-1 encoded messages even if our platform encoding is UTF-8. |
|
55 |
46 } |
56 } |
47 if (freeHandle) OdbcCommon::freeHandle(handleType, handle); |
57 if (freeHandle) OdbcCommon::freeHandle(handleType, handle); |
48 } |
58 } |
49 |
59 |
50 std::vector<SqlException::SqlDiagnosticsRecord> SqlException::getDiagnostics() const { |
60 std::vector<SqlException::SqlDiagnosticsRecord> SqlException::getDiagnostics() const { |