Skip to content

v1.5

Compare
Choose a tag to compare
@fnc12 fnc12 released this 24 Jul 23:35
· 1965 commits to master since this release
b30ddc6
⭐ 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%"));

More info about GLOB

⭐ 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.

  • 🐞 fixed compilation errors with older versions of sqlite3

  • 🐞 #384

  • 🐞 #369

  • 🐞 #400