Skip to content

v1.6

Compare
Choose a tag to compare
@fnc12 fnc12 released this 08 Oct 18:17
· 1762 commits to master since this release
4c6a46b
⭐ Added `CHECK` constraint
auto storage = make_storage("database.sqlite",
                            make_table("contacts",
                                       make_column("contact_id", &Contact::id, primary_key()),
                                       make_column("phone", &Contact::phone),
                                       check(length(&Contact::phone) >= 10)));

means

CREATE TABLE contacts (
    contact_id INTEGER NOT NULL PRIMARY KEY,
    phone TEXT NOT NULL,
    CHECK(LENGTH(phone >= 10))
)

or

auto storage = make_storage("database.sqlite",
                            make_table("BOOK",
                                       make_column("Book_id", &Book::id, primary_key()),
                                       make_column("Book_name", &Book::name),
                                       make_column("Pub_name", &Book::pubName),
                                       make_column("PRICE", &Book::price, check(c(&Book::price) > 0))));

means

CREATE TABLE BOOK(
    Book_id INTEGER NOT NULL PRIMARY KEY,
    Book_name TEXT NOT NULL,
    Pub_name TEXT NOT NULL,
    PRICE NUMERIC NOT NULL CHECK(PRICE > 0)
)
⭐ Added bitwise operators support
storage.select(bitwise_or(60, 13));  // SELECT 60 | 13
storage.select(bitwise_and(60, 13));  // SELECT 60 & 13
storage.select(bitwise_shift_left(60, 2));  // SELECT 60 << 2
storage.select(bitwise_shift_right(60, 2));  // SELECT 60 >> 2
storage.select(bitwise_not(60));  // SELECT ~60
⭐ Added `indexed_column` function to specify order (`ASC`, `DESC`) and collation for indexed columns
auto storage = make_storage({}, 
                            make_index("name_index", indexed_column(&User::name).collate("binary").asc()), 
                            make_table("users", 
                                       make_column("id", &User::id), 
                                       make_column("name", &User::name));

will translate to

CREATE TABLE users (
    id INTEGER NOT NULL,
    name TEXT NOT NULL);
CREATE INDEX name_index ON users (name COLLATE binary ASC);
⭐ New core functions
  • HEX
  • QUOTE
  • RANDOMBLOB
  • INSTR
  • REPLACE
  • ROUND
  • SOUNDEX
⭐ New date & time functions - all date & time functions are supported from now!
  • TIME
  • STRFTIME
⭐ Added `storage.dump` function for prepared statements
auto statement = storage.prepare(select(&User::id, where(length(&User::name) > 5 and like(&User::name, "T%"))));
auto str = storage.dump(statement);  // str is something like 'SELECT \"users\".\"name\", \"users\".\"id\" FROM 'users'  WHERE ( ((\"id\" % 2) = 0)) ORDER BY \"users\".\"name\" '

The difference between statement.sql is that dump function prints real values instead of question marks. Also it does not call any sqlite3 functions - it calls sqlite_orm serializer instead.

⭐ Added custom container support for `get_all` prepared statement

Example:

auto statement = storage.prepare(get_all<User, std::list<User>>());
⭐ `UNIQUE` constraint supports more than one column
Example:
make_table("shapes",
           make_column("shape_id", &Shape::id, primary_key()),
           make_column("background_color", &Shape::backgroundColor),
           make_column("foreground_color", &Shape::foregroundColor),
           sqlite_orm::unique(&Shape::backgroundColor, &Shape::foregroundColor))
⭐ New table operating API

Example:

* storage.rename_table<User>("new_table_name") -> change name in table information not database
* storage.rename_table("old_name", "new_name");  -> rename table using SQL query
* storage.tablename<User>(); -> get table name as `std::string` from table info not database
⭐ Added `VALUES` API

Example:

//    DELETE FROM devices
//    WHERE (serial_number, device_id) IN (VALUES ('abc', '123'), ('def', '456'))
storage.remove_all<Device>(where(in(std::make_tuple(&Device::serialNumber, &Device::deviceId),
                                         values(std::make_tuple("abc", "123"), std::make_tuple("def", "456")))));
//  or
storage.remove_all<Device>(
         where(in(std::make_tuple(&Device::serialNumber, &Device::deviceId),
                  values(std::vector<std::tuple<std::string, std::string>>{std::make_tuple("abc", "123"),
                                                                           std::make_tuple("def", "456")}))));

These queries are the same. The difference between them is that the first is static and the second is dynamic (std::vector based). It may be useful if you change bound values using get API.

  • ⚙️ sync_schema behavior changes: now types are ignored cause SQLite ignores them too. It allows using custom types.
  • ⚙️ Fixed all clang and GCC warnings.
  • 🐞 Fixed bug: unable to use reserved keywords as foreign key columns
  • 🐞 Fixed bug: compilation error during using any core function within CASE operator
  • 🐞 Fixed bug in sync_schema: #521
  • 🐞 Fixed backup bug: #540

Special thanks to:
@undisputed-seraphim
@Leon0402
@air-h-128k-il