Kaydet (Commit) 44416a16 authored tarafından Tamas Bunth's avatar Tamas Bunth Kaydeden (comit) Tamás Bunth

mysqlc: Fix obtaining field information in rs

Result set field information should be stored correctly. It is queried
from database on demand and stored locally.

Change-Id: Ia62c62e6db32b45640b9fcd5f48c6249aecc41a2
Reviewed-on: https://gerrit.libreoffice.org/64861
Tested-by: Jenkins
Reviewed-by: 's avatarTamás Bunth <btomi96@gmail.com>
üst bdeabe63
......@@ -182,6 +182,7 @@ void MysqlTestDriver::testIntegerInsertAndQuery()
Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable");
CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is());
Reference<XRow> xRow(xResultSet, UNO_QUERY);
Reference<XColumnLocate> xColumnLocate(xResultSet, UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is());
for (long i = 0; i < ROW_COUNT; ++i)
......@@ -189,6 +190,7 @@ void MysqlTestDriver::testIntegerInsertAndQuery()
bool hasRow = xResultSet->next();
CPPUNIT_ASSERT_MESSAGE("not enough result after query", hasRow);
CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(1)); // first and only column
CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(xColumnLocate->findColumn("id"))); // test findColumn
}
CPPUNIT_ASSERT_MESSAGE("Cursor is not on last position.",
xResultSet->isLast()); // cursor is on last position
......
......@@ -134,6 +134,18 @@ void OResultSet::ensureResultFetched()
}
}
void OResultSet::ensureFieldInfoFetched()
{
if (!m_aFields.empty())
return;
unsigned nFieldCount = mysql_num_fields(m_pResult);
MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
m_aFields.reserve(nFieldCount);
for (unsigned i = 0; i < nFieldCount; ++i)
m_aFields.push_back(OUString{
pFields[i].name, static_cast<sal_Int32>(strlen(pFields[i].name)), m_encoding });
}
void OResultSet::fetchResult()
{
// Mysql C API does not allow simultaneously opened result sets, but sdbc does.
......@@ -143,20 +155,18 @@ void OResultSet::fetchResult()
// TODO ensure that
m_nRowCount = mysql_num_rows(m_pResult);
ensureFieldInfoFetched();
// fetch all the data
m_aRows.reserve(m_nRowCount);
m_nFieldCount = mysql_num_fields(m_pResult);
MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
m_aFields.assign(pFields, pFields + m_nFieldCount);
for (sal_Int32 row = 0; row < m_nRowCount; ++row)
{
MYSQL_ROW data = mysql_fetch_row(m_pResult);
unsigned long* lengths = mysql_fetch_lengths(m_pResult);
m_aRows.push_back(DataFields{});
// MYSQL_ROW is char**, array of strings
for (unsigned col = 0; col < m_nFieldCount; ++col)
for (std::size_t col = 0; col < m_aFields.size(); ++col)
{
m_aRows.back().push_back(OString{ data[col], static_cast<sal_Int32>(lengths[col]) });
}
......@@ -202,11 +212,12 @@ sal_Int32 SAL_CALL OResultSet::findColumn(const OUString& columnName)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
for (unsigned int i = 0; i < m_nFieldCount; ++i)
for (std::size_t i = 0; i < m_aFields.size(); ++i)
{
if (columnName.equalsIgnoreAsciiCaseAscii(m_aFields[i].name))
return i + 1; // sdbc indexes from 1
if (columnName.equalsIgnoreAsciiCase(m_aFields[i]))
return static_cast<sal_Int32>(i) + 1; // sdbc indexes from 1
}
throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0,
......@@ -1092,7 +1103,7 @@ css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OResultSet::getProper
void OResultSet::checkColumnIndex(sal_Int32 index)
{
if (index < 1 || index > static_cast<int>(m_nFieldCount))
if (index < 1 || index > static_cast<int>(m_aFields.size()))
{
/* static object for efficiency or thread safety is a problem ? */
throw SQLException("index out of range", *this, OUString(), 1, Any());
......
......@@ -64,12 +64,11 @@ class OResultSet final : public OBase_Mutex,
{
using DataFields = std::vector<OString>;
std::vector<DataFields> m_aRows;
std::vector<MYSQL_FIELD> m_aFields;
std::vector<OUString> m_aFields;
MYSQL* m_pMysql = nullptr;
css::uno::WeakReferenceHelper m_aStatement;
css::uno::Reference<css::sdbc::XResultSetMetaData> m_xMetaData;
MYSQL_RES* m_pResult;
unsigned int m_nFieldCount = 0;
rtl_TextEncoding m_encoding;
bool m_bWasNull = false; // did the last getXXX result null?
bool m_bResultFetched = false;
......@@ -101,6 +100,7 @@ class OResultSet final : public OBase_Mutex,
virtual ~OResultSet() override = default;
void ensureResultFetched();
void ensureFieldInfoFetched();
void fetchResult();
public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment