From 3a6300a077df7222f04363fa36fe48a6339a1664 Mon Sep 17 00:00:00 2001 From: bergmann Date: Fri, 14 Sep 2018 18:41:29 +0200 Subject: [PATCH] * improved read methods of mariadb driver --- .../cpphibernate/driver/mariadb/impl/read.h | 31 +- src/driver/mariadb/schema/table.cpp | 17 +- test/cpphibernate_init.cpp | 4 +- test/cpphibernate_read.cpp | 276 +++++++++++++++++- 4 files changed, 314 insertions(+), 14 deletions(-) diff --git a/include/cpphibernate/driver/mariadb/impl/read.h b/include/cpphibernate/driver/mariadb/impl/read.h index 232df10..e0048a3 100644 --- a/include/cpphibernate/driver/mariadb/impl/read.h +++ b/include/cpphibernate/driver/mariadb/impl/read.h @@ -103,7 +103,7 @@ beg_namespace_cpphibernate_driver_mariadb virtual void* emplace_intern(void* data, size_t dataset_id) const override { if (data && !misc::is_pointer::value) - throw misc::hibernate_exception("This is not a pointer type!"); + throw misc::hibernate_exception("None pointer type can not be assigned!"); ++_count; if (_count > 1) throw misc::hibernate_exception("Expected exactly one dataset, but received more!"); @@ -165,10 +165,31 @@ beg_namespace_cpphibernate_driver_mariadb private: virtual void* emplace_intern(void* data, size_t dataset_id) const override { - if (data || dataset_id != 0) - throw misc::hibernate_exception("Static datasets can not be assigned!"); - auto& value = container_helper_type::emplace(_dataset); - return set(value); + return hana::eval_if( + misc::is_nullable { }, + [this, &data, &dataset_id](auto _){ + using nullable_type = typename mp::decay_t))>::type; + using nullable_helper_type = misc::nullable_helper; + using inner_value_type = typename nullable_helper_type::value_type; + + if (!data) + throw misc::hibernate_exception("Expected dynamic data for pointer type!"); + if (!misc::is_pointer::value) + throw misc::hibernate_exception("None pointer type can not be assigned!"); + + auto& nullable = container_helper_type::emplace(this->_dataset); + auto* cast = static_cast(data); + auto& value = nullable_helper_type::set(nullable, cast); + if (cast != &value) + throw misc::hibernate_exception("Nullable pointer value has changed!"); + return set(value, dataset_id); + }, + [this, &data, &dataset_id](){ + if (data || dataset_id != 0) + throw misc::hibernate_exception("Static datasets can not be assigned!"); + auto& value = container_helper_type::emplace(this->_dataset); + return this->set(value); + }); } virtual void finish_intern() const override diff --git a/src/driver/mariadb/schema/table.cpp b/src/driver/mariadb/schema/table.cpp index de787cc..02b432f 100644 --- a/src/driver/mariadb/schema/table.cpp +++ b/src/driver/mariadb/schema/table.cpp @@ -530,7 +530,7 @@ std::string build_init_stage1_query(const table_t& table) << field_info.table_name << "_index_" << field_info.field_name - << "` UNSIGNED INT NOT NULL,"; + << "` INT UNSIGNED NOT NULL,"; } } @@ -1281,6 +1281,7 @@ void table_t::read_exec(const read_context& context) const auto& ref_table = *field.referenced_table; auto& ref_field = *ref_table.primary_key_field; + { std::ostringstream ss; ss << "WHERE (`" << ref_table.table_name @@ -1296,6 +1297,20 @@ void table_t::read_exec(const read_context& context) const << ref_field.convert_to_close << ")"; next_context.where = ss.str(); + } + + { + std::ostringstream ss; + ss << "ORDER BY `" + << ref_table.table_name + << "`.`" + << field.table_name + << "_index_" + << field.field_name + << "` ASC"; + next_context.order_by = ss.str(); + } + ref_table.read(next_context); } } \ No newline at end of file diff --git a/test/cpphibernate_init.cpp b/test/cpphibernate_init.cpp index 021e5ab..ca641f2 100644 --- a/test/cpphibernate_init.cpp +++ b/test/cpphibernate_init.cpp @@ -83,9 +83,9 @@ TEST(CppHibernateTests, init) "(\n" " `tbl_test3_id` BINARY(16) NOT NULL,\n" " `tbl_derived3_id_test3_list` BINARY(16) NULL DEFAULT NULL,\n" - " `tbl_derived3_index_test3_list` UNSIGNED INT NOT NULL,\n" + " `tbl_derived3_index_test3_list` INT UNSIGNED NOT NULL,\n" " `tbl_derived3_id_test3_vector` BINARY(16) NULL DEFAULT NULL,\n" - " `tbl_derived3_index_test3_vector` UNSIGNED INT NOT NULL,\n" + " `tbl_derived3_index_test3_vector` INT UNSIGNED NOT NULL,\n" " `u32_data` INT UNSIGNED NOT NULL,\n" " `i32_data` INT NOT NULL,\n" " `u64_data` BIGINT UNSIGNED NOT NULL,\n" diff --git a/test/cpphibernate_read.cpp b/test/cpphibernate_read.cpp index a80cc1d..4e5a55a 100644 --- a/test/cpphibernate_read.cpp +++ b/test/cpphibernate_read.cpp @@ -340,7 +340,9 @@ TEST(CppHibernateTests, read_derived3_static) "FROM " "`tbl_test3` " "WHERE " - "(`tbl_test3`.`tbl_derived3_id_test3_list`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) ", + "(`tbl_test3`.`tbl_derived3_id_test3_list`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_list` ASC ", result_used({ { "3d1289f0-abb9-11e8-98d0-529269fb1459", "100", "101", "102", "103" }, { "3d128b26-abb9-11e8-98d0-529269fb1459", "110", "111", "112", "113" }, @@ -354,7 +356,9 @@ TEST(CppHibernateTests, read_derived3_static) "FROM " "`tbl_test3` " "WHERE " - "(`tbl_test3`.`tbl_derived3_id_test3_vector`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) ", + "(`tbl_test3`.`tbl_derived3_id_test3_vector`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_vector` ASC ", result_used({ { "3d128eb4-abb9-11e8-98d0-529269fb1459", "120", "121", "122", "123" }, { "3d128ffe-abb9-11e8-98d0-529269fb1459", "130", "131", "132", "133" }, @@ -440,9 +444,9 @@ TEST(CppHibernateTests, read_derived3_static) } } -TEST(CppHibernateTests, read_base_ptr_dynamic) +TEST(CppHibernateTests, read_derived2_ptr_dynamic) { -StrictMock mock; + StrictMock mock; expect_query(mock, "START TRANSACTION"); expect_query(mock, "SELECT " @@ -499,7 +503,9 @@ StrictMock mock; "FROM " "`tbl_test3` " "WHERE " - "(`tbl_test3`.`tbl_derived3_id_test3_list`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) ", + "(`tbl_test3`.`tbl_derived3_id_test3_list`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_list` ASC ", result_used({ { "3d1289f0-abb9-11e8-98d0-529269fb1459", "100", "101", "102", "103" }, { "3d128b26-abb9-11e8-98d0-529269fb1459", "110", "111", "112", "113" }, @@ -513,7 +519,9 @@ StrictMock mock; "FROM " "`tbl_test3` " "WHERE " - "(`tbl_test3`.`tbl_derived3_id_test3_vector`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) ", + "(`tbl_test3`.`tbl_derived3_id_test3_vector`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_vector` ASC ", result_used({ { "3d128eb4-abb9-11e8-98d0-529269fb1459", "120", "121", "122", "123" }, { "3d128ffe-abb9-11e8-98d0-529269fb1459", "130", "131", "132", "133" }, @@ -600,3 +608,259 @@ StrictMock mock; EXPECT_EQ(it, d3.test3_vector.end()); } } + +TEST(CppHibernateTests, read_base_ptr_vector_dynamic) +{ + StrictMock mock; + + expect_query(mock, "START TRANSACTION"); + expect_query(mock, "SELECT " + "`tbl_base`.`__type` AS `__type`, " + "BinToUuid(`tbl_base`.`tbl_base_id`), " + "`tbl_base`.`name`, " + "BinToUuid(`tbl_derived1`.`tbl_derived1_id`), " + "`tbl_derived1`.`enum_data`, " + "BinToUuid(`T0`.`tbl_test1_id`), " + "`T0`.`str_data`, " + "`T0`.`str64_data`, " + "`T0`.`u32_nullable`, " + "`T0`.`u32_ptr_u`, " + "`T0`.`u32_ptr_s`, " + "BinToUuid(`tbl_derived2`.`tbl_derived2_id`), " + "BinToUuid(`T1`.`tbl_test2_id`), " + "`T1`.`u8_data`, " + "`T1`.`i8_data`, " + "`T1`.`u16_data`, " + "`T1`.`i16_data`, " + "BinToUuid(`T2`.`tbl_test2_id`), " + "`T2`.`u8_data`, " + "`T2`.`i8_data`, " + "`T2`.`u16_data`, " + "`T2`.`i16_data`, " + "BinToUuid(`T3`.`tbl_test2_id`), " + "`T3`.`u8_data`, " + "`T3`.`i8_data`, " + "`T3`.`u16_data`, " + "`T3`.`i16_data`, " + "BinToUuid(`tbl_derived3`.`tbl_derived3_id`) " + "FROM " + "`tbl_base` " + "LEFT JOIN " + "`tbl_derived1` ON `tbl_base`.`tbl_base_id`=`tbl_derived1`.`tbl_base_id` " + "LEFT JOIN " + "`tbl_test1` AS `T0` ON `tbl_derived1`.`tbl_test1_id_test1_data`=`T0`.`tbl_test1_id` " + "LEFT JOIN " + "`tbl_derived2` ON `tbl_base`.`tbl_base_id`=`tbl_derived2`.`tbl_base_id` " + "LEFT JOIN " + "`tbl_test2` AS `T1` ON `tbl_derived2`.`tbl_test2_id_test2_nullable`=`T1`.`tbl_test2_id` " + "LEFT JOIN " + "`tbl_test2` AS `T2` ON `tbl_derived2`.`tbl_test2_id_test2_ptr_u`=`T2`.`tbl_test2_id` " + "LEFT JOIN " + "`tbl_test2` AS `T3` ON `tbl_derived2`.`tbl_test2_id_test2_ptr_s`=`T3`.`tbl_test2_id` " + "LEFT JOIN " + "`tbl_derived3` ON `tbl_derived2`.`tbl_derived2_id`=`tbl_derived3`.`tbl_derived2_id` ", + result_used({ + { + /* base */ "11", "3d12778a-abb9-11e8-98d0-529269fb1459", "derived1", + /* derived1 */ "3d12758c-abb9-11e8-98d0-529269fb1459", "test2", + /* derived1.test1 */ "3d127988-abb9-11e8-98d0-529269fb1459", "str_data of class `test1` object `d1.test1_data`", "str64_data of class `test1` object `d1.test1_data`", "32", nullptr, "789", + /* derived2 */ nullptr, + /* derived2.test2_nullable */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2.test2_ptr_u */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2.test2_ptr_s */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived3 */ nullptr + }, + { + /* base */ "12", "3d127db6-abb9-11e8-98d0-529269fb1459", "derived2", + /* derived1 */ nullptr, nullptr, + /* derived1.test1 */ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2 */ "3d127bcc-abb9-11e8-98d0-529269fb1459", + /* derived2.test2_nullable */ "3d1283a6-abb9-11e8-98d0-529269fb1459", "10", "11", "12", "13", + /* derived2.test2_ptr_u */ "3d128522-abb9-11e8-98d0-529269fb1459", "20", "21", "22", "23", + /* derived2.test2_ptr_s */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived3 */ nullptr + }, + { + /* base */ "13", "3d1288ce-abb9-11e8-98d0-529269fb1459", "derived3", + /* derived1 */ nullptr, nullptr, + /* derived1.test1 */ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2 */ "3d1287a2-abb9-11e8-98d0-529269fb1459", + /* derived2.test2_nullable */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2.test2_ptr_u */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived2.test2_ptr_s */ nullptr, nullptr, nullptr, nullptr, nullptr, + /* derived3 */ "3d12866c-abb9-11e8-98d0-529269fb1459" + }, + })); + expect_query(mock, "SELECT " + "BinToUuid(`tbl_test3`.`tbl_test3_id`), " + "`tbl_test3`.`u32_data`, " + "`tbl_test3`.`i32_data`, " + "`tbl_test3`.`u64_data`, " + "`tbl_test3`.`i64_data` " + "FROM " + "`tbl_test3` " + "WHERE " + "(`tbl_test3`.`tbl_derived3_id_test3_list`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_list` ASC ", + result_used({ + { "3d1289f0-abb9-11e8-98d0-529269fb1459", "100", "101", "102", "103" }, + { "3d128b26-abb9-11e8-98d0-529269fb1459", "110", "111", "112", "113" }, + })); + expect_query(mock, "SELECT " + "BinToUuid(`tbl_test3`.`tbl_test3_id`), " + "`tbl_test3`.`u32_data`, " + "`tbl_test3`.`i32_data`, " + "`tbl_test3`.`u64_data`, " + "`tbl_test3`.`i64_data` " + "FROM " + "`tbl_test3` " + "WHERE " + "(`tbl_test3`.`tbl_derived3_id_test3_vector`=UuidToBin('X3d12866c-abb9-11e8-98d0-529269fb1459X')) " + "ORDER BY " + "`tbl_test3`.`tbl_derived3_index_test3_vector` ASC ", + result_used({ + { "3d128eb4-abb9-11e8-98d0-529269fb1459", "120", "121", "122", "123" }, + { "3d128ffe-abb9-11e8-98d0-529269fb1459", "130", "131", "132", "133" }, + { "3d129134-abb9-11e8-98d0-529269fb1459", "140", "141", "142", "143" }, + })); + expect_query(mock, "COMMIT"); + + EXPECT_CALL( + mock, + mysql_real_escape_string(reinterpret_cast(0x1111), _, _, _)) + .Times(AnyNumber()) + .WillRepeatedly(WithArgs<1, 2, 3>(EscapeString())); + + EXPECT_CALL( + mock, + mysql_close( + reinterpret_cast(0x1111))); + + ::cppmariadb::connection connection(reinterpret_cast(0x1111)); + auto context = make_context(test_schema, connection); + + using base_ptr_type = std::unique_ptr; + using base_vec_type = std::vector; + + base_vec_type base_vec; + context.read(base_vec); + + auto bIt = base_vec.begin(); + { + ASSERT_NE (bIt, base_vec.end()); + auto* base_ptr = bIt->get(); + ASSERT_TRUE(static_cast(base_ptr)); + auto* d1_ptr = dynamic_cast(base_ptr); + ASSERT_TRUE(static_cast(d1_ptr)); + auto& d1 = *d1_ptr; + ++bIt; + + EXPECT_EQ (d1.id, uuid("3d12778a-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ (d1.derived1_id, uuid("3d12758c-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ (d1.name, "derived1"); + EXPECT_EQ (d1.enum_data, test_enum::test2); + EXPECT_EQ (d1.test1_data.str_data, "str_data of class `test1` object `d1.test1_data`"); + EXPECT_EQ (d1.test1_data.str64_data, "str64_data of class `test1` object `d1.test1_data`"); + ASSERT_TRUE (static_cast(d1.test1_data.u32_nullable)); + EXPECT_EQ (*d1.test1_data.u32_nullable, 32); + ASSERT_TRUE (static_cast(d1.test1_data.u32_ptr_s)); + EXPECT_EQ (*d1.test1_data.u32_ptr_s, 789); + EXPECT_FALSE(static_cast(d1.test1_data.u32_ptr_u)); + } + + { + ASSERT_NE (bIt, base_vec.end()); + auto* base_ptr = bIt->get(); + ASSERT_TRUE(static_cast(base_ptr)); + auto* d2_ptr = dynamic_cast(base_ptr); + ASSERT_TRUE(static_cast(d2_ptr)); + auto& d2 = *d2_ptr; + ++bIt; + + EXPECT_EQ (d2.id, uuid("3d127db6-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ (d2.derived2_id, uuid("3d127bcc-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ (d2.name, "derived2"); + ASSERT_TRUE (static_cast(d2.test2_nullable)); + EXPECT_EQ (d2.test2_nullable->u8_data, 10); + EXPECT_EQ (d2.test2_nullable->i8_data, 11); + EXPECT_EQ (d2.test2_nullable->u16_data, 12); + EXPECT_EQ (d2.test2_nullable->i16_data, 13); + ASSERT_TRUE (static_cast(d2.test2_ptr_u)); + EXPECT_EQ (d2.test2_ptr_u->u8_data, 20); + EXPECT_EQ (d2.test2_ptr_u->i8_data, 21); + EXPECT_EQ (d2.test2_ptr_u->u16_data, 22); + EXPECT_EQ (d2.test2_ptr_u->i16_data, 23); + EXPECT_FALSE(static_cast(d2.test2_ptr_s)); + } + + { + ASSERT_NE (bIt, base_vec.end()); + auto* base_ptr = bIt->get(); + ASSERT_TRUE(static_cast(base_ptr)); + auto* d3_ptr = dynamic_cast(base_ptr); + ASSERT_TRUE(static_cast(d3_ptr)); + auto& d3 = *d3_ptr; + ++bIt; + + EXPECT_EQ (d3.id, uuid("3d1288ce-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ (d3.name, "derived3"); + EXPECT_EQ (d3.derived2_id, uuid("3d1287a2-abb9-11e8-98d0-529269fb1459")); + EXPECT_FALSE(static_cast(d3.test2_nullable)); + EXPECT_FALSE(static_cast(d3.test2_ptr_u)); + EXPECT_FALSE(static_cast(d3.test2_ptr_s)); + EXPECT_EQ (d3.derived3_id, uuid("3d12866c-abb9-11e8-98d0-529269fb1459")); + + { + auto it = d3.test3_list.begin(); + ASSERT_NE(it, d3.test3_list.end()); + EXPECT_EQ(it->id, uuid("3d1289f0-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ(it->u32_data, 100); + EXPECT_EQ(it->i32_data, 101); + EXPECT_EQ(it->u64_data, 102); + EXPECT_EQ(it->i64_data, 103); + ++it; + + ASSERT_NE(it, d3.test3_list.end()); + EXPECT_EQ(it->id, uuid("3d128b26-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ(it->u32_data, 110); + EXPECT_EQ(it->i32_data, 111); + EXPECT_EQ(it->u64_data, 112); + EXPECT_EQ(it->i64_data, 113); + ++it; + + EXPECT_EQ(it, d3.test3_list.end()); + } + + { + auto it = d3.test3_vector.begin(); + ASSERT_NE(it, d3.test3_vector.end()); + EXPECT_EQ(it->id, uuid("3d128eb4-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ(it->u32_data, 120); + EXPECT_EQ(it->i32_data, 121); + EXPECT_EQ(it->u64_data, 122); + EXPECT_EQ(it->i64_data, 123); + ++it; + + ASSERT_NE(it, d3.test3_vector.end()); + EXPECT_EQ(it->id, uuid("3d128ffe-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ(it->u32_data, 130); + EXPECT_EQ(it->i32_data, 131); + EXPECT_EQ(it->u64_data, 132); + EXPECT_EQ(it->i64_data, 133); + ++it; + + ASSERT_NE(it, d3.test3_vector.end()); + EXPECT_EQ(it->id, uuid("3d129134-abb9-11e8-98d0-529269fb1459")); + EXPECT_EQ(it->u32_data, 140); + EXPECT_EQ(it->i32_data, 141); + EXPECT_EQ(it->u64_data, 142); + EXPECT_EQ(it->i64_data, 143); + ++it; + + EXPECT_EQ(it, d3.test3_vector.end()); + } + } + + EXPECT_EQ(bIt, base_vec.end()); +} \ No newline at end of file