activerecord 4.2.11.3 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (372) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +613 -1643
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +131 -287
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -243
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -635
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -180
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +23 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -112
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +87 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +621 -303
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +312 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  172. data/lib/active_record/railtie.rb +143 -44
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +328 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +164 -59
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -31
  362. data/lib/active_record/type/decimal.rb +0 -64
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -59
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,19 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasManyThrough < CollectionAssociation #:nodoc:
5
- include ThroughAssociation
6
-
7
- def associated_records_by_owner(preloader)
8
- records_by_owner = super
9
-
10
- if reflection_scope.distinct_value
11
- records_by_owner.each_value { |records| records.uniq! }
12
- end
13
-
14
- records_by_owner
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,23 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasOne < SingularAssociation #:nodoc:
5
-
6
- def association_key_name
7
- reflection.foreign_key
8
- end
9
-
10
- def owner_key_name
11
- reflection.active_record_primary_key
12
- end
13
-
14
- private
15
-
16
- def build_scope
17
- super.order(preload_scope.values[:order] || reflection_scope.values[:order])
18
- end
19
-
20
- end
21
- end
22
- end
23
- end
@@ -1,9 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasOneThrough < SingularAssociation #:nodoc:
5
- include ThroughAssociation
6
- end
7
- end
8
- end
9
- end
@@ -1,21 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class SingularAssociation < Association #:nodoc:
5
-
6
- private
7
-
8
- def preload(preloader)
9
- associated_records_by_owner(preloader).each do |owner, associated_records|
10
- record = associated_records.first
11
-
12
- association = owner.association(reflection.name)
13
- association.target = record
14
- association.set_inverse_instance(record) if record
15
- end
16
- end
17
-
18
- end
19
- end
20
- end
21
- end
@@ -1,163 +0,0 @@
1
- module ActiveRecord
2
- class Attribute # :nodoc:
3
- class << self
4
- def from_database(name, value, type)
5
- FromDatabase.new(name, value, type)
6
- end
7
-
8
- def from_user(name, value, type)
9
- FromUser.new(name, value, type)
10
- end
11
-
12
- def with_cast_value(name, value, type)
13
- WithCastValue.new(name, value, type)
14
- end
15
-
16
- def null(name)
17
- Null.new(name)
18
- end
19
-
20
- def uninitialized(name, type)
21
- Uninitialized.new(name, type)
22
- end
23
- end
24
-
25
- attr_reader :name, :value_before_type_cast, :type
26
-
27
- # This method should not be called directly.
28
- # Use #from_database or #from_user
29
- def initialize(name, value_before_type_cast, type)
30
- @name = name
31
- @value_before_type_cast = value_before_type_cast
32
- @type = type
33
- end
34
-
35
- def value
36
- # `defined?` is cheaper than `||=` when we get back falsy values
37
- @value = original_value unless defined?(@value)
38
- @value
39
- end
40
-
41
- def original_value
42
- type_cast(value_before_type_cast)
43
- end
44
-
45
- def value_for_database
46
- type.type_cast_for_database(value)
47
- end
48
-
49
- def changed_from?(old_value)
50
- type.changed?(old_value, value, value_before_type_cast)
51
- end
52
-
53
- def changed_in_place_from?(old_value)
54
- has_been_read? && type.changed_in_place?(old_value, value)
55
- end
56
-
57
- def with_value_from_user(value)
58
- self.class.from_user(name, value, type)
59
- end
60
-
61
- def with_value_from_database(value)
62
- self.class.from_database(name, value, type)
63
- end
64
-
65
- def with_cast_value(value)
66
- self.class.with_cast_value(name, value, type)
67
- end
68
-
69
- def type_cast(*)
70
- raise NotImplementedError
71
- end
72
-
73
- def initialized?
74
- true
75
- end
76
-
77
- def came_from_user?
78
- false
79
- end
80
-
81
- def ==(other)
82
- self.class == other.class &&
83
- name == other.name &&
84
- value_before_type_cast == other.value_before_type_cast &&
85
- type == other.type
86
- end
87
-
88
- protected
89
-
90
- def initialize_dup(other)
91
- if defined?(@value) && @value.duplicable?
92
- @value = @value.dup
93
- end
94
- end
95
-
96
- private
97
-
98
- def has_been_read?
99
- defined?(@value)
100
- end
101
-
102
- class FromDatabase < Attribute # :nodoc:
103
- def type_cast(value)
104
- type.type_cast_from_database(value)
105
- end
106
- end
107
-
108
- class FromUser < Attribute # :nodoc:
109
- def type_cast(value)
110
- type.type_cast_from_user(value)
111
- end
112
-
113
- def came_from_user?
114
- true
115
- end
116
- end
117
-
118
- class WithCastValue < Attribute # :nodoc:
119
- def type_cast(value)
120
- value
121
- end
122
-
123
- def changed_in_place_from?(old_value)
124
- false
125
- end
126
- end
127
-
128
- class Null < Attribute # :nodoc:
129
- def initialize(name)
130
- super(name, nil, Type::Value.new)
131
- end
132
-
133
- def value
134
- nil
135
- end
136
-
137
- def with_value_from_database(value)
138
- raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
139
- end
140
- alias_method :with_value_from_user, :with_value_from_database
141
- end
142
-
143
- class Uninitialized < Attribute # :nodoc:
144
- def initialize(name, type)
145
- super(name, nil, type)
146
- end
147
-
148
- def value
149
- if block_given?
150
- yield name
151
- end
152
- end
153
-
154
- def value_for_database
155
- end
156
-
157
- def initialized?
158
- false
159
- end
160
- end
161
- private_constant :FromDatabase, :FromUser, :Null, :Uninitialized
162
- end
163
- end
@@ -1,81 +0,0 @@
1
- require 'active_record/attribute_set/builder'
2
-
3
- module ActiveRecord
4
- class AttributeSet # :nodoc:
5
- def initialize(attributes)
6
- @attributes = attributes
7
- end
8
-
9
- def [](name)
10
- attributes[name] || Attribute.null(name)
11
- end
12
-
13
- def values_before_type_cast
14
- attributes.transform_values(&:value_before_type_cast)
15
- end
16
-
17
- def to_hash
18
- initialized_attributes.transform_values(&:value)
19
- end
20
- alias_method :to_h, :to_hash
21
-
22
- def key?(name)
23
- attributes.key?(name) && self[name].initialized?
24
- end
25
-
26
- def keys
27
- attributes.initialized_keys
28
- end
29
-
30
- def fetch_value(name)
31
- self[name].value { |n| yield n if block_given? }
32
- end
33
-
34
- def write_from_database(name, value)
35
- attributes[name] = self[name].with_value_from_database(value)
36
- end
37
-
38
- def write_from_user(name, value)
39
- attributes[name] = self[name].with_value_from_user(value)
40
- end
41
-
42
- def write_cast_value(name, value)
43
- attributes[name] = self[name].with_cast_value(value)
44
- end
45
-
46
- def freeze
47
- @attributes.freeze
48
- super
49
- end
50
-
51
- def initialize_dup(_)
52
- @attributes = attributes.dup
53
- super
54
- end
55
-
56
- def initialize_clone(_)
57
- @attributes = attributes.clone
58
- super
59
- end
60
-
61
- def reset(key)
62
- if key?(key)
63
- write_from_database(key, nil)
64
- end
65
- end
66
-
67
- def ==(other)
68
- attributes == other.attributes
69
- end
70
-
71
- protected
72
-
73
- attr_reader :attributes
74
-
75
- private
76
-
77
- def initialized_attributes
78
- attributes.select { |_, attr| attr.initialized? }
79
- end
80
- end
81
- end
@@ -1,106 +0,0 @@
1
- require 'active_record/attribute'
2
-
3
- module ActiveRecord
4
- class AttributeSet # :nodoc:
5
- class Builder # :nodoc:
6
- attr_reader :types, :always_initialized
7
-
8
- def initialize(types, always_initialized = nil)
9
- @types = types
10
- @always_initialized = always_initialized
11
- end
12
-
13
- def build_from_database(values = {}, additional_types = {})
14
- if always_initialized && !values.key?(always_initialized)
15
- values[always_initialized] = nil
16
- end
17
-
18
- attributes = LazyAttributeHash.new(types, values, additional_types)
19
- AttributeSet.new(attributes)
20
- end
21
- end
22
- end
23
-
24
- class LazyAttributeHash # :nodoc:
25
- delegate :transform_values, to: :materialize
26
-
27
- def initialize(types, values, additional_types)
28
- @types = types
29
- @values = values
30
- @additional_types = additional_types
31
- @materialized = false
32
- @delegate_hash = {}
33
- end
34
-
35
- def key?(key)
36
- delegate_hash.key?(key) || values.key?(key) || types.key?(key)
37
- end
38
-
39
- def [](key)
40
- delegate_hash[key] || assign_default_value(key)
41
- end
42
-
43
- def []=(key, value)
44
- if frozen?
45
- raise RuntimeError, "Can't modify frozen hash"
46
- end
47
- delegate_hash[key] = value
48
- end
49
-
50
- def initialized_keys
51
- delegate_hash.keys | values.keys
52
- end
53
-
54
- def initialize_dup(_)
55
- @delegate_hash = delegate_hash.transform_values(&:dup)
56
- super
57
- end
58
-
59
- def select
60
- keys = types.keys | values.keys | delegate_hash.keys
61
- keys.each_with_object({}) do |key, hash|
62
- attribute = self[key]
63
- if yield(key, attribute)
64
- hash[key] = attribute
65
- end
66
- end
67
- end
68
-
69
- def ==(other)
70
- if other.is_a?(LazyAttributeHash)
71
- materialize == other.materialize
72
- else
73
- materialize == other
74
- end
75
- end
76
-
77
- protected
78
-
79
- attr_reader :types, :values, :additional_types, :delegate_hash
80
-
81
- def materialize
82
- unless @materialized
83
- values.each_key { |key| self[key] }
84
- types.each_key { |key| self[key] }
85
- unless frozen?
86
- @materialized = true
87
- end
88
- end
89
- delegate_hash
90
- end
91
-
92
- private
93
-
94
- def assign_default_value(name)
95
- type = additional_types.fetch(name, types[name])
96
- value_present = true
97
- value = values.fetch(name) { value_present = false }
98
-
99
- if value_present
100
- delegate_hash[name] = Attribute.from_database(name, value, type)
101
- elsif types.key?(name)
102
- delegate_hash[name] = Attribute.uninitialized(name, type)
103
- end
104
- end
105
- end
106
- end
@@ -1,498 +0,0 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
2
- require 'active_record/connection_adapters/statement_pool'
3
- require 'active_support/core_ext/hash/keys'
4
-
5
- gem 'mysql', '~> 2.9'
6
- require 'mysql'
7
-
8
- class Mysql
9
- class Time
10
- def to_date
11
- Date.new(year, month, day)
12
- end
13
- end
14
- class Stmt; include Enumerable end
15
- class Result; include Enumerable end
16
- end
17
-
18
- module ActiveRecord
19
- module ConnectionHandling # :nodoc:
20
- # Establishes a connection to the database that's used by all Active Record objects.
21
- def mysql_connection(config)
22
- config = config.symbolize_keys
23
- host = config[:host]
24
- port = config[:port]
25
- socket = config[:socket]
26
- username = config[:username] ? config[:username].to_s : 'root'
27
- password = config[:password].to_s
28
- database = config[:database]
29
-
30
- mysql = Mysql.init
31
- mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslca] || config[:sslkey]
32
-
33
- default_flags = Mysql.const_defined?(:CLIENT_MULTI_RESULTS) ? Mysql::CLIENT_MULTI_RESULTS : 0
34
- default_flags |= Mysql::CLIENT_FOUND_ROWS if Mysql.const_defined?(:CLIENT_FOUND_ROWS)
35
- options = [host, username, password, database, port, socket, default_flags]
36
- ConnectionAdapters::MysqlAdapter.new(mysql, logger, options, config)
37
- rescue Mysql::Error => error
38
- if error.message.include?("Unknown database")
39
- raise ActiveRecord::NoDatabaseError.new(error.message, error)
40
- else
41
- raise
42
- end
43
- end
44
- end
45
-
46
- module ConnectionAdapters
47
- # The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with
48
- # the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/).
49
- #
50
- # Options:
51
- #
52
- # * <tt>:host</tt> - Defaults to "localhost".
53
- # * <tt>:port</tt> - Defaults to 3306.
54
- # * <tt>:socket</tt> - Defaults to "/tmp/mysql.sock".
55
- # * <tt>:username</tt> - Defaults to "root"
56
- # * <tt>:password</tt> - Defaults to nothing.
57
- # * <tt>:database</tt> - The name of the database. No default, must be provided.
58
- # * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
59
- # * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
60
- # * <tt>:strict</tt> - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html)
61
- # * <tt>:variables</tt> - (Optional) A hash session variables to send as <tt>SET @@SESSION.key = value</tt> on each database connection. Use the value +:default+ to set a variable to its DEFAULT value. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/set-statement.html).
62
- # * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection.
63
- # * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
64
- # * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
65
- # * <tt>:sslcapath</tt> - Necessary to use MySQL with an SSL connection.
66
- # * <tt>:sslcipher</tt> - Necessary to use MySQL with an SSL connection.
67
- #
68
- class MysqlAdapter < AbstractMysqlAdapter
69
- ADAPTER_NAME = 'MySQL'.freeze
70
-
71
- class StatementPool < ConnectionAdapters::StatementPool
72
- def initialize(connection, max = 1000)
73
- super
74
- @cache = Hash.new { |h,pid| h[pid] = {} }
75
- end
76
-
77
- def each(&block); cache.each(&block); end
78
- def key?(key); cache.key?(key); end
79
- def [](key); cache[key]; end
80
- def length; cache.length; end
81
- def delete(key); cache.delete(key); end
82
-
83
- def []=(sql, key)
84
- while @max <= cache.size
85
- cache.shift.last[:stmt].close
86
- end
87
- cache[sql] = key
88
- end
89
-
90
- def clear
91
- cache.each_value do |hash|
92
- hash[:stmt].close
93
- end
94
- cache.clear
95
- end
96
-
97
- private
98
- def cache
99
- @cache[Process.pid]
100
- end
101
- end
102
-
103
- def initialize(connection, logger, connection_options, config)
104
- super
105
- @statements = StatementPool.new(@connection,
106
- self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 }))
107
- @client_encoding = nil
108
- connect
109
- end
110
-
111
- # Returns true, since this connection adapter supports prepared statement
112
- # caching.
113
- def supports_statement_cache?
114
- true
115
- end
116
-
117
- # HELPER METHODS ===========================================
118
-
119
- def each_hash(result) # :nodoc:
120
- if block_given?
121
- result.each_hash do |row|
122
- row.symbolize_keys!
123
- yield row
124
- end
125
- else
126
- to_enum(:each_hash, result)
127
- end
128
- end
129
-
130
- def error_number(exception) # :nodoc:
131
- exception.errno if exception.respond_to?(:errno)
132
- end
133
-
134
- # QUOTING ==================================================
135
-
136
- def quote_string(string) #:nodoc:
137
- @connection.quote(string)
138
- end
139
-
140
- #--
141
- # CONNECTION MANAGEMENT ====================================
142
- #++
143
-
144
- def active?
145
- if @connection.respond_to?(:stat)
146
- @connection.stat
147
- else
148
- @connection.query 'select 1'
149
- end
150
-
151
- # mysql-ruby doesn't raise an exception when stat fails.
152
- if @connection.respond_to?(:errno)
153
- @connection.errno.zero?
154
- else
155
- true
156
- end
157
- rescue Mysql::Error
158
- false
159
- end
160
-
161
- def reconnect!
162
- super
163
- disconnect!
164
- connect
165
- end
166
-
167
- # Disconnects from the database if already connected. Otherwise, this
168
- # method does nothing.
169
- def disconnect!
170
- super
171
- @connection.close rescue nil
172
- end
173
-
174
- def reset!
175
- if @connection.respond_to?(:change_user)
176
- # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to
177
- # reset the connection is to change the user to the same user.
178
- @connection.change_user(@config[:username], @config[:password], @config[:database])
179
- configure_connection
180
- end
181
- end
182
-
183
- #--
184
- # DATABASE STATEMENTS ======================================
185
- #++
186
-
187
- def select_rows(sql, name = nil, binds = [])
188
- @connection.query_with_result = true
189
- rows = exec_query(sql, name, binds).rows
190
- @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
191
- rows
192
- end
193
-
194
- # Clears the prepared statements cache.
195
- def clear_cache!
196
- super
197
- @statements.clear
198
- end
199
-
200
- # Taken from here:
201
- # https://github.com/tmtm/ruby-mysql/blob/master/lib/mysql/charset.rb
202
- # Author: TOMITA Masahiro <tommy@tmtm.org>
203
- ENCODINGS = {
204
- "armscii8" => nil,
205
- "ascii" => Encoding::US_ASCII,
206
- "big5" => Encoding::Big5,
207
- "binary" => Encoding::ASCII_8BIT,
208
- "cp1250" => Encoding::Windows_1250,
209
- "cp1251" => Encoding::Windows_1251,
210
- "cp1256" => Encoding::Windows_1256,
211
- "cp1257" => Encoding::Windows_1257,
212
- "cp850" => Encoding::CP850,
213
- "cp852" => Encoding::CP852,
214
- "cp866" => Encoding::IBM866,
215
- "cp932" => Encoding::Windows_31J,
216
- "dec8" => nil,
217
- "eucjpms" => Encoding::EucJP_ms,
218
- "euckr" => Encoding::EUC_KR,
219
- "gb2312" => Encoding::EUC_CN,
220
- "gbk" => Encoding::GBK,
221
- "geostd8" => nil,
222
- "greek" => Encoding::ISO_8859_7,
223
- "hebrew" => Encoding::ISO_8859_8,
224
- "hp8" => nil,
225
- "keybcs2" => nil,
226
- "koi8r" => Encoding::KOI8_R,
227
- "koi8u" => Encoding::KOI8_U,
228
- "latin1" => Encoding::ISO_8859_1,
229
- "latin2" => Encoding::ISO_8859_2,
230
- "latin5" => Encoding::ISO_8859_9,
231
- "latin7" => Encoding::ISO_8859_13,
232
- "macce" => Encoding::MacCentEuro,
233
- "macroman" => Encoding::MacRoman,
234
- "sjis" => Encoding::SHIFT_JIS,
235
- "swe7" => nil,
236
- "tis620" => Encoding::TIS_620,
237
- "ucs2" => Encoding::UTF_16BE,
238
- "ujis" => Encoding::EucJP_ms,
239
- "utf8" => Encoding::UTF_8,
240
- "utf8mb4" => Encoding::UTF_8,
241
- }
242
-
243
- # Get the client encoding for this database
244
- def client_encoding
245
- return @client_encoding if @client_encoding
246
-
247
- result = exec_query(
248
- "select @@character_set_client",
249
- 'SCHEMA')
250
- @client_encoding = ENCODINGS[result.rows.last.last]
251
- end
252
-
253
- def exec_query(sql, name = 'SQL', binds = [])
254
- if without_prepared_statement?(binds)
255
- result_set, affected_rows = exec_without_stmt(sql, name)
256
- else
257
- result_set, affected_rows = exec_stmt(sql, name, binds)
258
- end
259
-
260
- yield affected_rows if block_given?
261
-
262
- result_set
263
- end
264
-
265
- def last_inserted_id(result)
266
- @connection.insert_id
267
- end
268
-
269
- module Fields # :nodoc:
270
- class DateTime < Type::DateTime # :nodoc:
271
- def cast_value(value)
272
- if Mysql::Time === value
273
- new_time(
274
- value.year,
275
- value.month,
276
- value.day,
277
- value.hour,
278
- value.minute,
279
- value.second,
280
- value.second_part)
281
- else
282
- super
283
- end
284
- end
285
-
286
- def has_precision?
287
- precision || 0
288
- end
289
- end
290
-
291
- class Time < Type::Time # :nodoc:
292
- def cast_value(value)
293
- if Mysql::Time === value
294
- new_time(
295
- 2000,
296
- 01,
297
- 01,
298
- value.hour,
299
- value.minute,
300
- value.second,
301
- value.second_part)
302
- else
303
- super
304
- end
305
- end
306
- end
307
-
308
- class << self
309
- TYPES = Type::HashLookupTypeMap.new # :nodoc:
310
-
311
- delegate :register_type, :alias_type, to: :TYPES
312
-
313
- def find_type(field)
314
- if field.type == Mysql::Field::TYPE_TINY && field.length > 1
315
- TYPES.lookup(Mysql::Field::TYPE_LONG)
316
- else
317
- TYPES.lookup(field.type)
318
- end
319
- end
320
- end
321
-
322
- register_type Mysql::Field::TYPE_TINY, Type::Boolean.new
323
- register_type Mysql::Field::TYPE_LONG, Type::Integer.new
324
- alias_type Mysql::Field::TYPE_LONGLONG, Mysql::Field::TYPE_LONG
325
- alias_type Mysql::Field::TYPE_NEWDECIMAL, Mysql::Field::TYPE_LONG
326
-
327
- register_type Mysql::Field::TYPE_DATE, Type::Date.new
328
- register_type Mysql::Field::TYPE_DATETIME, Fields::DateTime.new
329
- register_type Mysql::Field::TYPE_TIME, Fields::Time.new
330
- register_type Mysql::Field::TYPE_FLOAT, Type::Float.new
331
- end
332
-
333
- def initialize_type_map(m) # :nodoc:
334
- super
335
- m.register_type %r(time)i, Fields::Time.new
336
- m.register_type(%r(datetime)i) do |sql_type|
337
- precision = extract_precision(sql_type)
338
- Fields::DateTime.new(precision: precision)
339
- end
340
- end
341
-
342
- def exec_without_stmt(sql, name = 'SQL') # :nodoc:
343
- # Some queries, like SHOW CREATE TABLE don't work through the prepared
344
- # statement API. For those queries, we need to use this method. :'(
345
- log(sql, name) do
346
- result = @connection.query(sql)
347
- affected_rows = @connection.affected_rows
348
-
349
- if result
350
- types = {}
351
- fields = []
352
- result.fetch_fields.each { |field|
353
- field_name = field.name
354
- fields << field_name
355
-
356
- if field.decimals > 0
357
- types[field_name] = Type::Decimal.new
358
- else
359
- types[field_name] = Fields.find_type field
360
- end
361
- }
362
-
363
- result_set = ActiveRecord::Result.new(fields, result.to_a, types)
364
- result.free
365
- else
366
- result_set = ActiveRecord::Result.new([], [])
367
- end
368
-
369
- [result_set, affected_rows]
370
- end
371
- end
372
-
373
- def execute_and_free(sql, name = nil) # :nodoc:
374
- result = execute(sql, name)
375
- ret = yield result
376
- result.free
377
- ret
378
- end
379
-
380
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
381
- super sql, name
382
- id_value || @connection.insert_id
383
- end
384
- alias :create :insert_sql
385
-
386
- def exec_delete(sql, name, binds) # :nodoc:
387
- affected_rows = 0
388
-
389
- exec_query(sql, name, binds) do |n|
390
- affected_rows = n
391
- end
392
-
393
- affected_rows
394
- end
395
- alias :exec_update :exec_delete
396
-
397
- def begin_db_transaction #:nodoc:
398
- exec_query "BEGIN"
399
- end
400
-
401
- private
402
-
403
- def exec_stmt(sql, name, binds)
404
- cache = {}
405
- type_casted_binds = binds.map { |col, val|
406
- [col, type_cast(val, col)]
407
- }
408
-
409
- log(sql, name, type_casted_binds) do
410
- if binds.empty?
411
- stmt = @connection.prepare(sql)
412
- else
413
- cache = @statements[sql] ||= {
414
- :stmt => @connection.prepare(sql)
415
- }
416
- stmt = cache[:stmt]
417
- end
418
-
419
- begin
420
- stmt.execute(*type_casted_binds.map { |_, val| val })
421
- rescue Mysql::Error => e
422
- # Older versions of MySQL leave the prepared statement in a bad
423
- # place when an error occurs. To support older MySQL versions, we
424
- # need to close the statement and delete the statement from the
425
- # cache.
426
- stmt.close
427
- @statements.delete sql
428
- raise e
429
- end
430
-
431
- cols = nil
432
- if metadata = stmt.result_metadata
433
- cols = cache[:cols] ||= metadata.fetch_fields.map { |field|
434
- field.name
435
- }
436
- metadata.free
437
- end
438
-
439
- result_set = ActiveRecord::Result.new(cols, stmt.to_a) if cols
440
- affected_rows = stmt.affected_rows
441
-
442
- stmt.free_result
443
- stmt.close if binds.empty?
444
-
445
- [result_set, affected_rows]
446
- end
447
- end
448
-
449
- def connect
450
- encoding = @config[:encoding]
451
- if encoding
452
- @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
453
- end
454
-
455
- if @config[:sslca] || @config[:sslkey]
456
- @connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher])
457
- end
458
-
459
- @connection.options(Mysql::OPT_CONNECT_TIMEOUT, @config[:connect_timeout]) if @config[:connect_timeout]
460
- @connection.options(Mysql::OPT_READ_TIMEOUT, @config[:read_timeout]) if @config[:read_timeout]
461
- @connection.options(Mysql::OPT_WRITE_TIMEOUT, @config[:write_timeout]) if @config[:write_timeout]
462
-
463
- @connection.real_connect(*@connection_options)
464
-
465
- # reconnect must be set after real_connect is called, because real_connect sets it to false internally
466
- @connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=)
467
-
468
- configure_connection
469
- end
470
-
471
- # Many Rails applications monkey-patch a replacement of the configure_connection method
472
- # and don't call 'super', so leave this here even though it looks superfluous.
473
- def configure_connection
474
- super
475
- end
476
-
477
- def select(sql, name = nil, binds = [])
478
- @connection.query_with_result = true
479
- rows = super
480
- @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
481
- rows
482
- end
483
-
484
- # Returns the full version of the connected MySQL server.
485
- def full_version
486
- @full_version ||= @connection.server_info
487
- end
488
-
489
- def set_field_encoding field_name
490
- field_name.force_encoding(client_encoding)
491
- if internal_enc = Encoding.default_internal
492
- field_name = field_name.encode!(internal_enc)
493
- end
494
- field_name
495
- end
496
- end
497
- end
498
- end