Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

282 righe
9.5 KiB

  1. #include <string>
  2. #include <iostream>
  3. #include <cpputils/misc/enum.h>
  4. #include <cpputils/misc/string.h>
  5. #include <cpputils/misc/indent.h>
  6. #include <cpphibernate/misc.h>
  7. #include <cpphibernate/driver/mariadb/schema/field.h>
  8. #include <cpphibernate/driver/mariadb/schema/table.h>
  9. using namespace ::std;
  10. using namespace ::utl;
  11. using namespace ::cpphibernate::driver::mariadb_impl;
  12. void field_t::print(std::ostream& os) const
  13. {
  14. os << indent << '{'
  15. << incindent
  16. << indent << "\"id\": " << id << ","
  17. << indent << "\"dataset_id\": " << dataset_id << ","
  18. << indent << "\"real_dataset_id\": " << real_dataset_id << ","
  19. << indent << "\"value_id\": " << value_id << ","
  20. << indent << "\"real_value_id\": " << real_value_id << ","
  21. << indent << "\"value_is_nullable\": " << (value_is_nullable ? "true" : "false") << ","
  22. << indent << "\"value_is_pointer\": " << (value_is_pointer ? "true" : "false") << ","
  23. << indent << "\"value_is_container\": " << (value_is_container ? "true" : "false") << ","
  24. << indent << "\"value_is_auto_incremented\": " << (value_is_auto_incremented ? "true" : "false") << ","
  25. << indent << "\"table\": " << (table ? std::string("\"") + table->table_name + "\"" : "null") << ","
  26. << indent << "\"referenced_table\": " << (referenced_table ? std::string("\"") + referenced_table->table_name + "\"" : "null") << ","
  27. << indent << "\"schema_name\": \"" << schema_name << "\","
  28. << indent << "\"table_name\": \"" << table_name << "\","
  29. << indent << "\"field_name\": \"" << field_name << "\","
  30. << indent << "\"type\": \"" << type << "\","
  31. << indent << "\"create_arguments\": \"" << create_arguments << "\","
  32. << indent << "\"convert_to_open\": \"" << convert_to_open << "\","
  33. << indent << "\"convert_to_close\": \"" << convert_to_close << "\","
  34. << indent << "\"convert_from_open\": \"" << convert_from_open << "\","
  35. << indent << "\"convert_from_close\": \"" << convert_from_close << "\","
  36. << indent << "\"attributes\": " << misc::print_container(attributes, false)
  37. << decindent
  38. << indent << '}';
  39. }
  40. void field_t::update()
  41. {
  42. id = 0;
  43. dataset_id = 0;
  44. real_dataset_id = 0;
  45. value_id = 0;
  46. real_value_id = 0;
  47. value_is_nullable = false;
  48. value_is_container = false;
  49. value_is_auto_incremented = false;
  50. table = nullptr;
  51. referenced_table = nullptr;
  52. type.clear();
  53. create_arguments.clear();
  54. /* conver_to_open */
  55. {
  56. std::ostringstream ss;
  57. for (auto it = this->attributes.begin(); it != this->attributes.end(); ++it)
  58. {
  59. switch(*it)
  60. {
  61. case attribute_t::hex:
  62. ss << "HEX(";
  63. break;
  64. case attribute_t::compress:
  65. ss << "COMPRESS(";
  66. break;
  67. default:
  68. break;
  69. }
  70. }
  71. convert_to_open = ss.str();
  72. }
  73. /* convert_to_close */
  74. {
  75. std::ostringstream ss;
  76. for (auto it = this->attributes.begin(); it != this->attributes.end(); ++it)
  77. {
  78. switch(*it)
  79. {
  80. case attribute_t::hex:
  81. case attribute_t::compress:
  82. ss << ')';
  83. break;
  84. default:
  85. break;
  86. }
  87. }
  88. convert_to_close = ss.str();
  89. }
  90. /* convert_from_open */
  91. {
  92. std::ostringstream ss;
  93. for (auto it = this->attributes.rbegin(); it != this->attributes.rend(); ++it)
  94. {
  95. switch(*it)
  96. {
  97. case attribute_t::hex:
  98. ss << "UNHEX(";
  99. break;
  100. case attribute_t::compress:
  101. ss << "UNCOMPRESS(";
  102. break;
  103. default:
  104. break;
  105. }
  106. }
  107. convert_from_open = ss.str();
  108. }
  109. /* convert_from_close */
  110. {
  111. std::ostringstream ss;
  112. for (auto it = this->attributes.rbegin(); it != this->attributes.rend(); ++it)
  113. {
  114. switch(*it)
  115. {
  116. case attribute_t::hex:
  117. case attribute_t::compress:
  118. ss << ')';
  119. break;
  120. default:
  121. break;
  122. }
  123. }
  124. convert_from_close = ss.str();
  125. }
  126. }
  127. #define throw_not_implemented(p_ret, p_name, ...) \
  128. p_ret field_t::p_name(__VA_ARGS__) const \
  129. { \
  130. throw misc::hibernate_exception( \
  131. std::string("'") + table_name + "." + field_name + \
  132. "' does not implement the " #p_name "() method!"); \
  133. }
  134. /* CRUD */
  135. throw_not_implemented(value_t, foreign_create_update, const create_update_context&)
  136. throw_not_implemented(read_context_ptr, foreign_read, const read_context&, bool fake_context)
  137. /* properties */
  138. throw_not_implemented(bool, is_default, const data_context& context)
  139. throw_not_implemented(string, generate_value, ::cppmariadb::connection&)
  140. throw_not_implemented(value_t, get, const data_context& context)
  141. throw_not_implemented(void, set, const data_context& context, const value_t&)
  142. /* statements */
  143. throw_not_implemented(::cppmariadb::statement&, get_statement_foreign_one_delete, bool)
  144. throw_not_implemented(::cppmariadb::statement&, get_statement_foreign_many_update)
  145. ::cppmariadb::statement& field_t::get_statement_foreign_one_delete_impl(bool key_known, statement_ptr& known, statement_ptr& unknown) const
  146. {
  147. assert(table);
  148. assert(table->primary_key_field);
  149. assert(referenced_table);
  150. assert(referenced_table->primary_key_field);
  151. if (key_known)
  152. {
  153. if (!known)
  154. {
  155. auto& ref_table = *referenced_table;
  156. auto& key_info = *table->primary_key_field;
  157. auto& ref_key_info = *ref_table.primary_key_field;
  158. std::ostringstream os;
  159. os << "WHERE `"
  160. << ref_key_info.field_name
  161. << "` IN (SELECT `"
  162. << ref_key_info.table_name
  163. << "_id_"
  164. << field_name
  165. << "` FROM `"
  166. << key_info.table_name
  167. << "` WHERE `"
  168. << key_info.field_name
  169. << "`="
  170. << key_info.convert_to_open
  171. << "?\?"
  172. << key_info.convert_to_close
  173. << " AND `"
  174. << ref_key_info.table_name
  175. << "_id_"
  176. << field_name
  177. << "`!="
  178. << ref_key_info.convert_to_open
  179. << "?\?"
  180. << ref_key_info.convert_to_close
  181. << ")";
  182. auto where = os.str();
  183. auto query = ref_table.build_delete_query(&where);
  184. known.reset(new ::cppmariadb::statement(query));
  185. }
  186. return *known;
  187. }
  188. else
  189. {
  190. if (!unknown)
  191. {
  192. auto& ref_table = *referenced_table;
  193. auto& key_info = *table->primary_key_field;
  194. auto& ref_key_info = *ref_table.primary_key_field;
  195. std::ostringstream os;
  196. os << "WHERE `"
  197. << ref_key_info.field_name
  198. << "` IN (SELECT `"
  199. << ref_key_info.table_name
  200. << "_id_"
  201. << field_name
  202. << "` FROM `"
  203. << key_info.table_name
  204. << "` WHERE `"
  205. << key_info.field_name
  206. << "`="
  207. << key_info.convert_to_open
  208. << "?\?"
  209. << key_info.convert_to_close
  210. << ")";
  211. auto where = os.str();
  212. auto query = ref_table.build_delete_query(&where);
  213. unknown.reset(new ::cppmariadb::statement(query));
  214. }
  215. return *unknown;
  216. }
  217. }
  218. ::cppmariadb::statement& field_t::get_statement_foreign_many_update_impl(statement_ptr& statement) const
  219. {
  220. assert(referenced_table);
  221. assert(referenced_table->primary_key_field);
  222. if (!statement)
  223. {
  224. auto& ref_key_info = *referenced_table->primary_key_field;
  225. std::ostringstream os;
  226. os << "UPDATE `"
  227. << ref_key_info.table_name
  228. << "` SET `"
  229. << table_name
  230. << "_id_"
  231. << field_name
  232. << "`=NULL";
  233. if (value_is_container)
  234. {
  235. os << ", `"
  236. << table_name
  237. << "_index_"
  238. << field_name
  239. << "`=0";
  240. }
  241. os << " WHERE `"
  242. << table_name
  243. << "_id_"
  244. << field_name
  245. << "`="
  246. << ref_key_info.convert_to_open
  247. << "?\?"
  248. << ref_key_info.convert_to_close;
  249. statement.reset(new ::cppmariadb::statement(os.str()));
  250. }
  251. return *statement;
  252. }