4#include "Stroika/Frameworks/StroikaPreComp.h"
12#include "Stroika/Foundation/Containers/Set.h"
20#include "ThreadTest.h"
27using namespace Stroika::Foundation::Database;
29using namespace Stroika::Foundation::Time;
31using namespace Database::SQL;
37 SQL::ORM::ProvisionForVersion (
38 conn, kCurrentVersion_,
39 initializer_list<SQL::ORM::TableProvisioner>{
44 c.Exec (
"CREATE TABLE EMPLOYEES("
45 "ID INTEGER PRIMARY KEY AUTOINCREMENT,"
58 c.Exec (
"CREATE TABLE PAYCHECKS("
59 "ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
60 "EMPLOYEEREF INT NOT NULL,"
72 "INSERT INTO EMPLOYEES (NAME,AGE,ADDRESS,SALARY,STILL_EMPLOYED) values (:NAME, :AGE, :ADDRESS, :SALARY, :STILL_EMPLOYED);"sv);
75 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
78 {
":ADDRESS", L
"California"},
79 {
":SALARY", 20000.00},
80 {
":STILL_EMPLOYED", 1},
82 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
85 {
":ADDRESS", L
"Texas"},
86 {
":SALARY", 15000.00},
87 {
":STILL_EMPLOYED", 1},
89 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
92 {
":ADDRESS",
"Norway"sv},
93 {
":SALARY", 20000.00},
94 {
":STILL_EMPLOYED", 1},
96 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
99 {
":ADDRESS",
"Rich-Mond"sv},
100 {
":SALARY", 65000.00},
101 {
":STILL_EMPLOYED", 1},
103 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
104 {
":NAME",
"David"sv},
106 {
":ADDRESS",
"Texas"sv},
107 {
":SALARY", 85000.00},
108 {
":STILL_EMPLOYED", 1},
110 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
113 {
":ADDRESS", L
"South-Hall"},
114 {
":SALARY", 45000.00},
115 {
":STILL_EMPLOYED", 1},
117 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
118 {
":NAME",
"James"sv},
120 {
":ADDRESS",
"Houston"sv},
121 {
":SALARY", 10000.00},
122 {
":STILL_EMPLOYED", 1},
125 default_random_engine generator;
126 uniform_int_distribution<int> distribution{1, 6};
128 Statement getAllActiveEmployees = conn.
mkStatement (
"Select ID,NAME from EMPLOYEES where STILL_EMPLOYED=1;"sv);
130 Statement fireEmployee = conn.
mkStatement (
"Update EMPLOYEES Set STILL_EMPLOYED=0 where ID=:ID;"sv);
135 static const Sequence<String> kNames_{
"Joe",
"Phred",
"Barny",
"Sue",
"Anne"};
136 uniform_int_distribution<int> namesDistr{0,
static_cast<int> (kNames_.size () - 1)};
137 uniform_int_distribution<int> ageDistr{25, 50};
138 static const Sequence<String> kAddresses{
"Houston",
"Pittsburg",
"New York",
"Paris",
"California"};
139 uniform_int_distribution<int> addressesDistr{0,
static_cast<int> (kAddresses.size () - 1)};
140 uniform_real_distribution<float> salaryDistr{10000.00, 50000.00};
143 uniform_int_distribution<int> whatTodoDistr{0, 3};
144 switch (whatTodoDistr (generator)) {
147 String name = kNames_[namesDistr (generator)];
148 cout <<
"Adding employee {}"_f(name) << endl;
149 addEmployeeStatement.
Execute (initializer_list<Statement::ParameterDescription>{
151 {
":AGE"sv, ageDistr (generator)},
152 {
":ADDRESS"sv, kAddresses[addressesDistr (generator)]},
153 {
":SALARY"sv, salaryDistr (generator)},
154 {
":STILL_EMPLOYED"sv, 1},
160 if (not activeEmps.
empty ()) {
161 uniform_int_distribution<int> empDistr{0,
static_cast<int> (activeEmps.
size () - 1)};
162 tuple<VariantValue, VariantValue> killMe = activeEmps[empDistr (generator)];
163 cout <<
"Firing employee: {}, {}"_f(get<0> (killMe).As<int> (), get<1> (killMe).As<String> ()) << endl;
164 fireEmployee.
Execute (initializer_list<Statement::ParameterDescription>{{L
":ID", get<0> (killMe).As<
int> ()}});
171 cout <<
"Exception processing SQL - this should generally not happen: {}"_f(current_exception ()) << endl;
180 Statement addPaycheckStatement = conn.
mkStatement (
"INSERT INTO PAYCHECKS (EMPLOYEEREF,AMOUNT,DATE) values (:EMPLOYEEREF, :AMOUNT, :DATE);"sv);
181 Statement getAllActiveEmployees = conn.
mkStatement (
"Select ID,NAME,SALARY from EMPLOYEES where STILL_EMPLOYED=1;"sv);
185 for (
const auto& employee : getAllActiveEmployees.GetAllRows (0, 1, 2)) {
186 int id = get<0> (employee).As<
int> ();
188 double salary = get<2> (employee).
As<
double> ();
189 cout <<
"Writing paycheck for employee #{} ({}) amount {}"_f(
id, name, salary) << endl;
190 addPaycheckStatement.
Execute (initializer_list<Statement::ParameterDescription>{
191 {
":EMPLOYEEREF"sv,
id},
192 {
":AMOUNT"sv, salary / 12},
193 {
":DATE"sv, DateTime::Now ().Format (DateTime::kISO8601Format)},
199 cout <<
"Exception processing SQL - this should generally not happen: {}"_f(current_exception ()) << endl;
206void Stroika::Samples::SQL::ThreadTest (
const function<
Connection::Ptr ()>& connectionFactory)
216 Thread::New ([=] () { PeriodicallyUpdateEmployeesTable_ (conn1); }, Thread::eAutoStart,
"Update Employee Table"sv)};
218 Thread::New ([=] () { PeriodicallyWriteChecksForEmployeesTable_ (conn2); }, Thread::eAutoStart,
"Write Checks"sv)};
String is like std::u32string, except it is much easier to use, often much more space efficient,...
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual Statement mkStatement(const String &sql)
nonvirtual void Execute()
nonvirtual Sequence< Row > GetAllRows()
call Reset (), and then GetAllRemainingRows () - which always starts current statement with current b...
nonvirtual WaitStatus WaitQuietly(Time::DurationSeconds timeout=Time::kInfinity)
nonvirtual size_t size() const
Returns the number of items contained.
nonvirtual bool empty() const
Returns true iff size() == 0.
Ptr New(const function< void()> &fun2CallOnce, const optional< Characters::String > &name, const optional< Configuration > &configuration)
void Sleep(Time::Duration seconds2Wait)