This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
forked from fnc12/sqlite_orm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.h
130 lines (114 loc) · 4.28 KB
/
util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
#include <sqlite3.h>
#include <string> // std::string
#include <utility> // std::move
#include "error_code.h"
namespace sqlite_orm {
/**
* Escape the provided character in the given string by doubling it.
* @param str A copy of the original string
* @param char2Escape The character to escape
*/
inline std::string sql_escape(std::string str, char char2Escape) {
for(size_t pos = 0; (pos = str.find(char2Escape, pos)) != str.npos; pos += 2) {
str.replace(pos, 1, 2, char2Escape);
}
return str;
}
/**
* Quote the given string value using single quotes,
* escape containing single quotes by doubling them.
*/
inline std::string quote_string_literal(std::string v) {
constexpr char quoteChar = '\'';
return quoteChar + sql_escape(std::move(v), quoteChar) + quoteChar;
}
/**
* Quote the given string value using single quotes,
* escape containing single quotes by doubling them.
*/
inline std::string quote_blob_literal(std::string v) {
constexpr char quoteChar = '\'';
return std::string{char('x'), quoteChar} + std::move(v) + quoteChar;
}
/**
* Quote the given identifier using double quotes,
* escape containing double quotes by doubling them.
*/
inline std::string quote_identifier(std::string identifier) {
constexpr char quoteChar = '"';
return quoteChar + sql_escape(std::move(identifier), quoteChar) + quoteChar;
}
namespace internal {
// Wrapper to reduce boiler-plate code
inline sqlite3_stmt* reset_stmt(sqlite3_stmt* stmt) {
sqlite3_reset(stmt);
return stmt;
}
// note: query is deliberately taken by value, such that it is thrown away early
inline sqlite3_stmt* prepare_stmt(sqlite3* db, std::string query) {
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
throw_translated_sqlite_error(db);
}
return stmt;
}
inline void perform_void_exec(sqlite3* db, const std::string& query) {
int rc = sqlite3_exec(db, query.c_str(), nullptr, nullptr, nullptr);
if(rc != SQLITE_OK) {
throw_translated_sqlite_error(db);
}
}
inline void perform_exec(sqlite3* db,
const char* query,
int (*callback)(void* data, int argc, char** argv, char**),
void* user_data) {
int rc = sqlite3_exec(db, query, callback, user_data, nullptr);
if(rc != SQLITE_OK) {
throw_translated_sqlite_error(db);
}
}
inline void perform_exec(sqlite3* db,
const std::string& query,
int (*callback)(void* data, int argc, char** argv, char**),
void* user_data) {
return perform_exec(db, query.c_str(), callback, user_data);
}
template<int expected = SQLITE_DONE>
void perform_step(sqlite3_stmt* stmt) {
int rc = sqlite3_step(stmt);
if(rc != expected) {
throw_translated_sqlite_error(stmt);
}
}
template<class L>
void perform_step(sqlite3_stmt* stmt, L&& lambda) {
switch(int rc = sqlite3_step(stmt)) {
case SQLITE_ROW: {
lambda(stmt);
} break;
case SQLITE_DONE:
break;
default: {
throw_translated_sqlite_error(stmt);
}
}
}
template<class L>
void perform_steps(sqlite3_stmt* stmt, L&& lambda) {
int rc;
do {
switch(rc = sqlite3_step(stmt)) {
case SQLITE_ROW: {
lambda(stmt);
} break;
case SQLITE_DONE:
break;
default: {
throw_translated_sqlite_error(stmt);
}
}
} while(rc != SQLITE_DONE);
}
}
}