discord-bot/libs/sqlite_orm-1.8.2/examples/triggers.cpp

194 lines
9.5 KiB
C++

/**
* This example was grabbed from here https://www.sqlitetutorial.net/sqlite-trigger/
*/
#include <sqlite_orm/sqlite_orm.h>
#include <iostream>
#include <string>
using namespace sqlite_orm;
using std::cout;
using std::endl;
struct Lead {
int id = 0;
std::string firstName;
std::string lastName;
std::string email;
std::string phone;
#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED
Lead() = default;
Lead(int id, std::string firstName, std::string lastName, std::string email, std::string phone) :
id{id}, firstName{std::move(firstName)}, lastName{std::move(lastName)}, email{std::move(email)},
phone{std::move(phone)} {}
#endif
};
struct LeadLog {
int id = 0;
int oldId = 0;
int newId = 0;
std::string oldPhone;
std::string newPhone;
std::string oldEmail;
std::string newEmail;
std::string userAction;
std::string createdAt;
};
int main() {
auto storage = make_storage("",
// CREATE TRIGGER validate_email_before_insert_leads
// BEFORE INSERT ON leads
// BEGIN
// SELECT
// CASE
// WHEN NEW.email NOT LIKE '%_@__%.__%' THEN
// RAISE (ABORT,'Invalid email address')
// END;
// END;
make_trigger("validate_email_before_insert_leads",
before()
.insert()
.on<Lead>()
.begin(select(case_<int>()
.when(not like(new_(&Lead::email), "%_@__%.__%"),
then(raise_abort("Invalid email address")))
.end()))
.end()),
// CREATE TRIGGER log_contact_after_update
// AFTER UPDATE ON leads
// WHEN old.phone <> new.phone
// OR old.email <> new.email
// BEGIN
// INSERT INTO lead_logs (
// old_id,
// new_id,
// old_phone,
// new_phone,
// old_email,
// new_email,
// user_action,
// created_at
// )
// VALUES
// (
// old.id,
// new.id,
// old.phone,
// new.phone,
// old.email,
// new.email,
// 'UPDATE',
// DATETIME('NOW')
// ) ;
// END;
make_trigger("log_contact_after_update",
after()
.update()
.on<Lead>()
.when(is_not_equal(old(&Lead::phone), new_(&Lead::phone)) and
is_not_equal(old(&Lead::email), new_(&Lead::email)))
.begin(insert(into<LeadLog>(),
columns(&LeadLog::oldId,
&LeadLog::newId,
&LeadLog::oldPhone,
&LeadLog::newPhone,
&LeadLog::oldEmail,
&LeadLog::newEmail,
&LeadLog::userAction,
&LeadLog::createdAt),
values(std::make_tuple(old(&Lead::id),
new_(&Lead::id),
old(&Lead::phone),
new_(&Lead::phone),
old(&Lead::email),
new_(&Lead::email),
"UPDATE",
datetime("NOW")))))
.end()),
// CREATE TABLE leads (
// id integer PRIMARY KEY,
// first_name text NOT NULL,
// last_name text NOT NULL,
// email text NOT NULL,
// phone text NOT NULL
// );
make_table("leads",
make_column("id", &Lead::id, primary_key()),
make_column("first_name", &Lead::firstName),
make_column("last_name", &Lead::lastName),
make_column("email", &Lead::email),
make_column("phone", &Lead::phone)),
// CREATE TABLE lead_logs (
// id INTEGER PRIMARY KEY,
// old_id int,
// new_id int,
// old_phone text,
// new_phone text,
// old_email text,
// new_email text,
// user_action text,
// created_at text
// );
make_table("lead_logs",
make_column("id", &LeadLog::id, primary_key()),
make_column("old_id", &LeadLog::oldId),
make_column("new_id", &LeadLog::newId),
make_column("old_phone", &LeadLog::oldPhone),
make_column("new_phone", &LeadLog::newPhone),
make_column("old_email", &LeadLog::oldEmail),
make_column("new_email", &LeadLog::newEmail),
make_column("user_action", &LeadLog::userAction),
make_column("created_at", &LeadLog::createdAt)));
storage.sync_schema();
// Insert a row with an invalid email into the leads table:
//
// INSERT INTO leads (first_name, last_name, email, phone)
// VALUES('John', 'Doe', 'jjj', '4089009334');
try {
storage.insert(Lead{0, "John", "Doe", "jjj", "4089009334"});
} catch(const std::system_error& systemError) {
cout << "error: " << systemError.what() << endl;
}
// Insert a row with a valid email.
// INSERT INTO leads (first_name, last_name, email, phone)
// VALUES ('John', 'Doe', 'john.doe@sqlitetutorial.net', '4089009334');
storage.insert(Lead{0, "John", "Doe", "john.doe@sqlitetutorial.net", "4089009334"});
cout << "Leads:" << endl;
for(auto& lead: storage.iterate<Lead>()) {
cout << storage.dump(lead) << endl;
}
// UPDATE leads
// SET last_name = 'Smith'
// WHERE id = 1;
storage.update_all(set(c(&Lead::lastName) = "Smith"), where(c(&Lead::id) == 1));
cout << "Logs count = " << storage.count<LeadLog>() << endl;
// UPDATE leads
// SET
// phone = '4089998888',
// email = 'john.smith@sqlitetutorial.net'
// WHERE id = 1;
storage.update_all(set(c(&Lead::phone) = "4089998888", c(&Lead::email) = "john.smith@sqlitetutorial.net"),
where(c(&Lead::id) == 1));
cout << "Logs count = " << storage.count<LeadLog>() << endl;
for(auto& leadLog: storage.iterate<LeadLog>()) {
cout << storage.dump(leadLog) << endl;
}
return 0;
}