sequel 3.21.0 → 3.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. data/CHANGELOG +485 -3
  2. data/README.rdoc +20 -6
  3. data/Rakefile +37 -19
  4. data/bin/sequel +1 -5
  5. data/doc/association_basics.rdoc +249 -43
  6. data/doc/dataset_basics.rdoc +4 -4
  7. data/doc/dataset_filtering.rdoc +8 -0
  8. data/doc/mass_assignment.rdoc +54 -0
  9. data/doc/migration.rdoc +15 -538
  10. data/doc/model_hooks.rdoc +72 -27
  11. data/doc/opening_databases.rdoc +89 -50
  12. data/doc/prepared_statements.rdoc +40 -13
  13. data/doc/reflection.rdoc +8 -2
  14. data/doc/release_notes/3.22.0.txt +39 -0
  15. data/doc/release_notes/3.23.0.txt +172 -0
  16. data/doc/release_notes/3.24.0.txt +420 -0
  17. data/doc/release_notes/3.25.0.txt +88 -0
  18. data/doc/release_notes/3.26.0.txt +88 -0
  19. data/doc/release_notes/3.27.0.txt +82 -0
  20. data/doc/release_notes/3.28.0.txt +304 -0
  21. data/doc/release_notes/3.29.0.txt +459 -0
  22. data/doc/release_notes/3.30.0.txt +135 -0
  23. data/doc/release_notes/3.31.0.txt +146 -0
  24. data/doc/schema_modification.rdoc +547 -0
  25. data/doc/sharding.rdoc +7 -1
  26. data/doc/testing.rdoc +129 -0
  27. data/doc/transactions.rdoc +137 -0
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  30. data/lib/sequel/adapters/ado.rb +40 -18
  31. data/lib/sequel/adapters/amalgalite.rb +17 -9
  32. data/lib/sequel/adapters/db2.rb +175 -86
  33. data/lib/sequel/adapters/dbi.rb +15 -15
  34. data/lib/sequel/adapters/do/mysql.rb +5 -7
  35. data/lib/sequel/adapters/do/postgres.rb +0 -5
  36. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/do.rb +17 -36
  38. data/lib/sequel/adapters/firebird.rb +27 -208
  39. data/lib/sequel/adapters/ibmdb.rb +448 -0
  40. data/lib/sequel/adapters/informix.rb +6 -23
  41. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  42. data/lib/sequel/adapters/jdbc/db2.rb +45 -0
  43. data/lib/sequel/adapters/jdbc/derby.rb +247 -0
  44. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  45. data/lib/sequel/adapters/jdbc/h2.rb +56 -29
  46. data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
  47. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  48. data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
  49. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  50. data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
  51. data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
  52. data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
  53. data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
  54. data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
  55. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  56. data/lib/sequel/adapters/jdbc.rb +231 -78
  57. data/lib/sequel/adapters/mock.rb +335 -0
  58. data/lib/sequel/adapters/mysql.rb +82 -184
  59. data/lib/sequel/adapters/mysql2.rb +26 -25
  60. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  61. data/lib/sequel/adapters/odbc/mssql.rb +1 -6
  62. data/lib/sequel/adapters/odbc.rb +28 -9
  63. data/lib/sequel/adapters/openbase.rb +3 -5
  64. data/lib/sequel/adapters/oracle.rb +351 -53
  65. data/lib/sequel/adapters/postgres.rb +194 -33
  66. data/lib/sequel/adapters/shared/access.rb +32 -9
  67. data/lib/sequel/adapters/shared/db2.rb +321 -0
  68. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  69. data/lib/sequel/adapters/shared/informix.rb +53 -0
  70. data/lib/sequel/adapters/shared/mssql.rb +231 -106
  71. data/lib/sequel/adapters/shared/mysql.rb +181 -63
  72. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +231 -41
  74. data/lib/sequel/adapters/shared/postgres.rb +214 -82
  75. data/lib/sequel/adapters/shared/progress.rb +4 -7
  76. data/lib/sequel/adapters/shared/sqlite.rb +201 -57
  77. data/lib/sequel/adapters/sqlite.rb +29 -21
  78. data/lib/sequel/adapters/swift/mysql.rb +12 -7
  79. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  80. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  81. data/lib/sequel/adapters/swift.rb +5 -5
  82. data/lib/sequel/adapters/tinytds.rb +160 -19
  83. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  84. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  85. data/lib/sequel/ast_transformer.rb +190 -0
  86. data/lib/sequel/connection_pool/threaded.rb +3 -2
  87. data/lib/sequel/connection_pool.rb +1 -1
  88. data/lib/sequel/core.rb +46 -5
  89. data/lib/sequel/database/connecting.rb +5 -6
  90. data/lib/sequel/database/dataset.rb +4 -4
  91. data/lib/sequel/database/dataset_defaults.rb +59 -1
  92. data/lib/sequel/database/logging.rb +1 -1
  93. data/lib/sequel/database/misc.rb +104 -19
  94. data/lib/sequel/database/query.rb +153 -58
  95. data/lib/sequel/database/schema_generator.rb +17 -7
  96. data/lib/sequel/database/schema_methods.rb +59 -29
  97. data/lib/sequel/dataset/actions.rb +231 -76
  98. data/lib/sequel/dataset/features.rb +91 -8
  99. data/lib/sequel/dataset/graph.rb +38 -11
  100. data/lib/sequel/dataset/misc.rb +50 -23
  101. data/lib/sequel/dataset/mutation.rb +5 -6
  102. data/lib/sequel/dataset/prepared_statements.rb +48 -27
  103. data/lib/sequel/dataset/query.rb +236 -43
  104. data/lib/sequel/dataset/sql.rb +665 -253
  105. data/lib/sequel/dataset.rb +8 -0
  106. data/lib/sequel/exceptions.rb +4 -0
  107. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  108. data/lib/sequel/extensions/migration.rb +6 -4
  109. data/lib/sequel/extensions/named_timezones.rb +5 -0
  110. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  111. data/lib/sequel/extensions/to_dot.rb +95 -83
  112. data/lib/sequel/model/associations.rb +1020 -337
  113. data/lib/sequel/model/base.rb +414 -132
  114. data/lib/sequel/model/errors.rb +1 -1
  115. data/lib/sequel/model/exceptions.rb +5 -1
  116. data/lib/sequel/model.rb +15 -8
  117. data/lib/sequel/plugins/association_pks.rb +22 -4
  118. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  119. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  120. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  121. data/lib/sequel/plugins/force_encoding.rb +6 -6
  122. data/lib/sequel/plugins/identity_map.rb +114 -7
  123. data/lib/sequel/plugins/many_through_many.rb +65 -7
  124. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  125. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  126. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  127. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  128. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  129. data/lib/sequel/plugins/serialization.rb +88 -44
  130. data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
  131. data/lib/sequel/plugins/sharding.rb +21 -54
  132. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  133. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  134. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  135. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  136. data/lib/sequel/sql.rb +109 -52
  137. data/lib/sequel/timezones.rb +57 -38
  138. data/lib/sequel/version.rb +1 -1
  139. data/spec/adapters/db2_spec.rb +146 -0
  140. data/spec/adapters/mssql_spec.rb +111 -29
  141. data/spec/adapters/mysql_spec.rb +135 -123
  142. data/spec/adapters/oracle_spec.rb +49 -77
  143. data/spec/adapters/postgres_spec.rb +267 -78
  144. data/spec/adapters/spec_helper.rb +6 -5
  145. data/spec/adapters/sqlite_spec.rb +35 -21
  146. data/spec/core/connection_pool_spec.rb +71 -92
  147. data/spec/core/core_sql_spec.rb +21 -30
  148. data/spec/core/database_spec.rb +788 -512
  149. data/spec/core/dataset_spec.rb +1073 -1053
  150. data/spec/core/expression_filters_spec.rb +159 -42
  151. data/spec/core/mock_adapter_spec.rb +419 -0
  152. data/spec/core/object_graph_spec.rb +86 -114
  153. data/spec/core/schema_generator_spec.rb +3 -3
  154. data/spec/core/schema_spec.rb +298 -38
  155. data/spec/core/spec_helper.rb +6 -48
  156. data/spec/extensions/association_autoreloading_spec.rb +1 -10
  157. data/spec/extensions/association_dependencies_spec.rb +2 -12
  158. data/spec/extensions/association_pks_spec.rb +66 -32
  159. data/spec/extensions/caching_spec.rb +23 -50
  160. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  161. data/spec/extensions/columns_introspection_spec.rb +91 -0
  162. data/spec/extensions/composition_spec.rb +18 -13
  163. data/spec/extensions/dataset_associations_spec.rb +199 -0
  164. data/spec/extensions/defaults_setter_spec.rb +64 -0
  165. data/spec/extensions/hook_class_methods_spec.rb +65 -91
  166. data/spec/extensions/identity_map_spec.rb +114 -22
  167. data/spec/extensions/instance_filters_spec.rb +11 -21
  168. data/spec/extensions/instance_hooks_spec.rb +53 -0
  169. data/spec/extensions/json_serializer_spec.rb +4 -5
  170. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  171. data/spec/extensions/list_spec.rb +17 -39
  172. data/spec/extensions/many_through_many_spec.rb +283 -250
  173. data/spec/extensions/migration_spec.rb +35 -32
  174. data/spec/extensions/named_timezones_spec.rb +23 -3
  175. data/spec/extensions/nested_attributes_spec.rb +97 -88
  176. data/spec/extensions/optimistic_locking_spec.rb +9 -20
  177. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  178. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  179. data/spec/extensions/prepared_statements_spec.rb +53 -0
  180. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  181. data/spec/extensions/pretty_table_spec.rb +1 -6
  182. data/spec/extensions/rcte_tree_spec.rb +41 -43
  183. data/spec/extensions/schema_dumper_spec.rb +5 -8
  184. data/spec/extensions/schema_spec.rb +13 -21
  185. data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
  186. data/spec/extensions/serialization_spec.rb +72 -43
  187. data/spec/extensions/sharding_spec.rb +66 -140
  188. data/spec/extensions/single_table_inheritance_spec.rb +18 -29
  189. data/spec/extensions/spec_helper.rb +13 -61
  190. data/spec/extensions/sql_expr_spec.rb +20 -60
  191. data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
  192. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  193. data/spec/extensions/timestamps_spec.rb +6 -6
  194. data/spec/extensions/to_dot_spec.rb +4 -7
  195. data/spec/extensions/touch_spec.rb +13 -14
  196. data/spec/extensions/tree_spec.rb +11 -26
  197. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  198. data/spec/extensions/update_primary_key_spec.rb +30 -24
  199. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  200. data/spec/extensions/validation_helpers_spec.rb +16 -35
  201. data/spec/extensions/xml_serializer_spec.rb +16 -4
  202. data/spec/integration/associations_test.rb +537 -21
  203. data/spec/integration/database_test.rb +4 -2
  204. data/spec/integration/dataset_test.rb +461 -65
  205. data/spec/integration/eager_loader_test.rb +19 -21
  206. data/spec/integration/model_test.rb +80 -1
  207. data/spec/integration/plugin_test.rb +304 -116
  208. data/spec/integration/prepared_statement_test.rb +212 -122
  209. data/spec/integration/schema_test.rb +161 -30
  210. data/spec/integration/spec_helper.rb +39 -30
  211. data/spec/integration/timezone_test.rb +38 -12
  212. data/spec/integration/transaction_test.rb +172 -5
  213. data/spec/integration/type_test.rb +17 -3
  214. data/spec/model/association_reflection_spec.rb +201 -7
  215. data/spec/model/associations_spec.rb +865 -662
  216. data/spec/model/base_spec.rb +275 -95
  217. data/spec/model/dataset_methods_spec.rb +7 -27
  218. data/spec/model/eager_loading_spec.rb +677 -676
  219. data/spec/model/hooks_spec.rb +309 -67
  220. data/spec/model/model_spec.rb +222 -168
  221. data/spec/model/plugins_spec.rb +24 -13
  222. data/spec/model/record_spec.rb +381 -218
  223. data/spec/model/spec_helper.rb +13 -71
  224. data/spec/model/validations_spec.rb +11 -0
  225. metadata +115 -73
@@ -1,10 +1,13 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that set defaults for created datasets
4
+ # :section: 5 - Methods that set defaults for created datasets
5
5
  # This methods change the default behavior of this database's datasets.
6
6
  # ---------------------
7
7
 
8
+ # The default class to use for datasets
9
+ DatasetClass = Sequel::Dataset
10
+
8
11
  # The identifier input method to use by default
9
12
  @@identifier_input_method = nil
10
13
 
@@ -42,9 +45,59 @@ module Sequel
42
45
  @@quote_identifiers = value
43
46
  end
44
47
 
48
+ # The class to use for creating datasets. Should respond to
49
+ # new with the Database argument as the first argument, and
50
+ # an optional options hash.
51
+ attr_reader :dataset_class
52
+
45
53
  # The default schema to use, generally should be nil.
46
54
  attr_accessor :default_schema
47
55
 
56
+ # If the database has any dataset modules associated with it,
57
+ # use a subclass of the given class that includes the modules
58
+ # as the dataset class.
59
+ def dataset_class=(c)
60
+ unless @dataset_modules.empty?
61
+ c = Class.new(c)
62
+ @dataset_modules.each{|m| c.send(:include, m)}
63
+ end
64
+ @dataset_class = c
65
+ end
66
+
67
+ # Equivalent to extending all datasets produced by the database with a
68
+ # module. What it actually does is use a subclass of the current dataset_class
69
+ # as the new dataset_class, and include the module in the subclass.
70
+ # Instead of a module, you can provide a block that is used to create an
71
+ # anonymous module.
72
+ #
73
+ # This allows you to override any of the dataset methods even if they are
74
+ # defined directly on the dataset class that this Database object uses.
75
+ #
76
+ # Examples:
77
+ #
78
+ # # Introspec columns for all of DB's datasets
79
+ # DB.extend_datasets(Sequel::ColumnsIntrospection)
80
+ #
81
+ # # Trace all SELECT queries by printing the SQL and the full backtrace
82
+ # DB.extend_datasets do
83
+ # def fetch_rows(sql)
84
+ # puts sql
85
+ # puts caller
86
+ # super
87
+ # end
88
+ # end
89
+ def extend_datasets(mod=nil, &block)
90
+ raise(Error, "must provide either mod or block, not both") if mod && block
91
+ mod = Module.new(&block) if block
92
+ if @dataset_modules.empty?
93
+ @dataset_modules = [mod]
94
+ @dataset_class = Class.new(@dataset_class)
95
+ else
96
+ @dataset_modules << mod
97
+ end
98
+ @dataset_class.send(:include, mod)
99
+ end
100
+
48
101
  # The method to call on identifiers going into the database
49
102
  def identifier_input_method
50
103
  case @identifier_input_method
@@ -109,6 +162,11 @@ module Sequel
109
162
 
110
163
  private
111
164
 
165
+ # The default dataset class to use for the database
166
+ def dataset_class_default
167
+ self.class.const_get(:DatasetClass)
168
+ end
169
+
112
170
  # The default value for default_schema.
113
171
  def default_schema_default
114
172
  nil
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods relating to logging
4
+ # :section: 6 - Methods relating to logging
5
5
  # This methods affect relating to the logging of executed SQL.
6
6
  # ---------------------
7
7
 
@@ -1,13 +1,13 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Miscellaneous methods
4
+ # :section: 7 - Miscellaneous methods
5
5
  # These methods don't fit neatly into another category.
6
6
  # ---------------------
7
7
 
8
8
  # Converts a uri to an options hash. These options are then passed
9
9
  # to a newly created database object.
10
- def self.uri_to_options(uri) # :nodoc:
10
+ def self.uri_to_options(uri)
11
11
  { :user => uri.user,
12
12
  :password => uri.password,
13
13
  :host => uri.host,
@@ -19,6 +19,9 @@ module Sequel
19
19
  # The options hash for this database
20
20
  attr_reader :opts
21
21
 
22
+ # Set the timezone to use for this database, overridding <tt>Sequel.database_timezone</tt>.
23
+ attr_writer :timezone
24
+
22
25
  # Constructs a new instance of a database connection with the specified
23
26
  # options hash.
24
27
  #
@@ -50,15 +53,50 @@ module Sequel
50
53
  @schemas = {}
51
54
  @default_schema = @opts.fetch(:default_schema, default_schema_default)
52
55
  @prepared_statements = {}
53
- @transactions = []
56
+ @transactions = {}
54
57
  @identifier_input_method = nil
55
58
  @identifier_output_method = nil
56
59
  @quote_identifiers = nil
60
+ @timezone = nil
61
+ @dataset_class = dataset_class_default
62
+ @dataset_modules = []
57
63
  self.sql_log_level = @opts[:sql_log_level] ? @opts[:sql_log_level].to_sym : :info
58
64
  @pool = ConnectionPool.get_pool(@opts, &block)
59
65
 
60
66
  ::Sequel::DATABASES.push(self)
61
67
  end
68
+
69
+ # If a transaction is not currently in process, yield to the block immediately.
70
+ # Otherwise, add the block to the list of blocks to call after the currently
71
+ # in progress transaction commits (and only if it commits).
72
+ # Options:
73
+ # :server :: The server/shard to use.
74
+ def after_commit(opts={}, &block)
75
+ raise Error, "must provide block to after_commit" unless block
76
+ synchronize(opts[:server]) do |conn|
77
+ if h = @transactions[conn]
78
+ raise Error, "cannot call after_commit in a prepared transaction" if h[:prepare]
79
+ (h[:after_commit] ||= []) << block
80
+ else
81
+ yield
82
+ end
83
+ end
84
+ end
85
+
86
+ # If a transaction is not currently in progress, ignore the block.
87
+ # Otherwise, add the block to the list of the blocks to call after the currently
88
+ # in progress transaction rolls back (and only if it rolls back).
89
+ # Options:
90
+ # :server :: The server/shard to use.
91
+ def after_rollback(opts={}, &block)
92
+ raise Error, "must provide block to after_rollback" unless block
93
+ synchronize(opts[:server]) do |conn|
94
+ if h = @transactions[conn]
95
+ raise Error, "cannot call after_rollback in a prepared transaction" if h[:prepare]
96
+ (h[:after_rollback] ||= []) << block
97
+ end
98
+ end
99
+ end
62
100
 
63
101
  # Cast the given type to a literal type
64
102
  #
@@ -68,6 +106,20 @@ module Sequel
68
106
  type_literal(:type=>type)
69
107
  end
70
108
 
109
+ # Convert the given timestamp from the application's timezone,
110
+ # to the databases's timezone or the default database timezone if
111
+ # the database does not have a timezone.
112
+ def from_application_timestamp(v)
113
+ Sequel.convert_output_timestamp(v, timezone)
114
+ end
115
+
116
+ # Return true if already in a transaction given the options,
117
+ # false otherwise. Respects the :server option for selecting
118
+ # a shard.
119
+ def in_transaction?(opts={})
120
+ synchronize(opts[:server]){|conn| !!@transactions[conn]}
121
+ end
122
+
71
123
  # Returns a string representation of the database object including the
72
124
  # class name and the connection URI (or the opts if the URI
73
125
  # cannot be constructed).
@@ -90,6 +142,12 @@ module Sequel
90
142
  {:primary_key => true, :type => Integer, :auto_increment => true}
91
143
  end
92
144
 
145
+ # Whether the database supports CREATE TABLE IF NOT EXISTS syntax,
146
+ # false by default.
147
+ def supports_create_table_if_not_exists?
148
+ false
149
+ end
150
+
93
151
  # Whether the database and adapter support prepared transactions
94
152
  # (two-phase commit), false by default.
95
153
  def supports_prepared_transactions?
@@ -106,6 +164,18 @@ module Sequel
106
164
  false
107
165
  end
108
166
 
167
+ # The timezone to use for this database, defaulting to <tt>Sequel.database_timezone</tt>.
168
+ def timezone
169
+ @timezone || Sequel.database_timezone
170
+ end
171
+
172
+ # Convert the given timestamp to the application's timezone,
173
+ # from the databases's timezone or the default database timezone if
174
+ # the database does not have a timezone.
175
+ def to_application_timestamp(v)
176
+ Sequel.convert_timestamp(v, timezone)
177
+ end
178
+
109
179
  # Typecast the value to the given column_type. Calls
110
180
  # typecast_value_#{column_type} if the method exists,
111
181
  # otherwise returns the value.
@@ -175,12 +245,17 @@ module Sequel
175
245
  def database_error_classes
176
246
  []
177
247
  end
248
+
249
+ # Return true if exception represents a disconnect error, false otherwise.
250
+ def disconnect_error?(exception, opts)
251
+ opts[:disconnect]
252
+ end
178
253
 
179
254
  # Convert the given exception to a DatabaseError, keeping message
180
255
  # and traceback.
181
256
  def raise_error(exception, opts={})
182
257
  if !opts[:classes] || Array(opts[:classes]).any?{|c| exception.is_a?(c)}
183
- raise Sequel.convert_exception_class(exception, opts[:disconnect] ? DatabaseDisconnectError : DatabaseError)
258
+ raise Sequel.convert_exception_class(exception, disconnect_error?(exception, opts) ? DatabaseDisconnectError : DatabaseError)
184
259
  else
185
260
  raise exception
186
261
  end
@@ -194,7 +269,7 @@ module Sequel
194
269
  # Typecast the value to true, false, or nil
195
270
  def typecast_value_boolean(value)
196
271
  case value
197
- when false, 0, "0", /\Af(alse)?\z/i
272
+ when false, 0, "0", /\Af(alse)?\z/i, /\Ano?\z/i
198
273
  false
199
274
  else
200
275
  blank_object?(value) ? nil : true
@@ -204,10 +279,10 @@ module Sequel
204
279
  # Typecast the value to a Date
205
280
  def typecast_value_date(value)
206
281
  case value
207
- when Date
208
- value
209
282
  when DateTime, Time
210
283
  Date.new(value.year, value.month, value.day)
284
+ when Date
285
+ value
211
286
  when String
212
287
  Sequel.string_to_date(value)
213
288
  when Hash
@@ -219,12 +294,7 @@ module Sequel
219
294
 
220
295
  # Typecast the value to a DateTime or Time depending on Sequel.datetime_class
221
296
  def typecast_value_datetime(value)
222
- klass = Sequel.datetime_class
223
- if value.is_a?(Hash)
224
- klass.send(klass == Time ? :mktime : :new, *[:year, :month, :day, :hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
225
- else
226
- Sequel.typecast_to_application_timestamp(value)
227
- end
297
+ Sequel.typecast_to_application_timestamp(value)
228
298
  end
229
299
 
230
300
  # Typecast the value to a BigDecimal
@@ -244,9 +314,21 @@ module Sequel
244
314
  Float(value)
245
315
  end
246
316
 
247
- # Typecast the value to an Integer
248
- def typecast_value_integer(value)
249
- Integer(value)
317
+ # Used for checking/removing leading zeroes from strings so they don't get
318
+ # interpreted as octal.
319
+ LEADING_ZERO_RE = /\A0+(\d)/.freeze
320
+ if RUBY_VERSION >= '1.9'
321
+ # Typecast the value to an Integer
322
+ def typecast_value_integer(value)
323
+ (value.is_a?(String) && value =~ LEADING_ZERO_RE) ? Integer(value, 10) : Integer(value)
324
+ end
325
+ else
326
+ # Replacement string when replacing leading zeroes.
327
+ LEADING_ZERO_REP = "\\1".freeze
328
+ # Typecast the value to an Integer
329
+ def typecast_value_integer(value)
330
+ Integer(value.is_a?(String) ? value.sub(LEADING_ZERO_RE, LEADING_ZERO_REP) : value)
331
+ end
250
332
  end
251
333
 
252
334
  # Typecast the value to a String
@@ -258,12 +340,15 @@ module Sequel
258
340
  def typecast_value_time(value)
259
341
  case value
260
342
  when Time
261
- value
343
+ if value.is_a?(SQLTime)
344
+ value
345
+ else
346
+ SQLTime.create(value.hour, value.min, value.sec, value.respond_to?(:nsec) ? value.nsec/1000.0 : value.usec)
347
+ end
262
348
  when String
263
349
  Sequel.string_to_time(value)
264
350
  when Hash
265
- t = Time.now
266
- Time.mktime(t.year, t.month, t.day, *[:hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
351
+ SQLTime.create(*[:hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
267
352
  else
268
353
  raise Sequel::InvalidValue, "invalid value for Time: #{value.inspect}"
269
354
  end