activerecord 4.2.11.3 → 5.0.0.1

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 (246) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1281 -1204
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -8
  5. data/examples/performance.rb +2 -3
  6. data/examples/simple.rb +0 -1
  7. data/lib/active_record/aggregations.rb +35 -24
  8. data/lib/active_record/association_relation.rb +3 -3
  9. data/lib/active_record/associations/alias_tracker.rb +19 -16
  10. data/lib/active_record/associations/association.rb +11 -9
  11. data/lib/active_record/associations/association_scope.rb +73 -102
  12. data/lib/active_record/associations/belongs_to_association.rb +21 -32
  13. data/lib/active_record/associations/builder/association.rb +28 -34
  14. data/lib/active_record/associations/builder/belongs_to.rb +43 -18
  15. data/lib/active_record/associations/builder/collection_association.rb +7 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +14 -11
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +11 -6
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -10
  20. data/lib/active_record/associations/collection_association.rb +49 -41
  21. data/lib/active_record/associations/collection_proxy.rb +67 -27
  22. data/lib/active_record/associations/foreign_association.rb +1 -1
  23. data/lib/active_record/associations/has_many_association.rb +20 -71
  24. data/lib/active_record/associations/has_many_through_association.rb +8 -47
  25. data/lib/active_record/associations/has_one_association.rb +12 -5
  26. data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
  27. data/lib/active_record/associations/join_dependency.rb +29 -19
  28. data/lib/active_record/associations/preloader/association.rb +46 -52
  29. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  30. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  31. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  32. data/lib/active_record/associations/preloader/through_association.rb +27 -14
  33. data/lib/active_record/associations/preloader.rb +14 -4
  34. data/lib/active_record/associations/singular_association.rb +7 -1
  35. data/lib/active_record/associations/through_association.rb +11 -3
  36. data/lib/active_record/associations.rb +317 -209
  37. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  38. data/lib/active_record/attribute.rb +68 -18
  39. data/lib/active_record/attribute_assignment.rb +19 -140
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  42. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  43. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  44. data/lib/active_record/attribute_methods/query.rb +2 -2
  45. data/lib/active_record/attribute_methods/read.rb +31 -59
  46. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
  48. data/lib/active_record/attribute_methods/write.rb +13 -37
  49. data/lib/active_record/attribute_methods.rb +76 -47
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set/builder.rb +6 -4
  52. data/lib/active_record/attribute_set.rb +30 -3
  53. data/lib/active_record/attributes.rb +199 -81
  54. data/lib/active_record/autosave_association.rb +49 -16
  55. data/lib/active_record/base.rb +32 -23
  56. data/lib/active_record/callbacks.rb +39 -43
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +20 -8
  59. data/lib/active_record/collection_cache_key.rb +40 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +452 -182
  61. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  62. data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -61
  63. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -2
  64. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -10
  65. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  66. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
  67. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -185
  68. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
  69. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +380 -141
  70. data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
  71. data/lib/active_record/connection_adapters/abstract_adapter.rb +141 -59
  72. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -370
  73. data/lib/active_record/connection_adapters/column.rb +28 -43
  74. data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
  75. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  78. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  79. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  81. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  82. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  83. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +29 -166
  85. data/lib/active_record/connection_adapters/postgresql/column.rb +5 -10
  86. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +10 -72
  87. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +27 -57
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  98. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
  100. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  102. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  105. data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -18
  106. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  107. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  108. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  109. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +234 -148
  110. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  111. data/lib/active_record/connection_adapters/postgresql_adapter.rb +248 -160
  112. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  113. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  114. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  115. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  116. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  117. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +149 -192
  118. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  119. data/lib/active_record/connection_handling.rb +37 -14
  120. data/lib/active_record/core.rb +89 -107
  121. data/lib/active_record/counter_cache.rb +13 -24
  122. data/lib/active_record/dynamic_matchers.rb +1 -20
  123. data/lib/active_record/enum.rb +113 -76
  124. data/lib/active_record/errors.rb +87 -48
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +1 -1
  127. data/lib/active_record/fixture_set/file.rb +26 -5
  128. data/lib/active_record/fixtures.rb +76 -40
  129. data/lib/active_record/gem_version.rb +4 -4
  130. data/lib/active_record/inheritance.rb +32 -40
  131. data/lib/active_record/integration.rb +4 -4
  132. data/lib/active_record/internal_metadata.rb +56 -0
  133. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  134. data/lib/active_record/locale/en.yml +3 -2
  135. data/lib/active_record/locking/optimistic.rb +15 -15
  136. data/lib/active_record/locking/pessimistic.rb +1 -1
  137. data/lib/active_record/log_subscriber.rb +43 -21
  138. data/lib/active_record/migration/command_recorder.rb +59 -18
  139. data/lib/active_record/migration/compatibility.rb +126 -0
  140. data/lib/active_record/migration.rb +363 -133
  141. data/lib/active_record/model_schema.rb +129 -41
  142. data/lib/active_record/nested_attributes.rb +58 -29
  143. data/lib/active_record/null_relation.rb +16 -8
  144. data/lib/active_record/persistence.rb +121 -80
  145. data/lib/active_record/query_cache.rb +15 -18
  146. data/lib/active_record/querying.rb +10 -9
  147. data/lib/active_record/railtie.rb +23 -16
  148. data/lib/active_record/railties/controller_runtime.rb +1 -1
  149. data/lib/active_record/railties/databases.rake +69 -46
  150. data/lib/active_record/readonly_attributes.rb +1 -1
  151. data/lib/active_record/reflection.rb +282 -115
  152. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  153. data/lib/active_record/relation/batches.rb +139 -34
  154. data/lib/active_record/relation/calculations.rb +79 -108
  155. data/lib/active_record/relation/delegation.rb +7 -20
  156. data/lib/active_record/relation/finder_methods.rb +163 -81
  157. data/lib/active_record/relation/from_clause.rb +32 -0
  158. data/lib/active_record/relation/merger.rb +16 -42
  159. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  160. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  161. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  162. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  163. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  165. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  166. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  167. data/lib/active_record/relation/predicate_builder.rb +120 -107
  168. data/lib/active_record/relation/query_attribute.rb +19 -0
  169. data/lib/active_record/relation/query_methods.rb +308 -244
  170. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  171. data/lib/active_record/relation/spawn_methods.rb +4 -7
  172. data/lib/active_record/relation/where_clause.rb +174 -0
  173. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  174. data/lib/active_record/relation.rb +176 -116
  175. data/lib/active_record/result.rb +4 -3
  176. data/lib/active_record/runtime_registry.rb +1 -1
  177. data/lib/active_record/sanitization.rb +95 -66
  178. data/lib/active_record/schema.rb +26 -22
  179. data/lib/active_record/schema_dumper.rb +62 -38
  180. data/lib/active_record/schema_migration.rb +11 -14
  181. data/lib/active_record/scoping/default.rb +23 -9
  182. data/lib/active_record/scoping/named.rb +49 -28
  183. data/lib/active_record/scoping.rb +32 -15
  184. data/lib/active_record/secure_token.rb +38 -0
  185. data/lib/active_record/serialization.rb +2 -4
  186. data/lib/active_record/statement_cache.rb +16 -14
  187. data/lib/active_record/store.rb +8 -3
  188. data/lib/active_record/suppressor.rb +58 -0
  189. data/lib/active_record/table_metadata.rb +68 -0
  190. data/lib/active_record/tasks/database_tasks.rb +57 -43
  191. data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
  192. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
  193. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  194. data/lib/active_record/timestamp.rb +20 -9
  195. data/lib/active_record/touch_later.rb +58 -0
  196. data/lib/active_record/transactions.rb +138 -56
  197. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  198. data/lib/active_record/type/date.rb +2 -45
  199. data/lib/active_record/type/date_time.rb +2 -49
  200. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  201. data/lib/active_record/type/internal/timezone.rb +15 -0
  202. data/lib/active_record/type/serialized.rb +15 -14
  203. data/lib/active_record/type/time.rb +10 -16
  204. data/lib/active_record/type/type_map.rb +4 -4
  205. data/lib/active_record/type.rb +66 -17
  206. data/lib/active_record/type_caster/connection.rb +29 -0
  207. data/lib/active_record/type_caster/map.rb +19 -0
  208. data/lib/active_record/type_caster.rb +7 -0
  209. data/lib/active_record/validations/absence.rb +23 -0
  210. data/lib/active_record/validations/associated.rb +10 -3
  211. data/lib/active_record/validations/length.rb +24 -0
  212. data/lib/active_record/validations/presence.rb +11 -12
  213. data/lib/active_record/validations/uniqueness.rb +30 -29
  214. data/lib/active_record/validations.rb +33 -32
  215. data/lib/active_record.rb +8 -4
  216. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  217. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  218. data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
  219. data/lib/rails/generators/active_record/migration.rb +7 -0
  220. data/lib/rails/generators/active_record/model/model_generator.rb +32 -15
  221. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  222. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  223. metadata +60 -34
  224. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  225. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  226. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  227. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  228. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  229. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  230. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  231. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  232. data/lib/active_record/type/big_integer.rb +0 -13
  233. data/lib/active_record/type/binary.rb +0 -50
  234. data/lib/active_record/type/boolean.rb +0 -31
  235. data/lib/active_record/type/decimal.rb +0 -64
  236. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  237. data/lib/active_record/type/decorator.rb +0 -14
  238. data/lib/active_record/type/float.rb +0 -19
  239. data/lib/active_record/type/integer.rb +0 -59
  240. data/lib/active_record/type/mutable.rb +0 -16
  241. data/lib/active_record/type/numeric.rb +0 -36
  242. data/lib/active_record/type/string.rb +0 -40
  243. data/lib/active_record/type/text.rb +0 -11
  244. data/lib/active_record/type/time_value.rb +0 -38
  245. data/lib/active_record/type/unsigned_integer.rb +0 -15
  246. data/lib/active_record/type/value.rb +0 -110
@@ -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
@@ -1,93 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module ArrayParser # :nodoc:
5
-
6
- DOUBLE_QUOTE = '"'
7
- BACKSLASH = "\\"
8
- COMMA = ','
9
- BRACKET_OPEN = '{'
10
- BRACKET_CLOSE = '}'
11
-
12
- def parse_pg_array(string) # :nodoc:
13
- local_index = 0
14
- array = []
15
- while(local_index < string.length)
16
- case string[local_index]
17
- when BRACKET_OPEN
18
- local_index,array = parse_array_contents(array, string, local_index + 1)
19
- when BRACKET_CLOSE
20
- return array
21
- end
22
- local_index += 1
23
- end
24
-
25
- array
26
- end
27
-
28
- private
29
-
30
- def parse_array_contents(array, string, index)
31
- is_escaping = false
32
- is_quoted = false
33
- was_quoted = false
34
- current_item = ''
35
-
36
- local_index = index
37
- while local_index
38
- token = string[local_index]
39
- if is_escaping
40
- current_item << token
41
- is_escaping = false
42
- else
43
- if is_quoted
44
- case token
45
- when DOUBLE_QUOTE
46
- is_quoted = false
47
- was_quoted = true
48
- when BACKSLASH
49
- is_escaping = true
50
- else
51
- current_item << token
52
- end
53
- else
54
- case token
55
- when BACKSLASH
56
- is_escaping = true
57
- when COMMA
58
- add_item_to_array(array, current_item, was_quoted)
59
- current_item = ''
60
- was_quoted = false
61
- when DOUBLE_QUOTE
62
- is_quoted = true
63
- when BRACKET_OPEN
64
- internal_items = []
65
- local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
66
- array.push(internal_items)
67
- when BRACKET_CLOSE
68
- add_item_to_array(array, current_item, was_quoted)
69
- return local_index,array
70
- else
71
- current_item << token
72
- end
73
- end
74
- end
75
-
76
- local_index += 1
77
- end
78
- return local_index,array
79
- end
80
-
81
- def add_item_to_array(array, current_item, quoted)
82
- return if !quoted && current_item.length == 0
83
-
84
- if !quoted && current_item == 'NULL'
85
- array.push nil
86
- else
87
- array.push current_item
88
- end
89
- end
90
- end
91
- end
92
- end
93
- end
@@ -1,11 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module OID # :nodoc:
5
- class Date < Type::Date # :nodoc:
6
- include Infinity
7
- end
8
- end
9
- end
10
- end
11
- end
@@ -1,21 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module OID # :nodoc:
5
- class Float < Type::Float # :nodoc:
6
- include Infinity
7
-
8
- def cast_value(value)
9
- case value
10
- when ::Float then value
11
- when 'Infinity' then ::Float::INFINITY
12
- when '-Infinity' then -::Float::INFINITY
13
- when 'NaN' then ::Float::NAN
14
- else value.to_f
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,13 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module OID # :nodoc:
5
- module Infinity # :nodoc:
6
- def infinity(options = {})
7
- options[:negative] ? -::Float::INFINITY : ::Float::INFINITY
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module OID # :nodoc:
5
- class Integer < Type::Integer # :nodoc:
6
- include Infinity
7
- end
8
- end
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module OID # :nodoc:
5
- class Time < Type::Time # :nodoc:
6
- include Infinity
7
- end
8
- end
9
- end
10
- end
11
- end