issue #24 - insert DTO type ENUM as string

This commit is contained in:
bwengert79 2024-10-01 16:37:56 -04:00
parent 812572b559
commit 3d4f842ae7
5 changed files with 307 additions and 8 deletions

View File

@ -399,8 +399,23 @@ void Serializer::serializeEnum(const Serializer* _this, OutputData& outData, con
const auto& enumInterpretation = polymorphicDispatcher->toInterpretation(polymorph, false, e);
if(e == data::type::EnumInterpreterError::OK) {
_this->serialize(outData, enumInterpretation);
return;
if (enumInterpretation &&
enumInterpretation.getValueType()->classId == data::type::__class::String::CLASS_ID)
{
std::string* buff = static_cast<std::string*>(enumInterpretation.get());
outData.dataBuffer.reset(new char[buff->size()]);
outData.data = outData.dataBuffer.get();
outData.dataSize = buff->size();
outData.dataFormat = 1;
outData.oid = TEXTOID;
std::memcpy(outData.data, buff->data(), outData.dataSize);
}
else
{
_this->serialize(outData, enumInterpretation);
}
return;
}
switch(e) {

View File

@ -0,0 +1,15 @@
DROP TABLE IF EXISTS test_enumasstring;
CREATE TABLE test_enumasstring (
f_enumint int,
f_enumstring varchar(256)
);
INSERT INTO test_enumasstring
(f_enumint, f_enumstring) VALUES (null, null);
INSERT INTO test_enumasstring
(f_enumint, f_enumstring) VALUES (0, 'dog');
INSERT INTO test_enumasstring
(f_enumint, f_enumstring) VALUES (1, 'cat');

View File

@ -6,6 +6,7 @@
#include "types/FloatTest.hpp"
#include "types/InterpretationTest.hpp"
#include "types/CharacterTest.hpp"
#include "types/EnumAsStringTest.hpp"
#include "oatpp-postgresql/orm.hpp"
@ -35,14 +36,15 @@ void runTests() {
std::this_thread::sleep_for(std::chrono::seconds(10));
}
OATPP_RUN_TEST(oatpp::test::postgresql::ql_template::ParserTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::ql_template::ParserTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::IntTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::FloatTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::ArrayTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::InterpretationTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::CharacterTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::types::IntTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::types::FloatTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::types::ArrayTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::types::InterpretationTest);
//OATPP_RUN_TEST(oatpp::test::postgresql::types::CharacterTest);
OATPP_RUN_TEST(oatpp::test::postgresql::types::EnumAsStringTest);
}
}

View File

@ -0,0 +1,227 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed 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 "EnumAsStringTest.hpp"
#include "oatpp-postgresql/orm.hpp"
#include "oatpp/json/ObjectMapper.hpp"
#include <limits>
#include <cstdio>
namespace oatpp { namespace test { namespace postgresql { namespace types {
namespace {
#include OATPP_CODEGEN_BEGIN(DTO)
ENUM(Animal, v_int32,
VALUE(DOG, 0, "dog"),
VALUE(CAT, 1, "cat"),
VALUE(BIRD, 2, "bird"),
VALUE(HORSE, 3, "horse")
)
class Row : public oatpp::DTO {
DTO_INIT(Row, DTO);
DTO_FIELD(Enum<Animal>::AsNumber, f_enumint);
DTO_FIELD(Enum<Animal>::AsString, f_enumstring);
};
#include OATPP_CODEGEN_END(DTO)
#include OATPP_CODEGEN_BEGIN(DbClient)
class MyClient : public oatpp::orm::DbClient {
public:
MyClient(const std::shared_ptr<oatpp::orm::Executor>& executor)
: oatpp::orm::DbClient(executor)
{
executeQuery("DROP TABLE IF EXISTS oatpp_schema_version_EnumAsStringTest;", {});
oatpp::orm::SchemaMigration migration(executor, "EnumAsStringTest");
migration.addFile(1, TEST_DB_MIGRATION "EnumAsStringTest.sql");
migration.migrate();
auto version = executor->getSchemaVersion("EnumAsStringTest");
OATPP_LOGd("DbClient", "Migration - OK. Version={}.", version);
}
QUERY(insertValues,
"INSERT INTO test_EnumAsString "
"(f_enumint, f_enumstring) "
"VALUES "
"(:row.f_enumint, :row.f_enumstring);",
PARAM(oatpp::Object<Row>, row), PREPARE(true))
QUERY(deleteValues,
"DELETE FROM test_EnumAsString;")
QUERY(selectValues, "SELECT * FROM test_EnumAsString;")
};
#include OATPP_CODEGEN_END(DbClient)
}
void EnumAsStringTest::onRun() {
OATPP_LOGi(TAG, "DB-URL='{}'", TEST_DB_URL);
auto connectionProvider = std::make_shared<oatpp::postgresql::ConnectionProvider>(TEST_DB_URL);
auto executor = std::make_shared<oatpp::postgresql::Executor>(connectionProvider);
auto client = MyClient(executor);
{
auto res = client.selectValues();
if(res->isSuccess()) {
OATPP_LOGd(TAG, "OK, knownCount={}, hasMore={}", res->getKnownCount(), res->hasMoreToFetch());
} else {
auto message = res->getErrorMessage();
OATPP_LOGd(TAG, "Error, message={}", message->c_str());
}
auto dataset = res->fetch<oatpp::Vector<oatpp::Object<Row>>>();
oatpp::json::ObjectMapper om;
om.serializerConfig().json.useBeautifier = true;
om.serializerConfig().mapper.enabledInterpretations = { "postgresql" };
auto str = om.writeToString(dataset);
OATPP_LOGd(TAG, "res={}", str->c_str());
OATPP_ASSERT(dataset->size() == 3);
{
auto row = dataset[0];
OATPP_ASSERT(row->f_enumint == nullptr);
OATPP_ASSERT(row->f_enumstring == nullptr);
}
{
auto row = dataset[1];
OATPP_ASSERT(row->f_enumint == Animal::DOG);
OATPP_ASSERT(row->f_enumstring == Animal::DOG);
}
{
auto row = dataset[2];
OATPP_ASSERT(row->f_enumint == Animal::CAT);
OATPP_ASSERT(row->f_enumstring == Animal::CAT);
}
}
{
auto res = client.deleteValues();
if (res->isSuccess()) {
OATPP_LOGd(TAG, "OK, knownCount={}, hasMore={}", res->getKnownCount(), res->hasMoreToFetch());
} else {
auto message = res->getErrorMessage();
OATPP_LOGd(TAG, "Error, message={}", message->c_str());
}
OATPP_ASSERT(res->isSuccess());
}
{
auto connection = client.getConnection();
{
auto row = Row::createShared();
row->f_enumint = nullptr;
row->f_enumstring = nullptr;
auto res = client.insertValues(row, connection);
if (res->isSuccess()) {
OATPP_LOGd(TAG, "OK, knownCount={}, hasMore={}", res->getKnownCount(), res->hasMoreToFetch());
}
else {
auto message = res->getErrorMessage();
OATPP_LOGd(TAG, "Error, message={}", message->c_str());
}
OATPP_ASSERT(res->isSuccess());
}
{
auto row = Row::createShared();
row->f_enumint = Animal::HORSE;
row->f_enumstring = Animal::HORSE;
auto res = client.insertValues(row, connection);
if (res->isSuccess()) {
OATPP_LOGd(TAG, "OK, knownCount={}, hasMore={}", res->getKnownCount(), res->hasMoreToFetch());
}
else {
auto message = res->getErrorMessage();
OATPP_LOGd(TAG, "Error, message={}", message->c_str());
}
OATPP_ASSERT(res->isSuccess());
}
}
{
auto res = client.selectValues();
if(res->isSuccess()) {
OATPP_LOGd(TAG, "OK, knownCount={}, hasMore={}", res->getKnownCount(), res->hasMoreToFetch());
} else {
auto message = res->getErrorMessage();
OATPP_LOGd(TAG, "Error, message={}", message->c_str());
}
auto dataset = res->fetch<oatpp::Vector<oatpp::Object<Row>>>();
oatpp::json::ObjectMapper om;
om.serializerConfig().json.useBeautifier = true;
om.serializerConfig().mapper.enabledInterpretations = { "postgresql" };
auto str = om.writeToString(dataset);
OATPP_LOGd(TAG, "res={}", str->c_str());
OATPP_ASSERT(dataset->size() == 2);
{
auto row = dataset[0];
OATPP_ASSERT(row->f_enumint == nullptr);
OATPP_ASSERT(row->f_enumstring == nullptr);
}
{
auto row = dataset[1];
OATPP_ASSERT(row->f_enumint == Animal::HORSE);
OATPP_ASSERT(row->f_enumstring == Animal::HORSE);
}
}
}
}}}}

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed 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.
*
***************************************************************************/
#ifndef oatpp_test_postgresql_types_EnumAsStringTest_hpp
#define oatpp_test_postgresql_types_EnumAsStringTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace test { namespace postgresql { namespace types {
class EnumAsStringTest : public UnitTest {
public:
EnumAsStringTest() : UnitTest("TEST[postgresql::types::EnumAsStringTest]") {}
void onRun() override;
};
}}}}
#endif // oatpp_test_postgresql_types_EnumAsStringTest_hpp