Skip to content

Commit fd3f0bf

Browse files
committed
String_view arguments instead of string
1 parent 5515487 commit fd3f0bf

File tree

3 files changed

+45
-35
lines changed

3 files changed

+45
-35
lines changed

hdr/sqlite_modern_cpp.h

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace sqlite {
4242

4343
void execute();
4444

45-
std::string sql() {
45+
std::string_view sql() {
4646
#if SQLITE_VERSION_NUMBER >= 3014000
4747
auto sqlite_deleter = [](void *ptr) {sqlite3_free(ptr);};
4848
std::unique_ptr<char, decltype(sqlite_deleter)> str(sqlite3_expanded_sql(_stmt.get()), sqlite_deleter);
@@ -52,7 +52,7 @@ namespace sqlite {
5252
#endif
5353
}
5454

55-
std::string original_sql() {
55+
std::string_view original_sql() {
5656
return sqlite3_sql(_stmt.get());
5757
}
5858

@@ -85,11 +85,19 @@ namespace sqlite {
8585
return ++_inx;
8686
}
8787

88-
sqlite3_stmt* _prepare(const std::u16string& sql) {
89-
return _prepare(utility::utf16_to_utf8(sql));
88+
sqlite3_stmt* _prepare(const std::u16string_view& sql) {
89+
//return _prepare(utility::utf16_to_utf8(sql));
90+
int hresult;
91+
sqlite3_stmt* tmp = nullptr;
92+
const void *remaining;
93+
hresult = sqlite3_prepare16_v2(_db.get(), sql.data(), -1, &tmp, &remaining);
94+
if (hresult != SQLITE_OK) errors::throw_sqlite_error(hresult, utility::utf16_to_utf8(sql.data()));
95+
if (!std::all_of(static_cast<const char16_t*>(remaining), sql.data() + sql.size(), [](char16_t ch) {return std::isspace(ch); }))
96+
throw errors::more_statements("Multiple semicolon separated statements are unsupported", utility::utf16_to_utf8(sql.data()));
97+
return tmp;
9098
}
9199

92-
sqlite3_stmt* _prepare(const std::string& sql) {
100+
sqlite3_stmt* _prepare(const std::string_view& sql) {
93101
int hresult;
94102
sqlite3_stmt* tmp = nullptr;
95103
const char *remaining;
@@ -105,13 +113,13 @@ namespace sqlite {
105113

106114
public:
107115

108-
database_binder(std::shared_ptr<sqlite3> db, std::u16string const & sql):
116+
database_binder(std::shared_ptr<sqlite3> db, std::u16string_view const & sql):
109117
_db(db),
110118
_stmt(_prepare(sql), sqlite3_finalize),
111119
_inx(0) {
112120
}
113121

114-
database_binder(std::shared_ptr<sqlite3> db, std::string const & sql):
122+
database_binder(std::shared_ptr<sqlite3> db, std::string_view const & sql):
115123
_db(db),
116124
_stmt(_prepare(sql), sqlite3_finalize),
117125
_inx(0) {
@@ -362,7 +370,7 @@ namespace sqlite {
362370
std::shared_ptr<sqlite3> _db;
363371

364372
public:
365-
database(const std::string &db_name, const sqlite_config &config = {}): _db(nullptr) {
373+
database(const std::string_view &db_name, const sqlite_config &config = {}): _db(nullptr) {
366374
sqlite3* tmp = nullptr;
367375
auto ret = sqlite3_open_v2(db_name.data(), &tmp, static_cast<int>(config.flags), config.zVfs);
368376
_db = std::shared_ptr<sqlite3>(tmp, [=](sqlite3* ptr) { sqlite3_close_v2(ptr); }); // this will close the connection eventually when no longer needed.
@@ -372,8 +380,8 @@ namespace sqlite {
372380
*this << R"(PRAGMA encoding = "UTF-16";)";
373381
}
374382

375-
database(const std::u16string &db_name, const sqlite_config &config = {}): _db(nullptr) {
376-
auto db_name_utf8 = utility::utf16_to_utf8(db_name);
383+
database(const std::u16string_view &db_name, const sqlite_config &config = {}): _db(nullptr) {
384+
auto db_name_utf8 = utility::utf16_to_utf8(db_name.data());
377385
sqlite3* tmp = nullptr;
378386
auto ret = sqlite3_open_v2(db_name_utf8.data(), &tmp, static_cast<int>(config.flags), config.zVfs);
379387
_db = std::shared_ptr<sqlite3>(tmp, [=](sqlite3* ptr) { sqlite3_close_v2(ptr); }); // this will close the connection eventually when no longer needed.
@@ -386,20 +394,20 @@ namespace sqlite {
386394
database(std::shared_ptr<sqlite3> db):
387395
_db(db) {}
388396

389-
database_binder operator<<(const std::string& sql) {
397+
database_binder operator<<(const std::string_view& sql) {
390398
return database_binder(_db, sql);
391399
}
392400

393401
database_binder operator<<(const char* sql) {
394-
return *this << std::string(sql);
402+
return *this << std::string_view(sql);
395403
}
396404

397-
database_binder operator<<(const std::u16string& sql) {
405+
database_binder operator<<(const std::u16string_view& sql) {
398406
return database_binder(_db, sql);
399407
}
400408

401409
database_binder operator<<(const char16_t* sql) {
402-
return *this << std::u16string(sql);
410+
return *this << std::u16string_view(sql);
403411
}
404412

405413
connection_type connection() const { return _db; }
@@ -413,12 +421,12 @@ namespace sqlite {
413421
}
414422

415423
template <typename Function>
416-
void define(const std::string &name, Function&& func) {
424+
void define(const std::string_view &name, Function&& func) {
417425
typedef utility::function_traits<Function> traits;
418426

419427
auto funcPtr = new auto(std::forward<Function>(func));
420428
if(int result = sqlite3_create_function_v2(
421-
_db.get(), name.c_str(), traits::arity, SQLITE_UTF8, funcPtr,
429+
_db.get(), name.data(), traits::arity, SQLITE_UTF8, funcPtr,
422430
sql_function_binder::scalar<traits::arity, typename std::remove_reference<Function>::type>,
423431
nullptr, nullptr, [](void* ptr){
424432
delete static_cast<decltype(funcPtr)>(ptr);
@@ -427,13 +435,13 @@ namespace sqlite {
427435
}
428436

429437
template <typename StepFunction, typename FinalFunction>
430-
void define(const std::string &name, StepFunction&& step, FinalFunction&& final) {
438+
void define(const std::string_view &name, StepFunction&& step, FinalFunction&& final) {
431439
typedef utility::function_traits<StepFunction> traits;
432440
using ContextType = typename std::remove_reference<typename traits::template argument<0>>::type;
433441

434442
auto funcPtr = new auto(std::make_pair(std::forward<StepFunction>(step), std::forward<FinalFunction>(final)));
435443
if(int result = sqlite3_create_function_v2(
436-
_db.get(), name.c_str(), traits::arity - 1, SQLITE_UTF8, funcPtr, nullptr,
444+
_db.get(), name.data(), traits::arity - 1, SQLITE_UTF8, funcPtr, nullptr,
437445
sql_function_binder::step<ContextType, traits::arity, typename std::remove_reference<decltype(*funcPtr)>::type>,
438446
sql_function_binder::final<ContextType, typename std::remove_reference<decltype(*funcPtr)>::type>,
439447
[](void* ptr){

hdr/sqlite_modern_cpp/errors.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ namespace sqlite {
99

1010
class sqlite_exception: public std::runtime_error {
1111
public:
12-
sqlite_exception(const char* msg, std::string sql, int code = -1): runtime_error(msg), code(code), sql(sql) {}
13-
sqlite_exception(int code, std::string sql): runtime_error(sqlite3_errstr(code)), code(code), sql(sql) {}
12+
sqlite_exception(const char* msg, std::string_view sql, int code = -1): runtime_error(msg), code(code), sql(sql) {}
13+
sqlite_exception(int code, std::string_view sql): runtime_error(sqlite3_errstr(code)), code(code), sql(sql) {}
1414
int get_code() const {return code & 0xFF;}
1515
int get_extended_code() const {return code;}
16-
std::string get_sql() const {return sql;}
16+
std::string_view get_sql() const {return sql;}
1717
private:
1818
int code;
1919
std::string sql;
@@ -40,7 +40,7 @@ namespace sqlite {
4040
class more_statements: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements can only contain one statement
4141
class invalid_utf16: public sqlite_exception { using sqlite_exception::sqlite_exception; };
4242

43-
static void throw_sqlite_error(const int& error_code, const std::string &sql = "") {
43+
static void throw_sqlite_error(const int& error_code, const std::string_view &sql = "") {
4444
switch(error_code & 0xFF) {
4545
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
4646
case SQLITE_ ## NAME: switch(error_code) { \

hdr/sqlite_modern_cpp/type_wrapper.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,17 @@ namespace sqlite {
150150
sqlite3_result_null(db);
151151
}
152152

153-
// std::string
153+
// std::string_view
154+
template<>
155+
struct has_sqlite_type<std::string_view, SQLITE3_TEXT, void> : std::true_type {};
154156
template<>
155157
struct has_sqlite_type<std::string, SQLITE3_TEXT, void> : std::true_type {};
156-
157-
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const std::string& val) {
158+
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const std::string_view& val) {
158159
return sqlite3_bind_text(stmt, inx, val.data(), -1, SQLITE_TRANSIENT);
159160
}
160161

161-
// Convert char* to string to trigger op<<(..., const std::string )
162-
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) { return bind_col_in_db(stmt, inx, std::string(STR, N-1)); }
162+
// Convert char* to string_view to trigger op<<(..., const std::string_view )
163+
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) { return bind_col_in_db(stmt, inx, std::string_view(STR, N-1)); }
163164

164165
inline std::string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<std::string>) {
165166
return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::string() :
@@ -170,30 +171,31 @@ namespace sqlite {
170171
std::string(reinterpret_cast<char const *>(sqlite3_value_text(value)), sqlite3_value_bytes(value));
171172
}
172173

173-
inline void store_result_in_db(sqlite3_context* db, const std::string& val) {
174+
inline void store_result_in_db(sqlite3_context* db, const std::string_view& val) {
174175
sqlite3_result_text(db, val.data(), -1, SQLITE_TRANSIENT);
175176
}
176-
// std::u16string
177+
// std::u16string_view
178+
template<>
179+
struct has_sqlite_type<std::u16string_view, SQLITE3_TEXT, void> : std::true_type {};
177180
template<>
178181
struct has_sqlite_type<std::u16string, SQLITE3_TEXT, void> : std::true_type {};
179-
180-
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const std::u16string& val) {
182+
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const std::u16string_view& val) {
181183
return sqlite3_bind_text16(stmt, inx, val.data(), -1, SQLITE_TRANSIENT);
182184
}
183185

184-
// Convert char* to string to trigger op<<(..., const std::string )
185-
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char16_t(&STR)[N]) { return bind_col_in_db(stmt, inx, std::u16string(STR, N-1)); }
186+
// Convert char* to string_view to trigger op<<(..., const std::string_view )
187+
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char16_t(&STR)[N]) { return bind_col_in_db(stmt, inx, std::u16string_view(STR, N-1)); }
186188

187189
inline std::u16string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<std::u16string>) {
188190
return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::u16string() :
189191
std::u16string(reinterpret_cast<char16_t const *>(sqlite3_column_text16(stmt, inx)), sqlite3_column_bytes16(stmt, inx));
190192
}
191-
inline std::u16string get_val_from_db(sqlite3_value *value, result_type<std::u16string >) {
193+
inline std::u16string get_val_from_db(sqlite3_value *value, result_type<std::u16string>) {
192194
return sqlite3_value_type(value) == SQLITE_NULL ? std::u16string() :
193195
std::u16string(reinterpret_cast<char16_t const *>(sqlite3_value_text16(value)), sqlite3_value_bytes16(value));
194196
}
195197

196-
inline void store_result_in_db(sqlite3_context* db, const std::u16string& val) {
198+
inline void store_result_in_db(sqlite3_context* db, const std::u16string_view& val) {
197199
sqlite3_result_text16(db, val.data(), -1, SQLITE_TRANSIENT);
198200
}
199201

0 commit comments

Comments
 (0)