From 573dcca72adaa00a3463295454ee07234a850949 Mon Sep 17 00:00:00 2001 From: Hernan Martinez Date: Tue, 31 May 2022 08:53:15 -0400 Subject: [PATCH] Handle MariaDB JSON columns since they are stored as `longtext` (#3621) * Also extract BLOBs when reading longtext columns as std::string * Fix error message in unit test * Added unit test to read longtext columns as std::string --- Data/MySQL/src/Extractor.cpp | 3 +++ Data/MySQL/testsuite/src/MySQLTest.cpp | 13 ++++++++++-- Data/MySQL/testsuite/src/MySQLTest.h | 1 + Data/MySQL/testsuite/src/SQLExecutor.cpp | 25 ++++++++++++++++++++++++ Data/MySQL/testsuite/src/SQLExecutor.h | 1 + 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Data/MySQL/src/Extractor.cpp b/Data/MySQL/src/Extractor.cpp index 0e0862ea3..cb06a2d5d 100644 --- a/Data/MySQL/src/Extractor.cpp +++ b/Data/MySQL/src/Extractor.cpp @@ -134,6 +134,9 @@ bool Extractor::extract(std::size_t pos, std::string& val) if (columnType == Poco::Data::MetaColumn::FDT_JSON && !extractJSON(pos)) return false; + if (columnType == Poco::Data::MetaColumn::FDT_BLOB && !extractLongLOB(pos)) + return false; + val.assign(reinterpret_cast(_metadata.rawData(pos)), _metadata.length(pos)); return true; } diff --git a/Data/MySQL/testsuite/src/MySQLTest.cpp b/Data/MySQL/testsuite/src/MySQLTest.cpp index 93d675d50..cbe6a5dc8 100644 --- a/Data/MySQL/testsuite/src/MySQLTest.cpp +++ b/Data/MySQL/testsuite/src/MySQLTest.cpp @@ -479,6 +479,14 @@ void MySQLTest::testLongBLOB() _pExecutor->longBlob(); } +void MySQLTest::testLongTEXT() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonLongBLOBTable(); + _pExecutor->longText(); +} + void MySQLTest::testJSON() { if (!_pSession) fail("Test not available."); @@ -793,8 +801,8 @@ void MySQLTest::recreatePersonJSONTable() { dropTable("Person"); try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Biography JSON)", now; } - catch (ConnectionException& ce) { std::cout << ce.displayText() << std::endl; fail("recreatePersonLongBLOBTable()"); } - catch (StatementException& se) { std::cout << se.displayText() << std::endl; fail("recreatePersonLongBLOBTable()"); } + catch (ConnectionException& ce) { std::cout << ce.displayText() << std::endl; fail("recreatePersonJSONTable()"); } + catch (StatementException& se) { std::cout << se.displayText() << std::endl; fail("recreatePersonJSONTable()"); } } @@ -966,6 +974,7 @@ CppUnit::Test* MySQLTest::suite() //CppUnit_addTest(pSuite, MySQLTest, testBLOB); CppUnit_addTest(pSuite, MySQLTest, testBLOBStmt); CppUnit_addTest(pSuite, MySQLTest, testLongBLOB); + CppUnit_addTest(pSuite, MySQLTest, testLongTEXT); CppUnit_addTest(pSuite, MySQLTest, testJSON); CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts); CppUnit_addTest(pSuite, MySQLTest, testFloat); diff --git a/Data/MySQL/testsuite/src/MySQLTest.h b/Data/MySQL/testsuite/src/MySQLTest.h index b420e4580..8afdfb2d2 100644 --- a/Data/MySQL/testsuite/src/MySQLTest.h +++ b/Data/MySQL/testsuite/src/MySQLTest.h @@ -80,6 +80,7 @@ public: void testBLOB(); void testBLOBStmt(); void testLongBLOB(); + void testLongTEXT(); void testJSON(); void testUnsignedInts(); diff --git a/Data/MySQL/testsuite/src/SQLExecutor.cpp b/Data/MySQL/testsuite/src/SQLExecutor.cpp index 450ef507c..6c036b9b4 100644 --- a/Data/MySQL/testsuite/src/SQLExecutor.cpp +++ b/Data/MySQL/testsuite/src/SQLExecutor.cpp @@ -1488,6 +1488,31 @@ void SQLExecutor::longBlob() poco_assert (res == biography); } +void SQLExecutor::longText() +{ + std::string funct = "longText()"; + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + std::string biography("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 123); + + int count = 0; + Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(biography)); + ins.execute(); + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assertTrue (count == 1); + + std::string longTextRes; + poco_assert (longTextRes.size() == 0); + Statement stmt = (*_pSession << "SELECT Biography FROM Person", into(longTextRes)); + try { stmt.execute(); } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + poco_assert (longTextRes == biography); +} + void SQLExecutor::json() { std::string funct = "json()"; diff --git a/Data/MySQL/testsuite/src/SQLExecutor.h b/Data/MySQL/testsuite/src/SQLExecutor.h index 315eb4d12..0bec61457 100644 --- a/Data/MySQL/testsuite/src/SQLExecutor.h +++ b/Data/MySQL/testsuite/src/SQLExecutor.h @@ -85,6 +85,7 @@ public: void time(); void timestamp(); void longBlob(); + void longText(); void json(); void unsignedInts(); void floats();