Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
One implementation of stream_sql_escaped()
Browse files Browse the repository at this point in the history
  • Loading branch information
trueqbit committed Mar 12, 2023
1 parent e41c35a commit ddee500
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 77 deletions.
2 changes: 2 additions & 0 deletions dev/serialize_result_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ namespace sqlite_orm {
namespace internal {
#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED
using serialize_result_type = std::string_view;
using serialize_arg_type = std::string_view;
#else
using serialize_result_type = std::string;
using serialize_arg_type = const std::string&;
#endif
}
}
51 changes: 14 additions & 37 deletions dev/serializing_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
#include <string>
#include <ostream>
#include <utility> // std::exchange, std::tuple_size
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
#include <string_view>
#include <algorithm> // std::find
#endif

#include "functional/cxx_universal.h" // ::size_t
#include "functional/cxx_type_traits_polyfill.h"
#include "tuple_helper/tuple_iteration.h"
#include "error_code.h"
#include "serializer_context.h"
#include "serialize_result_type.h"
#include "util.h"

namespace sqlite_orm {
Expand All @@ -29,44 +26,24 @@ namespace sqlite_orm {
template<class T, class Ctx>
std::string serialize_order_by(const T& t, const Ctx& context);

#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
// optimized version when string_view's iterator range constructor is available
template<class SFINAE = void>
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
requires requires {
std::string_view{str.cbegin(), str.cend()};
}
{
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
next = std::find(it, str.cend(), char2Escape);
os << std::string_view{it, next};

if(next == str.cend()) [[likely]] {
inline void stream_sql_escaped(std::ostream& os, serialize_arg_type str, char char2Escape) {
for(size_t offset = 0, next; true; offset = next + 1) {
next = str.find(char2Escape, offset);

if(next == str.npos) {
os.write(str.data() + offset, str.size() - offset);
break;
}
os << std::string(2, char2Escape);
}
}

template<class SFINAE = void>
#endif
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
if(str.find(char2Escape) == str.npos) {
os << str;
} else {
for(char c: str) {
if(c == char2Escape) {
os << char2Escape;
}
os << c;
}
os.write(str.data() + offset, next - offset + 1);
os.write(&char2Escape, 1);
}
}

inline void stream_identifier(std::ostream& ss,
const std::string& qualifier,
const std::string& identifier,
const std::string& alias) {
serialize_arg_type qualifier,
serialize_arg_type identifier,
serialize_arg_type alias) {
constexpr char quoteChar = '"';
constexpr char qualified[] = {quoteChar, '.', '\0'};
constexpr char aliased[] = {' ', quoteChar, '\0'};
Expand All @@ -92,11 +69,11 @@ namespace sqlite_orm {
}

inline void stream_identifier(std::ostream& ss, const std::string& identifier, const std::string& alias) {
return stream_identifier(ss, std::string{}, identifier, alias);
return stream_identifier(ss, "", identifier, alias);
}

inline void stream_identifier(std::ostream& ss, const std::string& identifier) {
return stream_identifier(ss, std::string{}, identifier, std::string{});
return stream_identifier(ss, "", identifier, "");
}

template<typename Tpl, size_t... Is>
Expand Down
54 changes: 17 additions & 37 deletions include/sqlite_orm/sqlite_orm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1935,8 +1935,10 @@ namespace sqlite_orm {
namespace internal {
#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED
using serialize_result_type = std::string_view;
using serialize_arg_type = std::string_view;
#else
using serialize_result_type = std::string;
using serialize_arg_type = const std::string&;
#endif
}
}
Expand Down Expand Up @@ -13198,10 +13200,6 @@ namespace sqlite_orm {
#include <string>
#include <ostream>
#include <utility> // std::exchange, std::tuple_size
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
#include <string_view>
#include <algorithm> // std::find
#endif

// #include "functional/cxx_universal.h"
// ::size_t
Expand All @@ -13213,6 +13211,8 @@ namespace sqlite_orm {

// #include "serializer_context.h"

// #include "serialize_result_type.h"

// #include "util.h"

namespace sqlite_orm {
Expand All @@ -13226,44 +13226,24 @@ namespace sqlite_orm {
template<class T, class Ctx>
std::string serialize_order_by(const T& t, const Ctx& context);

#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
// optimized version when string_view's iterator range constructor is available
template<class SFINAE = void>
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
requires requires {
std::string_view{str.cbegin(), str.cend()};
}
{
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
next = std::find(it, str.cend(), char2Escape);
os << std::string_view{it, next};

if(next == str.cend()) [[likely]] {
inline void stream_sql_escaped(std::ostream& os, serialize_arg_type str, char char2Escape) {
for(size_t offset = 0, next; true; offset = next + 1) {
next = str.find(char2Escape, offset);

if(next == str.npos) {
os.write(str.data() + offset, str.size() - offset);
break;
}
os << std::string(2, char2Escape);
}
}

template<class SFINAE = void>
#endif
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
if(str.find(char2Escape) == str.npos) {
os << str;
} else {
for(char c: str) {
if(c == char2Escape) {
os << char2Escape;
}
os << c;
}
os.write(str.data() + offset, next - offset + 1);
os.write(&char2Escape, 1);
}
}

inline void stream_identifier(std::ostream& ss,
const std::string& qualifier,
const std::string& identifier,
const std::string& alias) {
serialize_arg_type qualifier,
serialize_arg_type identifier,
serialize_arg_type alias) {
constexpr char quoteChar = '"';
constexpr char qualified[] = {quoteChar, '.', '\0'};
constexpr char aliased[] = {' ', quoteChar, '\0'};
Expand All @@ -13289,11 +13269,11 @@ namespace sqlite_orm {
}

inline void stream_identifier(std::ostream& ss, const std::string& identifier, const std::string& alias) {
return stream_identifier(ss, std::string{}, identifier, alias);
return stream_identifier(ss, "", identifier, alias);
}

inline void stream_identifier(std::ostream& ss, const std::string& identifier) {
return stream_identifier(ss, std::string{}, identifier, std::string{});
return stream_identifier(ss, "", identifier, "");
}

template<typename Tpl, size_t... Is>
Expand Down
7 changes: 4 additions & 3 deletions tests/statement_serializer_tests/column_names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ TEST_CASE("statement_serializer column names") {
return R"(a"s)";
}
};
auto table1 = make_table(R"(ob"ject1)", make_column(R"(i"d)", &Object1::id));
auto table1 = make_table(R"(object1"")", make_column(R"(i"d)", &Object1::id));
auto table2 = make_table(R"(ob"ject2)", make_column(R"(i"d)", &Object2::id));
using db_objects_t = internal::db_objects_tuple<decltype(table1), decltype(table2)>;
db_objects_t dbObjects{table1, table2};
Expand All @@ -184,8 +184,9 @@ TEST_CASE("statement_serializer column names") {
multi_order_by(order_by(get<colalias>()), order_by(alias_column<als_d>(&Object2::id))));
expression.highest_level = true;
auto value = serialize(expression, context);
REQUIRE(value == R"(SELECT "ob""ject1"."i""d", "ob""ject1"."i""d" AS "a""s", "d"."i""d" FROM "ob""ject1" )"
R"(JOIN "ob""ject2" "d" USING ("i""d") ORDER BY "a""s", "d"."i""d")");
REQUIRE(value ==
R"(SELECT "object1"""""."i""d", "object1"""""."i""d" AS "a""s", "d"."i""d" FROM "object1""""" )"
R"(JOIN "ob""ject2" "d" USING ("i""d") ORDER BY "a""s", "d"."i""d")");
}
}
}

0 comments on commit ddee500

Please sign in to comment.