v1.4
⭐ CASE support
// SELECT ID, NAME, MARKS,
// CASE
// WHEN MARKS >=80 THEN 'A+'
// WHEN MARKS >=70 THEN 'A'
// WHEN MARKS >=60 THEN 'B'
// WHEN MARKS >=50 THEN 'C'
// ELSE 'Sorry!! Failed'
// END
// FROM STUDENT;
auto rows = storage.select(columns(&Student::id,
&Student::name,
&Student::marks,
case_<std::string>()
.when(greater_or_equal(&Student::marks, 80), then("A+"))
.when(greater_or_equal(&Student::marks, 70), then("A"))
.when(greater_or_equal(&Student::marks, 60), then("B"))
.when(greater_or_equal(&Student::marks, 50), then("C"))
.else_("Sorry!! Failed")
.end()));
// decltype(rows) is std::vector<std::tuple<decltype(Student::id), decltype(Student::name), decltype(Student::marks), std::string>>
or
// SELECT CASE country WHEN 'USA' THEN 'Dosmetic' ELSE 'Foreign' END
// FROM users
auto rows = storage.select(columns(case_<std::string>(&User::country)
.when("USA", then("Dosmetic"))
.else_("Foreign")
.end()),
multi_order_by(order_by(&User::lastName), order_by(&User::firstName)));
// decltype(rows) is std::vector<std::string>
⭐ Added core functions: COALESCE, ZEROBLOB, SUBSTR
// SELECT coalesce(10,20);
cout << "coalesce(10,20) = " << storage.select(coalesce<int>(10, 20)).front() << endl;
// SELECT substr('SQLite substr', 8);
cout << "substr('SQLite substr', 8) = " << storage.select(substr("SQLite substr", 8)).front() << endl;
// SELECT substr('SQLite substr', 1, 6);
cout << "substr('SQLite substr', 1, 6) = " << storage.select(substr("SQLite substr", 1, 6)).front() << endl;
// SELECT zeroblob(5);
cout << "zeroblob(5) = " << storage.select(zeroblob(5)).front().size() << endl;
⭐ Dynamic ORDER BY
order_by
and multi_order_by
are strong typed so you cannot specify ORDER BY column type at runtime. dynamic_order_by
solves this problem. dynamic_order_by
is a multi_order_by
that accepts order_by
conditions at runtime. Example:
auto orderBy = dynamic_order_by(storage);
if(shouldOrderByNameAndId){
orderBy.push_back(order_by(&User::name));
orderBy.push_back(order_by(&User::id));
}else{
orderBy.push_back(order_by(&User::id));
}
auto rows = storage.get_all<User>(where(...), orderBy);
⭐ Added LIKE as a query result
Now LIKE
can also be used as a core function to retrieve a result:
auto rows = storage.select(like(&User::name, "J%"));
// decltype(rows) is std::vector<bool>
⭐ Added LIKE ESCAPE option support
LIKE
has a third argument and now it is available in sqlite_orm
:
// SELECT name LIKE 'J%' ESCAPE '_'
// FROM users
auto rows = storage.select(like(&User::name, "J%").escape("_"));
or
// SELECT LIKE(name, 'J%', '_')
// FROM users
auto rows = storage.select(like(&User::name, "J%", "_"));
- ⚙️ Added Catch2 unit tests framework into unit tests project
- ⚙️ Added unit tests configurations for even more platforms and compilers (thanks to @Farwaykorse)
- ⚙️ Added contributing doc
- 🚀 Added
nullptr
binding to WHERE conditions - 🚀 Reduced binary size
- 🚀 Added composite key support for
storage_t::remove
function - 🚀 Reduces memory consumption
🚀 Better error reporting
Before once you get an exception thrown asking e.what()
gave you a poor text like NOT NULL constraint failed
. Now it is more detailed (thanks to sqlite3_errmsg
function) like: NOT NULL constraint failed: users.age: constraint failed
🐞 Bug fixes
- Fixed GCC6 compilation bug
- Fixed runtime error on ARM architecture
- Fixed getter by value support for
storage_t::replace
andstorage_t::update
functions - Fixed bug with iterating over blob values
- Fixed on_copy coping on
storage_t
copy - Fixed silencing binding failure - now exception is thrown
- Fixed using
std::unique_ptr
instorage_t::update_all
set arguments - Fixed incorrect (reverse) arguments order in GROUP BY