Skip to content

Commit ffd2bd8

Browse files
authored
Merge pull request #1152 from FireDaemon/issues/#1149/2
Use a single implementation of `stream_sql_escaped()`
2 parents 246f974 + 15bee9c commit ffd2bd8

File tree

7 files changed

+57
-97
lines changed

7 files changed

+57
-97
lines changed

dev/column_names_getter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ namespace sqlite_orm {
2121

2222
namespace internal {
2323

24-
template<class T, class I>
25-
std::string serialize(const T& t, const serializer_context<I>& context);
24+
template<class T, class DBOs>
25+
std::string serialize(const T&, const serializer_context<DBOs>&);
2626

2727
template<class T, class Ctx>
2828
std::vector<std::string>& collect_table_column_names(std::vector<std::string>& collectedExpressions,

dev/default_value_extractor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ namespace sqlite_orm {
1010

1111
namespace internal {
1212

13-
template<class T, class I>
14-
std::string serialize(const T& t, const serializer_context<I>& context);
13+
template<class T, class DBOs>
14+
std::string serialize(const T&, const serializer_context<DBOs>&);
1515

1616
/**
1717
* Serialize default value of a column's default valu

dev/serialize_result_type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ namespace sqlite_orm {
99
namespace internal {
1010
#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED
1111
using serialize_result_type = std::string_view;
12+
using serialize_arg_type = std::string_view;
1213
#else
1314
using serialize_result_type = std::string;
15+
using serialize_arg_type = const std::string&;
1416
#endif
1517
}
1618
}

dev/serializing_util.h

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,44 @@
66
#include <string>
77
#include <ostream>
88
#include <utility> // std::exchange, std::tuple_size
9-
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
10-
#include <string_view>
11-
#include <algorithm> // std::find
12-
#endif
139

1410
#include "functional/cxx_universal.h" // ::size_t
1511
#include "functional/cxx_type_traits_polyfill.h"
1612
#include "tuple_helper/tuple_iteration.h"
1713
#include "error_code.h"
1814
#include "serializer_context.h"
15+
#include "serialize_result_type.h"
1916
#include "util.h"
2017

2118
namespace sqlite_orm {
2219
namespace internal {
2320
template<class O>
2421
struct order_by_t;
2522

26-
template<class T, class I>
27-
std::string serialize(const T& t, const serializer_context<I>& context);
23+
template<class T, class DBOs>
24+
std::string serialize(const T&, const serializer_context<DBOs>&);
2825

2926
template<class T, class Ctx>
30-
std::string serialize_order_by(const T& t, const Ctx& context);
31-
32-
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
33-
// optimized version when string_view's iterator range constructor is available
34-
template<class SFINAE = void>
35-
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
36-
requires requires {
37-
std::string_view{str.cbegin(), str.cend()};
38-
}
39-
{
40-
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
41-
next = std::find(it, str.cend(), char2Escape);
42-
os << std::string_view{it, next};
43-
44-
if(next == str.cend()) [[likely]] {
27+
std::string serialize_order_by(const T&, const Ctx&);
28+
29+
inline void stream_sql_escaped(std::ostream& os, serialize_arg_type str, char char2Escape) {
30+
for(size_t offset = 0, next; true; offset = next + 1) {
31+
next = str.find(char2Escape, offset);
32+
33+
if(next == str.npos) {
34+
os.write(str.data() + offset, str.size() - offset);
4535
break;
4636
}
47-
os << std::string(2, char2Escape);
48-
}
49-
}
5037

51-
template<class SFINAE = void>
52-
#endif
53-
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
54-
if(str.find(char2Escape) == str.npos) {
55-
os << str;
56-
} else {
57-
for(char c: str) {
58-
if(c == char2Escape) {
59-
os << char2Escape;
60-
}
61-
os << c;
62-
}
38+
os.write(str.data() + offset, next - offset + 1);
39+
os.write(&char2Escape, 1);
6340
}
6441
}
6542

6643
inline void stream_identifier(std::ostream& ss,
67-
const std::string& qualifier,
68-
const std::string& identifier,
69-
const std::string& alias) {
44+
serialize_arg_type qualifier,
45+
serialize_arg_type identifier,
46+
serialize_arg_type alias) {
7047
constexpr char quoteChar = '"';
7148
constexpr char qualified[] = {quoteChar, '.', '\0'};
7249
constexpr char aliased[] = {' ', quoteChar, '\0'};
@@ -92,11 +69,11 @@ namespace sqlite_orm {
9269
}
9370

9471
inline void stream_identifier(std::ostream& ss, const std::string& identifier, const std::string& alias) {
95-
return stream_identifier(ss, std::string{}, identifier, alias);
72+
return stream_identifier(ss, "", identifier, alias);
9673
}
9774

9875
inline void stream_identifier(std::ostream& ss, const std::string& identifier) {
99-
return stream_identifier(ss, std::string{}, identifier, std::string{});
76+
return stream_identifier(ss, "", identifier, "");
10077
}
10178

10279
template<typename Tpl, size_t... Is>

dev/statement_serializer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ namespace sqlite_orm {
5151
template<class T, class SFINAE = void>
5252
struct statement_serializer;
5353

54-
template<class T, class I>
55-
std::string serialize(const T& t, const serializer_context<I>& context) {
54+
template<class T, class DBOs>
55+
std::string serialize(const T& t, const serializer_context<DBOs>& context) {
5656
statement_serializer<T> serializer;
5757
return serializer(t, context);
5858
}

include/sqlite_orm/sqlite_orm.h

Lines changed: 27 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,8 +1935,10 @@ namespace sqlite_orm {
19351935
namespace internal {
19361936
#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED
19371937
using serialize_result_type = std::string_view;
1938+
using serialize_arg_type = std::string_view;
19381939
#else
19391940
using serialize_result_type = std::string;
1941+
using serialize_arg_type = const std::string&;
19401942
#endif
19411943
}
19421944
}
@@ -10202,8 +10204,8 @@ namespace sqlite_orm {
1020210204

1020310205
namespace internal {
1020410206

10205-
template<class T, class I>
10206-
std::string serialize(const T& t, const serializer_context<I>& context);
10207+
template<class T, class DBOs>
10208+
std::string serialize(const T&, const serializer_context<DBOs>&);
1020710209

1020810210
/**
1020910211
* Serialize default value of a column's default valu
@@ -13206,10 +13208,6 @@ namespace sqlite_orm {
1320613208
#include <string>
1320713209
#include <ostream>
1320813210
#include <utility> // std::exchange, std::tuple_size
13209-
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
13210-
#include <string_view>
13211-
#include <algorithm> // std::find
13212-
#endif
1321313211

1321413212
// #include "functional/cxx_universal.h"
1321513213
// ::size_t
@@ -13221,57 +13219,39 @@ namespace sqlite_orm {
1322113219

1322213220
// #include "serializer_context.h"
1322313221

13222+
// #include "serialize_result_type.h"
13223+
1322413224
// #include "util.h"
1322513225

1322613226
namespace sqlite_orm {
1322713227
namespace internal {
1322813228
template<class O>
1322913229
struct order_by_t;
1323013230

13231-
template<class T, class I>
13232-
std::string serialize(const T& t, const serializer_context<I>& context);
13231+
template<class T, class DBOs>
13232+
std::string serialize(const T&, const serializer_context<DBOs>&);
1323313233

1323413234
template<class T, class Ctx>
13235-
std::string serialize_order_by(const T& t, const Ctx& context);
13236-
13237-
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
13238-
// optimized version when string_view's iterator range constructor is available
13239-
template<class SFINAE = void>
13240-
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
13241-
requires requires {
13242-
std::string_view{str.cbegin(), str.cend()};
13243-
}
13244-
{
13245-
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
13246-
next = std::find(it, str.cend(), char2Escape);
13247-
os << std::string_view{it, next};
13248-
13249-
if(next == str.cend()) [[likely]] {
13235+
std::string serialize_order_by(const T&, const Ctx&);
13236+
13237+
inline void stream_sql_escaped(std::ostream& os, serialize_arg_type str, char char2Escape) {
13238+
for(size_t offset = 0, next; true; offset = next + 1) {
13239+
next = str.find(char2Escape, offset);
13240+
13241+
if(next == str.npos) {
13242+
os.write(str.data() + offset, str.size() - offset);
1325013243
break;
1325113244
}
13252-
os << std::string(2, char2Escape);
13253-
}
13254-
}
1325513245

13256-
template<class SFINAE = void>
13257-
#endif
13258-
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
13259-
if(str.find(char2Escape) == str.npos) {
13260-
os << str;
13261-
} else {
13262-
for(char c: str) {
13263-
if(c == char2Escape) {
13264-
os << char2Escape;
13265-
}
13266-
os << c;
13267-
}
13246+
os.write(str.data() + offset, next - offset + 1);
13247+
os.write(&char2Escape, 1);
1326813248
}
1326913249
}
1327013250

1327113251
inline void stream_identifier(std::ostream& ss,
13272-
const std::string& qualifier,
13273-
const std::string& identifier,
13274-
const std::string& alias) {
13252+
serialize_arg_type qualifier,
13253+
serialize_arg_type identifier,
13254+
serialize_arg_type alias) {
1327513255
constexpr char quoteChar = '"';
1327613256
constexpr char qualified[] = {quoteChar, '.', '\0'};
1327713257
constexpr char aliased[] = {' ', quoteChar, '\0'};
@@ -13297,11 +13277,11 @@ namespace sqlite_orm {
1329713277
}
1329813278

1329913279
inline void stream_identifier(std::ostream& ss, const std::string& identifier, const std::string& alias) {
13300-
return stream_identifier(ss, std::string{}, identifier, alias);
13280+
return stream_identifier(ss, "", identifier, alias);
1330113281
}
1330213282

1330313283
inline void stream_identifier(std::ostream& ss, const std::string& identifier) {
13304-
return stream_identifier(ss, std::string{}, identifier, std::string{});
13284+
return stream_identifier(ss, "", identifier, "");
1330513285
}
1330613286

1330713287
template<typename Tpl, size_t... Is>
@@ -15334,8 +15314,8 @@ namespace sqlite_orm {
1533415314

1533515315
namespace internal {
1533615316

15337-
template<class T, class I>
15338-
std::string serialize(const T& t, const serializer_context<I>& context);
15317+
template<class T, class DBOs>
15318+
std::string serialize(const T&, const serializer_context<DBOs>&);
1533915319

1534015320
template<class T, class Ctx>
1534115321
std::vector<std::string>& collect_table_column_names(std::vector<std::string>& collectedExpressions,
@@ -15530,8 +15510,8 @@ namespace sqlite_orm {
1553015510
template<class T, class SFINAE = void>
1553115511
struct statement_serializer;
1553215512

15533-
template<class T, class I>
15534-
std::string serialize(const T& t, const serializer_context<I>& context) {
15513+
template<class T, class DBOs>
15514+
std::string serialize(const T& t, const serializer_context<DBOs>& context) {
1553515515
statement_serializer<T> serializer;
1553615516
return serializer(t, context);
1553715517
}

tests/statement_serializer_tests/column_names.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ TEST_CASE("statement_serializer column names") {
169169
return R"(a"s)";
170170
}
171171
};
172-
auto table1 = make_table(R"(ob"ject1)", make_column(R"(i"d)", &Object1::id));
172+
auto table1 = make_table(R"(object1"")", make_column(R"(i"d)", &Object1::id));
173173
auto table2 = make_table(R"(ob"ject2)", make_column(R"(i"d)", &Object2::id));
174174
using db_objects_t = internal::db_objects_tuple<decltype(table1), decltype(table2)>;
175175
db_objects_t dbObjects{table1, table2};
@@ -184,8 +184,9 @@ TEST_CASE("statement_serializer column names") {
184184
multi_order_by(order_by(get<colalias>()), order_by(alias_column<als_d>(&Object2::id))));
185185
expression.highest_level = true;
186186
auto value = serialize(expression, context);
187-
REQUIRE(value == R"(SELECT "ob""ject1"."i""d", "ob""ject1"."i""d" AS "a""s", "d"."i""d" FROM "ob""ject1" )"
188-
R"(JOIN "ob""ject2" "d" USING ("i""d") ORDER BY "a""s", "d"."i""d")");
187+
REQUIRE(value ==
188+
R"(SELECT "object1"""""."i""d", "object1"""""."i""d" AS "a""s", "d"."i""d" FROM "object1""""" )"
189+
R"(JOIN "ob""ject2" "d" USING ("i""d") ORDER BY "a""s", "d"."i""d")");
189190
}
190191
}
191192
}

0 commit comments

Comments
 (0)