25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
2.5 KiB

  1. #include <cppmariadb/enums.h>
  2. #include <cppmariadb/exception.h>
  3. #include <cppmariadb/statement.h>
  4. #include <cppmariadb/row.inl>
  5. #include <cppmariadb/column.inl>
  6. #include <cppmariadb/result.inl>
  7. #include <cppmariadb/statement.inl>
  8. #include <cppmariadb/connection.inl>
  9. #include <cppmariadb/impl/handle.inl>
  10. using namespace ::cppmariadb;
  11. void statement::parse(const std::string& query)
  12. {
  13. auto c = query.c_str();
  14. auto t = c;
  15. bool inParam = false;
  16. while (*c != '\0')
  17. {
  18. switch (*c)
  19. {
  20. case '?':
  21. if (inParam)
  22. _parameters.emplace_back(std::string(t, static_cast<std::string::size_type>(c - t)), parameter { false, false, std::string() });
  23. else
  24. _code.emplace_back(t, c - t);
  25. inParam = !inParam;
  26. t = c + 1;
  27. break;
  28. case '!':
  29. if (!inParam)
  30. break;
  31. _parameters.emplace_back(std::string(t, static_cast<std::string::size_type>(c - t)), parameter { false, true, std::string() });
  32. inParam = false;
  33. t = c + 1;
  34. break;
  35. }
  36. ++c;
  37. }
  38. if (inParam)
  39. throw exception("unclosed parameter in statement", error_code::Unknown, query);
  40. if (c != t)
  41. _code.emplace_back(t, c - t);
  42. }
  43. void statement::build(const connection& con) const
  44. {
  45. _connection = &con;
  46. std::ostringstream ss;
  47. size_t i = 0;
  48. if (std::abs(static_cast<ssize_t>(_code.size()) - static_cast<ssize_t>(_parameters.size())) > 1)
  49. throw exception("statement::build() - internal error: code and parameter size mismatch", error_code::Unknown);
  50. while ( (i >> 1) < _code.size()
  51. || (i >> 1) < _parameters.size())
  52. {
  53. size_t idx = (i >> 1);
  54. if ((i & 1) == 0)
  55. {
  56. if (idx >= _code.size())
  57. break;
  58. ss << _code.at(i >> 1);
  59. }
  60. else
  61. {
  62. if (idx >= _parameters.size())
  63. break;
  64. auto& param = _parameters.at(i >> 1).second;
  65. if (param.has_value)
  66. {
  67. if (param.unescaped)
  68. ss << param.value;
  69. else
  70. ss << "'" << con.escape(param.value) << "'";
  71. }
  72. else
  73. {
  74. if (!param.unescaped)
  75. ss << "null";
  76. }
  77. }
  78. ++i;
  79. }
  80. _changed = false;
  81. _query = ss.str();
  82. }