You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
9.5 KiB

2 years ago
  1. /**
  2. * This example was grabbed from here https://www.sqlitetutorial.net/sqlite-trigger/
  3. */
  4. #include <sqlite_orm/sqlite_orm.h>
  5. #include <iostream>
  6. #include <string>
  7. using namespace sqlite_orm;
  8. using std::cout;
  9. using std::endl;
  10. struct Lead {
  11. int id = 0;
  12. std::string firstName;
  13. std::string lastName;
  14. std::string email;
  15. std::string phone;
  16. #ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED
  17. Lead() = default;
  18. Lead(int id, std::string firstName, std::string lastName, std::string email, std::string phone) :
  19. id{id}, firstName{std::move(firstName)}, lastName{std::move(lastName)}, email{std::move(email)},
  20. phone{std::move(phone)} {}
  21. #endif
  22. };
  23. struct LeadLog {
  24. int id = 0;
  25. int oldId = 0;
  26. int newId = 0;
  27. std::string oldPhone;
  28. std::string newPhone;
  29. std::string oldEmail;
  30. std::string newEmail;
  31. std::string userAction;
  32. std::string createdAt;
  33. };
  34. int main() {
  35. auto storage = make_storage("",
  36. // CREATE TRIGGER validate_email_before_insert_leads
  37. // BEFORE INSERT ON leads
  38. // BEGIN
  39. // SELECT
  40. // CASE
  41. // WHEN NEW.email NOT LIKE '%_@__%.__%' THEN
  42. // RAISE (ABORT,'Invalid email address')
  43. // END;
  44. // END;
  45. make_trigger("validate_email_before_insert_leads",
  46. before()
  47. .insert()
  48. .on<Lead>()
  49. .begin(select(case_<int>()
  50. .when(not like(new_(&Lead::email), "%_@__%.__%"),
  51. then(raise_abort("Invalid email address")))
  52. .end()))
  53. .end()),
  54. // CREATE TRIGGER log_contact_after_update
  55. // AFTER UPDATE ON leads
  56. // WHEN old.phone <> new.phone
  57. // OR old.email <> new.email
  58. // BEGIN
  59. // INSERT INTO lead_logs (
  60. // old_id,
  61. // new_id,
  62. // old_phone,
  63. // new_phone,
  64. // old_email,
  65. // new_email,
  66. // user_action,
  67. // created_at
  68. // )
  69. // VALUES
  70. // (
  71. // old.id,
  72. // new.id,
  73. // old.phone,
  74. // new.phone,
  75. // old.email,
  76. // new.email,
  77. // 'UPDATE',
  78. // DATETIME('NOW')
  79. // ) ;
  80. // END;
  81. make_trigger("log_contact_after_update",
  82. after()
  83. .update()
  84. .on<Lead>()
  85. .when(is_not_equal(old(&Lead::phone), new_(&Lead::phone)) and
  86. is_not_equal(old(&Lead::email), new_(&Lead::email)))
  87. .begin(insert(into<LeadLog>(),
  88. columns(&LeadLog::oldId,
  89. &LeadLog::newId,
  90. &LeadLog::oldPhone,
  91. &LeadLog::newPhone,
  92. &LeadLog::oldEmail,
  93. &LeadLog::newEmail,
  94. &LeadLog::userAction,
  95. &LeadLog::createdAt),
  96. values(std::make_tuple(old(&Lead::id),
  97. new_(&Lead::id),
  98. old(&Lead::phone),
  99. new_(&Lead::phone),
  100. old(&Lead::email),
  101. new_(&Lead::email),
  102. "UPDATE",
  103. datetime("NOW")))))
  104. .end()),
  105. // CREATE TABLE leads (
  106. // id integer PRIMARY KEY,
  107. // first_name text NOT NULL,
  108. // last_name text NOT NULL,
  109. // email text NOT NULL,
  110. // phone text NOT NULL
  111. // );
  112. make_table("leads",
  113. make_column("id", &Lead::id, primary_key()),
  114. make_column("first_name", &Lead::firstName),
  115. make_column("last_name", &Lead::lastName),
  116. make_column("email", &Lead::email),
  117. make_column("phone", &Lead::phone)),
  118. // CREATE TABLE lead_logs (
  119. // id INTEGER PRIMARY KEY,
  120. // old_id int,
  121. // new_id int,
  122. // old_phone text,
  123. // new_phone text,
  124. // old_email text,
  125. // new_email text,
  126. // user_action text,
  127. // created_at text
  128. // );
  129. make_table("lead_logs",
  130. make_column("id", &LeadLog::id, primary_key()),
  131. make_column("old_id", &LeadLog::oldId),
  132. make_column("new_id", &LeadLog::newId),
  133. make_column("old_phone", &LeadLog::oldPhone),
  134. make_column("new_phone", &LeadLog::newPhone),
  135. make_column("old_email", &LeadLog::oldEmail),
  136. make_column("new_email", &LeadLog::newEmail),
  137. make_column("user_action", &LeadLog::userAction),
  138. make_column("created_at", &LeadLog::createdAt)));
  139. storage.sync_schema();
  140. // Insert a row with an invalid email into the leads table:
  141. //
  142. // INSERT INTO leads (first_name, last_name, email, phone)
  143. // VALUES('John', 'Doe', 'jjj', '4089009334');
  144. try {
  145. storage.insert(Lead{0, "John", "Doe", "jjj", "4089009334"});
  146. } catch(const std::system_error& systemError) {
  147. cout << "error: " << systemError.what() << endl;
  148. }
  149. // Insert a row with a valid email.
  150. // INSERT INTO leads (first_name, last_name, email, phone)
  151. // VALUES ('John', 'Doe', 'john.doe@sqlitetutorial.net', '4089009334');
  152. storage.insert(Lead{0, "John", "Doe", "john.doe@sqlitetutorial.net", "4089009334"});
  153. cout << "Leads:" << endl;
  154. for(auto& lead: storage.iterate<Lead>()) {
  155. cout << storage.dump(lead) << endl;
  156. }
  157. // UPDATE leads
  158. // SET last_name = 'Smith'
  159. // WHERE id = 1;
  160. storage.update_all(set(c(&Lead::lastName) = "Smith"), where(c(&Lead::id) == 1));
  161. cout << "Logs count = " << storage.count<LeadLog>() << endl;
  162. // UPDATE leads
  163. // SET
  164. // phone = '4089998888',
  165. // email = 'john.smith@sqlitetutorial.net'
  166. // WHERE id = 1;
  167. storage.update_all(set(c(&Lead::phone) = "4089998888", c(&Lead::email) = "john.smith@sqlitetutorial.net"),
  168. where(c(&Lead::id) == 1));
  169. cout << "Logs count = " << storage.count<LeadLog>() << endl;
  170. for(auto& leadLog: storage.iterate<LeadLog>()) {
  171. cout << storage.dump(leadLog) << endl;
  172. }
  173. return 0;
  174. }