42 else if (result == SQL_NO_DATA) return false; |
42 else if (result == SQL_NO_DATA) return false; |
43 else throw SqlException(L"Unable to fetch next record", result, SQL_HANDLE_STMT, statement); |
43 else throw SqlException(L"Unable to fetch next record", result, SQL_HANDLE_STMT, statement); |
44 } |
44 } |
45 |
45 |
46 relpipe::writer::boolean_t ResultSet::getBoolean(unsigned short columnNumber, bool* isNull) { |
46 relpipe::writer::boolean_t ResultSet::getBoolean(unsigned short columnNumber, bool* isNull) { |
47 throw SqlException(L"not yet implemented: getBoolean()"); |
47 relpipe::writer::string_t s = getString(columnNumber, isNull); |
|
48 if (isNull && *isNull) return false; |
|
49 else if (s == L"1" || s == L"true" || s == L"y" || s == L"yes" || s == L"TRUE" || s == L"Y" || s == L"YES") return true; |
|
50 else if (s == L"0" || s == L"false" || s == L"n" || s == L"no" || s == L"FALSE" || s == L"N" || s == L"NO") return false; |
|
51 else throw SqlException(L"Unable to parse „" + s + L"“ as boolean"); |
48 } |
52 } |
49 |
53 |
50 relpipe::writer::integer_t ResultSet::getInteger(unsigned short columnNumber, bool* isNull) { |
54 relpipe::writer::integer_t ResultSet::getInteger(unsigned short columnNumber, bool* isNull) { |
51 throw SqlException(L"not yet implemented: getInteger()"); |
55 // TODO: get integer directly from SQLGetData() without string conversion |
52 |
56 relpipe::writer::string_t s = getString(columnNumber, isNull); |
|
57 if (isNull && *isNull) return 0; |
|
58 else return std::stol(s); |
53 } |
59 } |
54 |
60 |
55 relpipe::writer::string_t ResultSet::getString(unsigned short columnNumber, bool* isNull) { |
61 relpipe::writer::string_t ResultSet::getString(unsigned short columnNumber, bool* isNull) { |
56 SQLCHAR uselessBuffer; // just to get stringLength – ODBC does not eat nullptr |
62 SQLCHAR uselessBuffer; // just to get stringLength – ODBC does not eat nullptr |
57 SQLLEN stringLength = -1; |
63 SQLLEN stringLength = -1; |
83 SQLSMALLINT nameLength; |
89 SQLSMALLINT nameLength; |
84 SQLSMALLINT dataType; |
90 SQLSMALLINT dataType; |
85 SQLULEN columnSize; |
91 SQLULEN columnSize; |
86 SQLSMALLINT decimalDigits; |
92 SQLSMALLINT decimalDigits; |
87 SQLSMALLINT nullable; |
93 SQLSMALLINT nullable; |
|
94 |
88 result = SQLDescribeCol(statement, columnNumber, (SQLCHAR*) nameBuffer.c_str(), nameBuffer.capacity(), &nameLength, &dataType, &columnSize, &decimalDigits, &nullable); |
95 result = SQLDescribeCol(statement, columnNumber, (SQLCHAR*) nameBuffer.c_str(), nameBuffer.capacity(), &nameLength, &dataType, &columnSize, &decimalDigits, &nullable); |
89 if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable describe column", result, SQL_HANDLE_STMT, statement); |
96 if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable describe column", result, SQL_HANDLE_STMT, statement); |
|
97 |
90 columnDescriptor.name = convertor.from_bytes(nameBuffer.c_str()); |
98 columnDescriptor.name = convertor.from_bytes(nameBuffer.c_str()); |
91 //columnDescriptor.type = … // FIXME: support also other types than string |
99 |
|
100 if (dataType == SQL_INTEGER || dataType == SQL_BIGINT) columnDescriptor.type = relpipe::writer::TypeId::INTEGER; |
|
101 else if (dataType == SQL_BIT) columnDescriptor.type = relpipe::writer::TypeId::BOOLEAN; |
|
102 |
92 columnDescriptors.emplace_back(columnDescriptor); |
103 columnDescriptors.emplace_back(columnDescriptor); |
93 } |
104 } |
94 |
105 |
95 return new MetaData(columnCount, columnDescriptors); |
106 return new MetaData(columnCount, columnDescriptors); |
96 } |
107 } |