blob: 02e63517bd813cb717834a549c09db7f24d397d6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <boost/test/unit_test.hpp>
#include <ignite/impl/binary/binary_writer_impl.h>
#include "ignite/odbc/diagnostic/diagnosable_adapter.h"
#include "ignite/odbc/system/odbc_constants.h"
#include "ignite/odbc/row.h"
using namespace ignite::odbc::app;
using namespace ignite::odbc;
std::string GetStrColumnValue(size_t rowIdx)
{
std::stringstream generator;
generator << "Column 2 test string, row num: "
<< rowIdx << ". Some trailing bytes";
return generator.str();
}
void FillMemWithData(ignite::impl::interop::InteropUnpooledMemory& mem, size_t rowNum)
{
using namespace ignite::impl::binary;
using namespace ignite::impl::interop;
InteropOutputStream stream(&mem);
BinaryWriterImpl writer(&stream, 0);
for (size_t i = 0; i < rowNum; ++i)
{
// Number of columns in page.
writer.WriteInt32(4);
// First column is int.
writer.WriteInt8(IGNITE_TYPE_LONG);
writer.WriteInt64(static_cast<int64_t>(i * 10));
// Second column is string.
const std::string& str(GetStrColumnValue(i));
writer.WriteString(str.data(), static_cast<int32_t>(str.size()));
// Third column is GUID.
ignite::Guid guid(0x2b218f63642a4a64UL, 0x9674098f388ac298UL + i);
writer.WriteGuid(guid);
// The last column is bool.
writer.WriteInt8(IGNITE_TYPE_BOOL);
writer.WriteBool(i % 2 == 1);
}
stream.Synchronize();
}
void CheckRowData(Row& row, size_t rowIdx)
{
SqlLen reslen;
SQLINTEGER longBuf;
char strBuf[1024];
SQLGUID guidBuf;
char bitBuf;
ApplicationDataBuffer appLongBuf(type_traits::OdbcNativeType::AI_SIGNED_LONG, &longBuf, sizeof(longBuf), &reslen);
ApplicationDataBuffer appStrBuf(type_traits::OdbcNativeType::AI_CHAR, &strBuf, sizeof(strBuf), &reslen);
ApplicationDataBuffer appGuidBuf(type_traits::OdbcNativeType::AI_GUID, &guidBuf, sizeof(guidBuf), &reslen);
ApplicationDataBuffer appBitBuf(type_traits::OdbcNativeType::AI_BIT, &bitBuf, sizeof(bitBuf), &reslen);
// Checking size.
BOOST_REQUIRE(row.GetSize() == 4);
// Checking 1st column.
BOOST_REQUIRE(row.ReadColumnToBuffer(1, appLongBuf) == ConversionResult::AI_SUCCESS);
BOOST_REQUIRE_EQUAL(static_cast<size_t>(longBuf), rowIdx * 10);
// Checking 2nd column.
BOOST_REQUIRE(row.ReadColumnToBuffer(2, appStrBuf) == ConversionResult::AI_SUCCESS);
std::string strReal(strBuf, static_cast<size_t>(reslen));
std::string strExpected(GetStrColumnValue(rowIdx));
BOOST_REQUIRE(strReal == strExpected);
// Checking 3rd column.
BOOST_REQUIRE(row.ReadColumnToBuffer(3, appGuidBuf) == ConversionResult::AI_SUCCESS);
BOOST_REQUIRE(guidBuf.Data1 == 0x2b218f63UL);
BOOST_REQUIRE(guidBuf.Data2 == 0x642aU);
BOOST_REQUIRE(guidBuf.Data3 == 0x4a64U);
BOOST_REQUIRE(guidBuf.Data4[0] == 0x96);
BOOST_REQUIRE(guidBuf.Data4[1] == 0x74);
BOOST_REQUIRE(guidBuf.Data4[2] == 0x09);
BOOST_REQUIRE(guidBuf.Data4[3] == 0x8f);
BOOST_REQUIRE(guidBuf.Data4[4] == 0x38);
BOOST_REQUIRE(guidBuf.Data4[5] == 0x8a);
BOOST_REQUIRE(guidBuf.Data4[6] == 0xc2);
BOOST_REQUIRE(guidBuf.Data4[7] == 0x98 + rowIdx);
// Checking 4th column.
BOOST_REQUIRE(row.ReadColumnToBuffer(4, appBitBuf) == ConversionResult::AI_SUCCESS);
BOOST_REQUIRE_EQUAL(static_cast<size_t>(bitBuf), rowIdx % 2);
}
BOOST_AUTO_TEST_SUITE(RowTestSuite)
BOOST_AUTO_TEST_CASE(TestRowMoveToNext)
{
ignite::impl::interop::InteropUnpooledMemory mem(4096);
const size_t rowNum = 32;
FillMemWithData(mem, rowNum);
Row row(mem);
for (size_t i = 0; i < rowNum - 1; ++i)
{
BOOST_REQUIRE(row.GetSize() == 4);
BOOST_REQUIRE(row.MoveToNext());
}
BOOST_REQUIRE(row.GetSize() == 4);
}
BOOST_AUTO_TEST_CASE(TestRowRead)
{
ignite::impl::interop::InteropUnpooledMemory mem(4096);
const size_t rowNum = 8;
FillMemWithData(mem, rowNum);
Row row(mem);
BOOST_REQUIRE(row.GetSize() == 4);
for (size_t i = 0; i < rowNum - 1; ++i)
{
CheckRowData(row, i);
BOOST_REQUIRE(row.MoveToNext());
}
CheckRowData(row, rowNum - 1);
}
BOOST_AUTO_TEST_CASE(TestSingleRow)
{
ignite::impl::interop::InteropUnpooledMemory mem(4096);
FillMemWithData(mem, 1);
Row row(mem);
BOOST_REQUIRE(row.GetSize() == 4);
CheckRowData(row, 0);
}
BOOST_AUTO_TEST_CASE(TestTwoRows)
{
ignite::impl::interop::InteropUnpooledMemory mem(4096);
FillMemWithData(mem, 2);
Row row(mem);
BOOST_REQUIRE(row.GetSize() == 4);
CheckRowData(row, 0);
BOOST_REQUIRE(row.MoveToNext());
BOOST_REQUIRE(row.GetSize() == 4);
CheckRowData(row, 1);
}
BOOST_AUTO_TEST_SUITE_END()