v1.5
⭐ Prepared statements
// SELECT doctor_id
// FROM visits
// WHERE LENGTH(patient_name) > 8
auto selectStatement = storage.prepare(select(&Visit::doctor_id,
where(length(&Visit::patient_name) > 8)));
cout << "selectStatement = " << selectStatement.sql() << endl;
auto rows = storage.execute(selectStatement);
get<0>(selectStatement) = 10; // change LENGTH(patient_name) > 8 to LENGTH(patient_name) > 10
auto rows2 = storage.execute(selectStatement);
More info can be found in the example
⭐ GLOB operator
// SELECT id, first_name, last_name
// FROM users
// WHERE first_name GLOB 'C*'
auto users = storage.get_all<User>(where(glob(&User::firstName, "C*")));
or
// SELECT id
// FROM users
// WHERE last_name GLOB '*a*' OR first_name LIKE 'J%'
auto rows = storage.select(&User::id, where(glob(lower(&User::lastName), "*a*")
or like(&User::firstName, "J%"));
⭐ std::optional support (C++17 and higher)
auto userMaybe = storage.get_optional<User>(14); // decltype(userMaybe) is std::optional<User>
if(userMaybe.has_value()){
cout << "user = " << storage.dump(userMaybe.value()) << endl;
}else{
cout << "user with id 14 doesn't exist" << endl;
}
std::optional
better suites for returning nullable data than std::unique_ptr
so it is highly recommended to use storage_t::get_optional
instead of storage_t::get_pointer
to avoid extra heap allocations. Hint: available only with C++17 or higher. One can set C++ standard version with -std=c++17
compiler option with clang
and gcc
or in target properties in Visual Studio and Xcode. For different build systems please check out related documentation.
More info about std::optional on cppreference
⭐ get_all_pointer query
storage_t:: get_all_pointer
can be useful if you want to obtain your objects allocated as unique pointers.
auto users = storage.get_all_pointer<User>(); // decltype(users) is std::vector<std::unique_ptr<User>>
or
auto statement = storage.prepare(get_all_pointer<User>(where(c(&User::id) < 100));
auto users = storage.execute(statement); // decltype(users) is std::vector<std::unique_ptr<User>>
⭐ Improved DEFAULT constraint
DEFAULT
constraint can accept not only literals but functions like DATETIME
. sqlite_orm
now also has support for it.
auto storage = make_storage("myDatabase.sqlite",
make_table("induction",
make_column("timestamp", &Induction::time, default_value(datetime("now", "localtime")))));
means
CREATE TABLE induction (
timestamp INTEGER NOT NULL DEFAULT DATETIME('now', 'localtime')
)
⚙️ Query static validations
Once you try to create a query with more than one WHERE
options you get a static assert telling you "a single query cannot contain > 1 WHERE blocks". Same check works for:
- WHERE
- GROUP BY
- ORDER BY
- LIMIT
Before you'd know that you constructed incorrect query only in runtime. Now this check happens in compile time!
⚙️ storage_t::filename()
Use storage_t::filename()
function to retrieve filename passed in storage during construction.
Example:
const auto &filename = storage.filename(); // decltype(filename) is std::string
⚙️ Added code format with clang-format
All library code is formatted with clang-format
using config located in project root. From now when you create a pull request please don't forget to format it using clang-format
tool. If code is not formatted then your pull request will be declined cause one of CI check will be failed.
More information about clang-format
can be found here.
🐞 Fixed bug with incorrect PRIMARY KEY and AUTOINCREMENT order
Now one can write these two constraints in either order: the correct one and the legacy one.