From 561da29b0d53fa70e055c97144ef90d9169fad0f Mon Sep 17 00:00:00 2001 From: fnc12 Date: Wed, 8 Jan 2020 19:06:23 +0300 Subject: [PATCH] added replace core func --- dev/core_functions.h | 15 +++++++++ examples/core_functions.cpp | 35 +++++++++++++++++++- include/sqlite_orm/sqlite_orm.h | 15 +++++++++ tests/core_functions_tests.cpp | 58 +++++++++++++++++++++++++++++++++ tests/tests2.cpp | 2 +- 5 files changed, 123 insertions(+), 2 deletions(-) diff --git a/dev/core_functions.h b/dev/core_functions.h index 6b2cc6759..685cb31c5 100644 --- a/dev/core_functions.h +++ b/dev/core_functions.h @@ -105,6 +105,12 @@ namespace sqlite_orm { } }; + struct replace_string { + operator std::string() const { + return "REPLACE"; + } + }; + #if SQLITE_VERSION_NUMBER >= 3007016 struct char_string { @@ -349,6 +355,15 @@ namespace sqlite_orm { return {move(args)}; } + /** + * REPLACE(X) function https://sqlite.org/lang_corefunc.html#replace + */ + template + core_functions::core_function_t replace(X x, Y y, Z z) { + std::tuple args{std::forward(x), std::forward(y), std::forward(z)}; + return {move(args)}; + } + #if SQLITE_VERSION_NUMBER >= 3007016 /** diff --git a/examples/core_functions.cpp b/examples/core_functions.cpp index f778f6e4b..91da9e09e 100644 --- a/examples/core_functions.cpp +++ b/examples/core_functions.cpp @@ -13,6 +13,13 @@ struct MarvelHero { short points; }; +struct Contact { + int id = 0; + std::string firstName; + std::string lastName; + std::string phone; +}; + int main(int, char **argv) { cout << "path = " << argv[0] << endl; @@ -22,7 +29,12 @@ int main(int, char **argv) { make_column("id", &MarvelHero::id, primary_key()), make_column("name", &MarvelHero::name), make_column("abilities", &MarvelHero::abilities), - make_column("points", &MarvelHero::points))); + make_column("points", &MarvelHero::points)), + make_table("contacts", + make_column("contact_id", &Contact::id, primary_key()), + make_column("first_name", &Contact::firstName), + make_column("last_name", &Contact::lastName), + make_column("phone", &Contact::phone))); storage.sync_schema(); storage.remove_all(); @@ -42,6 +54,11 @@ int main(int, char **argv) { return true; }); + Contact john{0, "John", "Doe", "410-555-0168"}; + Contact lily{0, "Lily", "Bush", "410-444-9862"}; + john.id = storage.insert(john); + lily.id = storage.insert(lily); + // SELECT LENGTH(name) // FROM marvel auto nameLengths = storage.select(length(&MarvelHero::name)); // nameLengths is std::vector @@ -291,5 +308,21 @@ int main(int, char **argv) { cout << endl; } + // SELECT REPLACE('AA B CC AAA','A','Z') + cout << "SELECT REPLACE('AA B CC AAA','A','Z') = " << storage.select(replace("AA B CC AAA", "A", "Z")).front() + << endl; + + // SELECT REPLACE('This is a cat','This','That') + cout << "SELECT REPLACE('This is a cat','This','That') = " + << storage.select(replace("This is a cat", "This", "That")).front() << endl; + + // UPDATE contacts + // SET phone = REPLACE(phone, '410', '+1-410') + storage.update_all(set(c(&Contact::phone) = replace(&Contact::phone, "410", "+1-410"))); + cout << "Contacts:" << endl; + for(auto &contact: storage.iterate()) { + cout << storage.dump(contact) << endl; + } + return 0; } diff --git a/include/sqlite_orm/sqlite_orm.h b/include/sqlite_orm/sqlite_orm.h index eb4f3d717..9e722eba0 100644 --- a/include/sqlite_orm/sqlite_orm.h +++ b/include/sqlite_orm/sqlite_orm.h @@ -3426,6 +3426,12 @@ namespace sqlite_orm { } }; + struct replace_string { + operator std::string() const { + return "REPLACE"; + } + }; + #if SQLITE_VERSION_NUMBER >= 3007016 struct char_string { @@ -3670,6 +3676,15 @@ namespace sqlite_orm { return {move(args)}; } + /** + * REPLACE(X) function https://sqlite.org/lang_corefunc.html#replace + */ + template + core_functions::core_function_t replace(X x, Y y, Z z) { + std::tuple args{std::forward(x), std::forward(y), std::forward(z)}; + return {move(args)}; + } + #if SQLITE_VERSION_NUMBER >= 3007016 /** diff --git a/tests/core_functions_tests.cpp b/tests/core_functions_tests.cpp index 3a57ad15f..06ee00540 100644 --- a/tests/core_functions_tests.cpp +++ b/tests/core_functions_tests.cpp @@ -306,3 +306,61 @@ TEST_CASE("instr") { REQUIRE_THAT(rows, UnorderedEquals(expected)); } } + +namespace replace_func_local { + struct Contact { + int id = 0; + std::string firstName; + std::string lastName; + std::string phone; + }; + + bool operator==(const Contact &lhs, const Contact &rhs) { + return lhs.id == rhs.id && lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && + lhs.phone == rhs.phone; + } +} + +TEST_CASE("replace func") { + using Catch::Matchers::UnorderedEquals; + using namespace replace_func_local; + + auto storage = make_storage({}, + make_table("contacts", + make_column("contact_id", &Contact::id, primary_key()), + make_column("first_name", &Contact::firstName), + make_column("last_name", &Contact::lastName), + make_column("phone", &Contact::phone))); + storage.sync_schema(); + { + auto rows = storage.select(replace("AA B CC AAA", "A", "Z")); + REQUIRE(rows.size() == 1); + REQUIRE(rows.front() == "ZZ B CC ZZZ"); + } + { + auto rows = storage.select(replace("This is a cat", "This", "That")); + REQUIRE(rows.size() == 1); + REQUIRE(rows.front() == "That is a cat"); + } + Contact john{0, "John", "Doe", "410-555-0168"}; + Contact lily{0, "Lily", "Bush", "410-444-9862"}; + john.id = storage.insert(john); + lily.id = storage.insert(lily); + { + auto contacts = storage.get_all(); + std::vector expected; + expected.push_back(john); + expected.push_back(lily); + REQUIRE_THAT(contacts, UnorderedEquals(expected)); + } + storage.update_all(set(c(&Contact::phone) = replace(&Contact::phone, "410", "+1-410"))); + { + auto contacts = storage.get_all(); + john.phone = "+1-410-555-0168"; + lily.phone = "+1-410-444-9862"; + std::vector expected; + expected.push_back(john); + expected.push_back(lily); + REQUIRE_THAT(contacts, UnorderedEquals(expected)); + } +} diff --git a/tests/tests2.cpp b/tests/tests2.cpp index 2ffe3eee5..b9dc64cf1 100644 --- a/tests/tests2.cpp +++ b/tests/tests2.cpp @@ -254,7 +254,7 @@ TEST_CASE("Select") { REQUIRE(storage.get(firstId).currentWord == "ototo"); } -TEST_CASE("Replace") { +TEST_CASE("Replace query") { struct Object { int id; std::string name;