SlideShare a Scribd company logo
1 of 48
Download to read offline
SQLite + C++14
Докладчик: Евгений Захаров
1
database db(«dbfile.db»);
db << "insert into user (age,name,weight) values (?,?,?);"
<< 20
<< u"bob"
<< 83.25;
Какие уже есть ORM для SQLite на C++?
2
https://github.com/SqliteModernCpp/sqlite_modern_cpp
SqliteModernCpp/sqlite_modern_cpp
Какие уже есть ORM для SQLite на C++?
SQLite::Statement query(db, "SELECT id as test_id, value as test_val, weight as
test_weight FROM test WHERE weight > ?»);
query.bind(1, 2);
while (query.executeStep()) {
const int id = query.getColumn(0);
const std::string value = query.getColumn(1);
const int bytes = query.getColumn(1).size();
const double weight = query.getColumn(2);
}
3
https://github.com/SRombauts/SQLiteCpp
SRombauts/SQLiteCpp
Какие уже есть ORM для SQLite на C++?
db <<
"create table if not exists user ("
" _id integer primary key autoincrement not null,"
" age int,"
" name text,"
" weight real"
");";
4
https://github.com/SqliteModernCpp/sqlite_modern_cpp
SqliteModernCpp/sqlite_modern_cpp
Какие уже есть ORM для SQLite на C++?
class Person{
friend class hiberlite::access;
template<class Archive>
void hibernate(Archive & ar)
{
ar & HIBERLITE_NVP(name);
ar & HIBERLITE_NVP(age);
ar & HIBERLITE_NVP(bio);
}
public:
string name;
double age;
vector<string> bio;
};
HIBERLITE_EXPORT_CLASS(Person)
5
https://github.com/paulftw/hiberlite
paulftw/hiberlite
6
Какие уже есть ORM для SQLite на C++?

TabFoo foo;
Db db(/* some arguments*/);
for (const auto& row : db(select(all_of(foo)).from(foo).where(foo.hasFun or foo.name == "joker")))
{
int64_t id = row.id;
}
https://github.com/rbock/sqlpp11
rbock/sqlpp11
Что хочется иметь при работе с ORM?
7
1) не тратить кучу времени на создание БД (в коде либо во внешних
редакторах)
2) иметь встроенный язык (DSL) c отсутствием кодогенерации, макросов и прочей
«черной магии»
8
Что хочется иметь при работе с ORM?
3) single responsibility principle - классы модели не должны иметь
ORM в качестве зависимости
9
Что хочется иметь при работе с ORM?
struct User {
int id = 0;
std::string name;
int tag = 0;
};
auto storage = make_storage("db.sqlite",
make_table("users",
make_column("identifier", &User::id, primary_key()),
make_column("name", &User::name),
make_column("tag", &User::tag)));
storage.sync_schema();
storage.sync_schema(true);
10
Описание схемы
S
11
CREATE TABLE IF NOT EXISTS 'users' (
‘identifier' INTEGER PRIMARY KEY NOT NULL ,
'name' TEXT NOT NULL ,
'tag' INTEGER NOT NULL );
Описание схемы

storage.insert(Artist{3, "Ted Mosby"});
storage.replace(Track{14, "Lily Aldrin", 3});
auto track = storage.get<Track>(14); // decltype(track) is
Track
cout << storage.dump(track) << endl; // { trackid : '14',
trackname : 'Mr. Bojangles', trackartist : '3' }
track.trackName = "Robin Scherbatsky";
storage.update(track); // UPDATE track SET …
storage.remove<Track>(14); // DELETE FROM track WHERE id = 14
auto allTracks = storage.get_all<Track>(); // decltype(allTracks)
is vector<Track>
12
Банальный CRUD
I
13
Банальный CRUD

14
auto users = storage.get_all<User>(where(lesser_than(&User::id, 5)));
// decltype(users) is vector<User>
Условия
S
15
Условия
SELECT id, first_name, last_name
FROM users
WHERE id < 5
+
16
template<class L, class R>
conditions::lesser_than_t<L, R> lesser_than(L l, R r) {
return {std::move(l), std::move(r)};
}
template<class L, class R>
struct lesser_than_t : binary_condition<L, R>, lesser_than_string {
using self = lesser_than_t<L, R>;
using binary_condition<L, R>::binary_condition;
negated_condition_t<self> operator!() const {
return {*this};
}
};
Условия
17
template<class L, class R>
struct binary_condition : public condition_t {
using left_type = L;
using right_type = R;
left_type l;
right_type r;
binary_condition() = default;
binary_condition(left_type l_, right_type r_) : l(std::move(l_)), r(std::move(r_)) {}
};
Условия
18
auto users = storage.get_all<User>(where(lt(&User::id, 5)));
// decltype(users) is vector<User>
auto users = storage.get_all<User>(where(c(&User::id) < 5));
Условия
19
template<class T>
internal::expression_t<T> c(T t) {
return {std::move(t)};
}
template<class T, class R>
conditions::lesser_than_t<T, R> operator<(internal::expression_t<T> expr, R r) {
return {std::move(expr.t), std::move(r)};
}
template<class L, class T>
conditions::lesser_than_t<L, T> operator<(L l, internal::expression_t<T> expr) {
return {std::move(l), std::move(expr.t)};
}
Условия
20
template<class T>
struct expression_t {
T t;
expression_t(T t_) : t(std::move(t_)) {}
template<class R>
assign_t<T, R> operator=(R r) const {
return {this->t, std::move(r)};
}
assign_t<T, std::nullptr_t> operator=(std::nullptr_t) const {
return {this->t, nullptr};
}
};
Условия
+
21
auto users = storage.get_all<User>(where(c(&User::id) < 5 and
c(&User::firstName) == «Barney»));
Условия
S
22
Условия
SELECT id, first_name, last_name
FROM users
WHERE id < 5 AND first_name = ‘Barney’
23
template<class L,
class R,
typename = typename
std::enable_if<std::is_base_of<conditions::condition_t, L>::value ||
std::is_base_of<conditions::condition_t, R>::value>::type>
and_condition_t<L, R> operator&&(L l, R r)
{
return {std::move(l), std::move(r)};
}
Условия

24
auto users = storage.get_all<User>(where(not like(&User::firstName,
"J%") and (between(&User::id, 10, 20) or glob(&User::lastName,
"*b*"))));
Core functions & operators
S
25
Core functions & operators
SELECT id, first_name, last_name
FROM users
WHERE NOT (first_name LIKE ‘J%’) AND (id BETWEEN 10 AND 20 OR
last_name GLOB ‘*b*’)
+
26
struct between_string {
operator std::string() const {
return "BETWEEN";
}
};
template<class A, class T>
struct between_t : condition_t, between_string {
using expression_type = A;
using lower_type = T;
using upper_type = T;
expression_type expr;
lower_type b1;
upper_type b2;
between_t(expression_type expr_, lower_type b1_, upper_type b2_) :
expr(std::move(expr_)), b1(std::move(b1_)), b2(std::move(b2_)) {}
};
template<class A, class T>
between_t<A, T> between(A expr, T b1, T b2) {
return {std::move(expr), std::move(b1), std::move(b2)};
}
Core functions & operators

27
auto allIds = storage.select(&User::id);
// decltype(allIds) is vector<decltype(User::id)> AKA
vector<int>
Raw select
S
28
Raw select
SELECT id
FROM users
+
29
auto rows = storage.select(columns(&User::firstName, &User::lastName),
where(c(&User::id) > 250),
order_by(&User::id));
// decltype(partialSelect) is vector<tuple<string, string>>
Raw select
S
30
Raw select
SELECT first_name, last_name
FROM users
WHERE id > 250
ORDER BY id
+
31
auto rows = storage.select(columns(&Doctor::id, &Doctor::name,
&Visit::patientName, &Visit::vdate),
left_join<Visit>(on(c(&Doctor::id) ==
&Visit::doctorId)));
Raw select
S
32
Raw select
SELECT doctors.doctor_id, doctors.doctor_name,
visits.patient_name, visits.vdate
FROM doctors
LEFT JOIN visits
ON doctors.doctor_id = visits.doctor_id;
+
33
Raw select
template<class... Args>
internal::columns_t<Args...> columns(Args... args) {
return {std::make_tuple<Args...>(std::forward<Args>(args)...)};
}
template<class... Args>
struct columns_t {
using columns_type = std::tuple<Args...>;
columns_type columns;
bool distinct = false;
static constexpr const size_t count = std::tuple_size<columns_type>::value;
};
34
Raw select
template<class T,
class... Args,
class R = typename column_result_t<self, T>::type>
std::vector<R> select(T m, Args... args)
{
static_assert(!is_base_of_template<T, compound_operator>::value ||
std::tuple_size<std::tuple<Args...>>::value == 0,
"Cannot use args with a compound operator");
auto statement = this->prepare(sqlite_orm::select(std::move(m),
std::forward<Args>(args)...));
return this->execute(statement);
}
35
Raw select
template<class St, class T, class SFINAE = void>
struct column_result_t;
template<class St, class O, class F>
struct column_result_t<St,
F O::*,
typename std::enable_if<std::is_member_pointer<F O::*>::value
&&!std::is_member_function_pointer<F O::*>::value>::type>
{
using type = F;
};
template<class St, class... Args>
struct column_result_t<St, columns_t<Args...>, void>
{
using type = std::tuple<typename column_result_t<St, typename
std::decay<Args>::type>::type...>;
};
+
36
auto rows = storage.select(
union_all(select(columns(&Department::employeeId,
&Employee::name,
&Department::dept),
inner_join<Department>(on(c(&Employee::id) == &Department::employeeId))),
select(columns(&Department::employeeId,
&Employee::name,
&Department::dept),
left_outer_join<Department>(on(c(&Employee::id) == &Department::employeeId)))));
Raw select
S
37
SELECT emp_id, name, dept
FROM company
INNER JOIN department
ON company.id = department.emp_id
UNION ALL
SELECT emp_id, name, dept
FROM company
LEFT OUTER JOIN department
ON company.id = department.emp_id
Raw select
I
38
Raw select

39
auto statement = storage.prepare(select(columns(5.0,
&User::id,
count(&User::name)),
where(c(&User::id) < 10)));
auto rows = storage.execute(statement);
Prepared statements
S
40
Prepared statements
SELECT 5.0, id, COUNT(name)
FROM users
WHERE id < 10
+
41
get<0>(statement) = 4;
get<1>(statement) = 2;
Prepared statements
S
42
Prepared statements
SELECT 4.0, id, COUNT(name)
FROM users
WHERE id < 2
I
43
Prepared statements
44
template<class T, class... Args>
struct select_t {
using return_type = T;
using conditions_type = std::tuple<Args...>;
return_type col;
conditions_type conditions;
bool highest_level = false;
};
template<class T, class... Args>
select_t<T, Args...> select(T t, Args... args) {
return {std::move(t), std::make_tuple<Args...>(std::forward<Args>(args)...)};
}
Prepared statements
45
template<int N, class T>
auto &get(prepared_statement_t<T> &statement) {
using statement_type = typename std::decay<decltype(statement)>::type;
using expression_type = typename statement_type::expression_type;
using node_tuple = typename node_tuple<expression_type>::type;
using bind_tuple = typename bindable_filter<node_tuple>::type;
using result_tupe = typename std::tuple_element<N, bind_tuple>::type;
result_tupe *result = nullptr;
auto index = -1;
iterate_ast(statement.t, [&result, &index](auto &node) {
using node_type = typename std::decay<decltype(node)>::type;
if(is_bindable<node_type>::value) {
++index;
}
if(index == N) {
static_if<std::is_same<result_tupe, node_type>{}>([](auto &result, auto &node) {
result = const_cast<typename std::remove_reference<decltype(result)>::type>(&node);
})(result, node);
}
});
return get_ref(*result);
}
Prepared statements
46
template<class T, class L>
void iterate_ast(const T &t, const L &l) {
ast_iterator<T> iterator;
iterator(t, l);
}
template<class T, class SFINAE = void>
struct ast_iterator {
using node_type = T;
template<class L>
void operator()(const T &t, const L &l) const {
l(t);
}
};
template<class T>
struct ast_iterator<
T,
typename std::enable_if<is_base_of_template<T,
conditions::binary_condition>::value>::type> {
using node_type = T;
template<class L>
void operator()(const node_type &binaryCondition, const L &l) const {
iterate_ast(binaryCondition.l, l);
iterate_ast(binaryCondition.r, l);
}
};
AST iteration

47
Ложка дегтя
48
Полезные ссылки
https://github.com/fnc12/sqlite_orm
fnc12/sqlite_orm
Другие библиотеки
https://github.com/iwongu/sqlite3pp
https://github.com/SqliteModernCpp/sqlite_modern_cpp
https://github.com/SRombauts/SQLiteCpp
https://github.com/paulftw/hiberlite
https://github.com/rbock/sqlpp11
https://github.com/qicosmos/ormpp
https://www.codesynthesis.com/products/odb/

More Related Content

What's hot

Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objectsHusain Dalal
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkKaniska Mandal
 
10. session 10 loops and arrays
10. session 10   loops and arrays10. session 10   loops and arrays
10. session 10 loops and arraysPhúc Đỗ
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFabio Collini
 
openFrameworks 007 - utils
openFrameworks 007 - utilsopenFrameworks 007 - utils
openFrameworks 007 - utilsroxlu
 
Js 单元测试框架介绍
Js 单元测试框架介绍Js 单元测试框架介绍
Js 单元测试框架介绍louieuser
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)cruisercoder
 
Collection v3
Collection v3Collection v3
Collection v3Sunil OS
 
Spring data access
Spring data accessSpring data access
Spring data access명철 강
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFabio Collini
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorFedor Lavrentyev
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicNew Relic
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 

What's hot (20)

Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD Framework
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
10. session 10 loops and arrays
10. session 10   loops and arrays10. session 10   loops and arrays
10. session 10 loops and arrays
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
openFrameworks 007 - utils
openFrameworks 007 - utilsopenFrameworks 007 - utils
openFrameworks 007 - utils
 
Java Cheat Sheet
Java Cheat SheetJava Cheat Sheet
Java Cheat Sheet
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
Specs2
Specs2Specs2
Specs2
 
Js 单元测试框架介绍
Js 单元测试框架介绍Js 单元测试框架介绍
Js 单元测试框架介绍
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)
 
Python speleology
Python speleologyPython speleology
Python speleology
 
Collection v3
Collection v3Collection v3
Collection v3
 
Spring data access
Spring data accessSpring data access
Spring data access
 
Academy PRO: ES2015
Academy PRO: ES2015Academy PRO: ES2015
Academy PRO: ES2015
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 

Similar to Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019

Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0Yaser Zhian
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methodsphil_nash
 
Implement the Queue ADT using array – based approach. Using C++ prog.pdf
Implement the Queue ADT using array – based approach. Using C++ prog.pdfImplement the Queue ADT using array – based approach. Using C++ prog.pdf
Implement the Queue ADT using array – based approach. Using C++ prog.pdfsktambifortune
 
Basic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersBasic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersJen Yee Hong
 
DEFCON 23 - Miaubiz - put on your tinfo_t hat
DEFCON 23 - Miaubiz - put on your tinfo_t hatDEFCON 23 - Miaubiz - put on your tinfo_t hat
DEFCON 23 - Miaubiz - put on your tinfo_t hatFelipe Prado
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings imtiazalijoono
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Platonov Sergey
 
Postgresql 9.3 overview
Postgresql 9.3 overviewPostgresql 9.3 overview
Postgresql 9.3 overviewAveic
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
String in .net
String in .netString in .net
String in .netLarry Nung
 
Structured data type
Structured data typeStructured data type
Structured data typeOmkar Majukar
 
Templates in C++
Templates in C++Templates in C++
Templates in C++Tech_MX
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»e-Legion
 

Similar to Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019 (20)

greenDAO
greenDAOgreenDAO
greenDAO
 
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
 
Learning Dtrace
Learning DtraceLearning Dtrace
Learning Dtrace
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Implement the Queue ADT using array – based approach. Using C++ prog.pdf
Implement the Queue ADT using array – based approach. Using C++ prog.pdfImplement the Queue ADT using array – based approach. Using C++ prog.pdf
Implement the Queue ADT using array – based approach. Using C++ prog.pdf
 
Basic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersBasic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmers
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
DEFCON 23 - Miaubiz - put on your tinfo_t hat
DEFCON 23 - Miaubiz - put on your tinfo_t hatDEFCON 23 - Miaubiz - put on your tinfo_t hat
DEFCON 23 - Miaubiz - put on your tinfo_t hat
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings
 
Chapter 2
Chapter 2Chapter 2
Chapter 2
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Postgresql 9.3 overview
Postgresql 9.3 overviewPostgresql 9.3 overview
Postgresql 9.3 overview
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
String in .net
String in .netString in .net
String in .net
 
Structured data type
Structured data typeStructured data type
Structured data type
 
Lab 13
Lab 13Lab 13
Lab 13
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

Recently uploaded

How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxmprakaash5
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Arti Languages Pre Seed Pitchdeck 2024.pdf
Arti Languages Pre Seed Pitchdeck 2024.pdfArti Languages Pre Seed Pitchdeck 2024.pdf
Arti Languages Pre Seed Pitchdeck 2024.pdfwill854175
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdf
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdfHCI Lesson 1 - Introduction to Human-Computer Interaction.pdf
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdfROWELL MARQUINA
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneUiPathCommunity
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
A PowerPoint Presentation on Vikram Lander pptx
A PowerPoint Presentation on Vikram Lander pptxA PowerPoint Presentation on Vikram Lander pptx
A PowerPoint Presentation on Vikram Lander pptxatharvdev2010
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?Rustici Software
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 

Recently uploaded (20)

How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Arti Languages Pre Seed Pitchdeck 2024.pdf
Arti Languages Pre Seed Pitchdeck 2024.pdfArti Languages Pre Seed Pitchdeck 2024.pdf
Arti Languages Pre Seed Pitchdeck 2024.pdf
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdf
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdfHCI Lesson 1 - Introduction to Human-Computer Interaction.pdf
HCI Lesson 1 - Introduction to Human-Computer Interaction.pdf
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
WomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyoneWomenInAutomation2024: AI and Automation for eveyone
WomenInAutomation2024: AI and Automation for eveyone
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
A PowerPoint Presentation on Vikram Lander pptx
A PowerPoint Presentation on Vikram Lander pptxA PowerPoint Presentation on Vikram Lander pptx
A PowerPoint Presentation on Vikram Lander pptx
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 

Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019

  • 1. SQLite + C++14 Докладчик: Евгений Захаров 1
  • 2. database db(«dbfile.db»); db << "insert into user (age,name,weight) values (?,?,?);" << 20 << u"bob" << 83.25; Какие уже есть ORM для SQLite на C++? 2 https://github.com/SqliteModernCpp/sqlite_modern_cpp SqliteModernCpp/sqlite_modern_cpp
  • 3. Какие уже есть ORM для SQLite на C++? SQLite::Statement query(db, "SELECT id as test_id, value as test_val, weight as test_weight FROM test WHERE weight > ?»); query.bind(1, 2); while (query.executeStep()) { const int id = query.getColumn(0); const std::string value = query.getColumn(1); const int bytes = query.getColumn(1).size(); const double weight = query.getColumn(2); } 3 https://github.com/SRombauts/SQLiteCpp SRombauts/SQLiteCpp
  • 4. Какие уже есть ORM для SQLite на C++? db << "create table if not exists user (" " _id integer primary key autoincrement not null," " age int," " name text," " weight real" ");"; 4 https://github.com/SqliteModernCpp/sqlite_modern_cpp SqliteModernCpp/sqlite_modern_cpp
  • 5. Какие уже есть ORM для SQLite на C++? class Person{ friend class hiberlite::access; template<class Archive> void hibernate(Archive & ar) { ar & HIBERLITE_NVP(name); ar & HIBERLITE_NVP(age); ar & HIBERLITE_NVP(bio); } public: string name; double age; vector<string> bio; }; HIBERLITE_EXPORT_CLASS(Person) 5 https://github.com/paulftw/hiberlite paulftw/hiberlite
  • 6. 6 Какие уже есть ORM для SQLite на C++?  TabFoo foo; Db db(/* some arguments*/); for (const auto& row : db(select(all_of(foo)).from(foo).where(foo.hasFun or foo.name == "joker"))) { int64_t id = row.id; } https://github.com/rbock/sqlpp11 rbock/sqlpp11
  • 7. Что хочется иметь при работе с ORM? 7 1) не тратить кучу времени на создание БД (в коде либо во внешних редакторах)
  • 8. 2) иметь встроенный язык (DSL) c отсутствием кодогенерации, макросов и прочей «черной магии» 8 Что хочется иметь при работе с ORM?
  • 9. 3) single responsibility principle - классы модели не должны иметь ORM в качестве зависимости 9 Что хочется иметь при работе с ORM?
  • 10. struct User { int id = 0; std::string name; int tag = 0; }; auto storage = make_storage("db.sqlite", make_table("users", make_column("identifier", &User::id, primary_key()), make_column("name", &User::name), make_column("tag", &User::tag))); storage.sync_schema(); storage.sync_schema(true); 10 Описание схемы S
  • 11. 11 CREATE TABLE IF NOT EXISTS 'users' ( ‘identifier' INTEGER PRIMARY KEY NOT NULL , 'name' TEXT NOT NULL , 'tag' INTEGER NOT NULL ); Описание схемы 
  • 12. storage.insert(Artist{3, "Ted Mosby"}); storage.replace(Track{14, "Lily Aldrin", 3}); auto track = storage.get<Track>(14); // decltype(track) is Track cout << storage.dump(track) << endl; // { trackid : '14', trackname : 'Mr. Bojangles', trackartist : '3' } track.trackName = "Robin Scherbatsky"; storage.update(track); // UPDATE track SET … storage.remove<Track>(14); // DELETE FROM track WHERE id = 14 auto allTracks = storage.get_all<Track>(); // decltype(allTracks) is vector<Track> 12 Банальный CRUD I
  • 14. 14 auto users = storage.get_all<User>(where(lesser_than(&User::id, 5))); // decltype(users) is vector<User> Условия S
  • 15. 15 Условия SELECT id, first_name, last_name FROM users WHERE id < 5 +
  • 16. 16 template<class L, class R> conditions::lesser_than_t<L, R> lesser_than(L l, R r) { return {std::move(l), std::move(r)}; } template<class L, class R> struct lesser_than_t : binary_condition<L, R>, lesser_than_string { using self = lesser_than_t<L, R>; using binary_condition<L, R>::binary_condition; negated_condition_t<self> operator!() const { return {*this}; } }; Условия
  • 17. 17 template<class L, class R> struct binary_condition : public condition_t { using left_type = L; using right_type = R; left_type l; right_type r; binary_condition() = default; binary_condition(left_type l_, right_type r_) : l(std::move(l_)), r(std::move(r_)) {} }; Условия
  • 18. 18 auto users = storage.get_all<User>(where(lt(&User::id, 5))); // decltype(users) is vector<User> auto users = storage.get_all<User>(where(c(&User::id) < 5)); Условия
  • 19. 19 template<class T> internal::expression_t<T> c(T t) { return {std::move(t)}; } template<class T, class R> conditions::lesser_than_t<T, R> operator<(internal::expression_t<T> expr, R r) { return {std::move(expr.t), std::move(r)}; } template<class L, class T> conditions::lesser_than_t<L, T> operator<(L l, internal::expression_t<T> expr) { return {std::move(l), std::move(expr.t)}; } Условия
  • 20. 20 template<class T> struct expression_t { T t; expression_t(T t_) : t(std::move(t_)) {} template<class R> assign_t<T, R> operator=(R r) const { return {this->t, std::move(r)}; } assign_t<T, std::nullptr_t> operator=(std::nullptr_t) const { return {this->t, nullptr}; } }; Условия +
  • 21. 21 auto users = storage.get_all<User>(where(c(&User::id) < 5 and c(&User::firstName) == «Barney»)); Условия S
  • 22. 22 Условия SELECT id, first_name, last_name FROM users WHERE id < 5 AND first_name = ‘Barney’
  • 23. 23 template<class L, class R, typename = typename std::enable_if<std::is_base_of<conditions::condition_t, L>::value || std::is_base_of<conditions::condition_t, R>::value>::type> and_condition_t<L, R> operator&&(L l, R r) { return {std::move(l), std::move(r)}; } Условия 
  • 24. 24 auto users = storage.get_all<User>(where(not like(&User::firstName, "J%") and (between(&User::id, 10, 20) or glob(&User::lastName, "*b*")))); Core functions & operators S
  • 25. 25 Core functions & operators SELECT id, first_name, last_name FROM users WHERE NOT (first_name LIKE ‘J%’) AND (id BETWEEN 10 AND 20 OR last_name GLOB ‘*b*’) +
  • 26. 26 struct between_string { operator std::string() const { return "BETWEEN"; } }; template<class A, class T> struct between_t : condition_t, between_string { using expression_type = A; using lower_type = T; using upper_type = T; expression_type expr; lower_type b1; upper_type b2; between_t(expression_type expr_, lower_type b1_, upper_type b2_) : expr(std::move(expr_)), b1(std::move(b1_)), b2(std::move(b2_)) {} }; template<class A, class T> between_t<A, T> between(A expr, T b1, T b2) { return {std::move(expr), std::move(b1), std::move(b2)}; } Core functions & operators 
  • 27. 27 auto allIds = storage.select(&User::id); // decltype(allIds) is vector<decltype(User::id)> AKA vector<int> Raw select S
  • 29. 29 auto rows = storage.select(columns(&User::firstName, &User::lastName), where(c(&User::id) > 250), order_by(&User::id)); // decltype(partialSelect) is vector<tuple<string, string>> Raw select S
  • 30. 30 Raw select SELECT first_name, last_name FROM users WHERE id > 250 ORDER BY id +
  • 31. 31 auto rows = storage.select(columns(&Doctor::id, &Doctor::name, &Visit::patientName, &Visit::vdate), left_join<Visit>(on(c(&Doctor::id) == &Visit::doctorId))); Raw select S
  • 32. 32 Raw select SELECT doctors.doctor_id, doctors.doctor_name, visits.patient_name, visits.vdate FROM doctors LEFT JOIN visits ON doctors.doctor_id = visits.doctor_id; +
  • 33. 33 Raw select template<class... Args> internal::columns_t<Args...> columns(Args... args) { return {std::make_tuple<Args...>(std::forward<Args>(args)...)}; } template<class... Args> struct columns_t { using columns_type = std::tuple<Args...>; columns_type columns; bool distinct = false; static constexpr const size_t count = std::tuple_size<columns_type>::value; };
  • 34. 34 Raw select template<class T, class... Args, class R = typename column_result_t<self, T>::type> std::vector<R> select(T m, Args... args) { static_assert(!is_base_of_template<T, compound_operator>::value || std::tuple_size<std::tuple<Args...>>::value == 0, "Cannot use args with a compound operator"); auto statement = this->prepare(sqlite_orm::select(std::move(m), std::forward<Args>(args)...)); return this->execute(statement); }
  • 35. 35 Raw select template<class St, class T, class SFINAE = void> struct column_result_t; template<class St, class O, class F> struct column_result_t<St, F O::*, typename std::enable_if<std::is_member_pointer<F O::*>::value &&!std::is_member_function_pointer<F O::*>::value>::type> { using type = F; }; template<class St, class... Args> struct column_result_t<St, columns_t<Args...>, void> { using type = std::tuple<typename column_result_t<St, typename std::decay<Args>::type>::type...>; }; +
  • 36. 36 auto rows = storage.select( union_all(select(columns(&Department::employeeId, &Employee::name, &Department::dept), inner_join<Department>(on(c(&Employee::id) == &Department::employeeId))), select(columns(&Department::employeeId, &Employee::name, &Department::dept), left_outer_join<Department>(on(c(&Employee::id) == &Department::employeeId))))); Raw select S
  • 37. 37 SELECT emp_id, name, dept FROM company INNER JOIN department ON company.id = department.emp_id UNION ALL SELECT emp_id, name, dept FROM company LEFT OUTER JOIN department ON company.id = department.emp_id Raw select I
  • 39. 39 auto statement = storage.prepare(select(columns(5.0, &User::id, count(&User::name)), where(c(&User::id) < 10))); auto rows = storage.execute(statement); Prepared statements S
  • 40. 40 Prepared statements SELECT 5.0, id, COUNT(name) FROM users WHERE id < 10 +
  • 41. 41 get<0>(statement) = 4; get<1>(statement) = 2; Prepared statements S
  • 42. 42 Prepared statements SELECT 4.0, id, COUNT(name) FROM users WHERE id < 2 I
  • 44. 44 template<class T, class... Args> struct select_t { using return_type = T; using conditions_type = std::tuple<Args...>; return_type col; conditions_type conditions; bool highest_level = false; }; template<class T, class... Args> select_t<T, Args...> select(T t, Args... args) { return {std::move(t), std::make_tuple<Args...>(std::forward<Args>(args)...)}; } Prepared statements
  • 45. 45 template<int N, class T> auto &get(prepared_statement_t<T> &statement) { using statement_type = typename std::decay<decltype(statement)>::type; using expression_type = typename statement_type::expression_type; using node_tuple = typename node_tuple<expression_type>::type; using bind_tuple = typename bindable_filter<node_tuple>::type; using result_tupe = typename std::tuple_element<N, bind_tuple>::type; result_tupe *result = nullptr; auto index = -1; iterate_ast(statement.t, [&result, &index](auto &node) { using node_type = typename std::decay<decltype(node)>::type; if(is_bindable<node_type>::value) { ++index; } if(index == N) { static_if<std::is_same<result_tupe, node_type>{}>([](auto &result, auto &node) { result = const_cast<typename std::remove_reference<decltype(result)>::type>(&node); })(result, node); } }); return get_ref(*result); } Prepared statements
  • 46. 46 template<class T, class L> void iterate_ast(const T &t, const L &l) { ast_iterator<T> iterator; iterator(t, l); } template<class T, class SFINAE = void> struct ast_iterator { using node_type = T; template<class L> void operator()(const T &t, const L &l) const { l(t); } }; template<class T> struct ast_iterator< T, typename std::enable_if<is_base_of_template<T, conditions::binary_condition>::value>::type> { using node_type = T; template<class L> void operator()(const node_type &binaryCondition, const L &l) const { iterate_ast(binaryCondition.l, l); iterate_ast(binaryCondition.r, l); } }; AST iteration 