sequel 3.21.0 → 3.36.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 (311) hide show
  1. data/CHANGELOG +855 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +23 -7
  4. data/Rakefile +42 -24
  5. data/bin/sequel +26 -8
  6. data/doc/active_record.rdoc +1 -0
  7. data/doc/advanced_associations.rdoc +171 -11
  8. data/doc/association_basics.rdoc +293 -43
  9. data/doc/dataset_basics.rdoc +5 -5
  10. data/doc/dataset_filtering.rdoc +8 -0
  11. data/doc/mass_assignment.rdoc +56 -0
  12. data/doc/migration.rdoc +85 -552
  13. data/doc/model_hooks.rdoc +78 -27
  14. data/doc/object_model.rdoc +541 -0
  15. data/doc/opening_databases.rdoc +97 -50
  16. data/doc/prepared_statements.rdoc +40 -14
  17. data/doc/querying.rdoc +28 -4
  18. data/doc/reflection.rdoc +30 -4
  19. data/doc/release_notes/3.22.0.txt +39 -0
  20. data/doc/release_notes/3.23.0.txt +172 -0
  21. data/doc/release_notes/3.24.0.txt +420 -0
  22. data/doc/release_notes/3.25.0.txt +88 -0
  23. data/doc/release_notes/3.26.0.txt +88 -0
  24. data/doc/release_notes/3.27.0.txt +82 -0
  25. data/doc/release_notes/3.28.0.txt +304 -0
  26. data/doc/release_notes/3.29.0.txt +459 -0
  27. data/doc/release_notes/3.30.0.txt +135 -0
  28. data/doc/release_notes/3.31.0.txt +146 -0
  29. data/doc/release_notes/3.32.0.txt +202 -0
  30. data/doc/release_notes/3.33.0.txt +157 -0
  31. data/doc/release_notes/3.34.0.txt +671 -0
  32. data/doc/release_notes/3.35.0.txt +144 -0
  33. data/doc/release_notes/3.36.0.txt +245 -0
  34. data/doc/schema_modification.rdoc +572 -0
  35. data/doc/sharding.rdoc +95 -3
  36. data/doc/testing.rdoc +129 -0
  37. data/doc/thread_safety.rdoc +17 -0
  38. data/doc/transactions.rdoc +137 -0
  39. data/doc/virtual_rows.rdoc +51 -2
  40. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  41. data/lib/sequel/adapters/ado.rb +40 -18
  42. data/lib/sequel/adapters/amalgalite.rb +17 -9
  43. data/lib/sequel/adapters/db2.rb +175 -86
  44. data/lib/sequel/adapters/dbi.rb +15 -15
  45. data/lib/sequel/adapters/do/mysql.rb +17 -11
  46. data/lib/sequel/adapters/do/postgres.rb +1 -57
  47. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  48. data/lib/sequel/adapters/do.rb +18 -36
  49. data/lib/sequel/adapters/firebird.rb +27 -208
  50. data/lib/sequel/adapters/ibmdb.rb +453 -0
  51. data/lib/sequel/adapters/informix.rb +6 -23
  52. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  53. data/lib/sequel/adapters/jdbc/db2.rb +47 -0
  54. data/lib/sequel/adapters/jdbc/derby.rb +287 -0
  55. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  56. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  57. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  58. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  59. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  61. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  62. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
  64. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  65. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  66. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  67. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  68. data/lib/sequel/adapters/jdbc.rb +265 -94
  69. data/lib/sequel/adapters/mock.rb +361 -0
  70. data/lib/sequel/adapters/mysql.rb +118 -222
  71. data/lib/sequel/adapters/mysql2.rb +58 -57
  72. data/lib/sequel/adapters/odbc/mssql.rb +15 -7
  73. data/lib/sequel/adapters/odbc.rb +28 -9
  74. data/lib/sequel/adapters/openbase.rb +3 -5
  75. data/lib/sequel/adapters/oracle.rb +349 -53
  76. data/lib/sequel/adapters/postgres.rb +356 -107
  77. data/lib/sequel/adapters/shared/access.rb +32 -9
  78. data/lib/sequel/adapters/shared/db2.rb +342 -0
  79. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  80. data/lib/sequel/adapters/shared/informix.rb +53 -0
  81. data/lib/sequel/adapters/shared/mssql.rb +335 -118
  82. data/lib/sequel/adapters/shared/mysql.rb +340 -76
  83. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  84. data/lib/sequel/adapters/shared/oracle.rb +243 -45
  85. data/lib/sequel/adapters/shared/postgres.rb +524 -279
  86. data/lib/sequel/adapters/shared/progress.rb +5 -8
  87. data/lib/sequel/adapters/shared/sqlite.rb +265 -89
  88. data/lib/sequel/adapters/sqlite.rb +101 -39
  89. data/lib/sequel/adapters/swift/mysql.rb +9 -12
  90. data/lib/sequel/adapters/swift/postgres.rb +9 -74
  91. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  92. data/lib/sequel/adapters/swift.rb +8 -7
  93. data/lib/sequel/adapters/tinytds.rb +161 -21
  94. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  95. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  96. data/lib/sequel/ast_transformer.rb +194 -0
  97. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  98. data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
  99. data/lib/sequel/connection_pool/single.rb +5 -0
  100. data/lib/sequel/connection_pool/threaded.rb +38 -14
  101. data/lib/sequel/connection_pool.rb +10 -2
  102. data/lib/sequel/core.rb +118 -11
  103. data/lib/sequel/database/connecting.rb +38 -28
  104. data/lib/sequel/database/dataset.rb +4 -4
  105. data/lib/sequel/database/dataset_defaults.rb +63 -2
  106. data/lib/sequel/database/logging.rb +7 -2
  107. data/lib/sequel/database/misc.rb +150 -46
  108. data/lib/sequel/database/query.rb +215 -65
  109. data/lib/sequel/database/schema_generator.rb +64 -20
  110. data/lib/sequel/database/schema_methods.rb +212 -54
  111. data/lib/sequel/dataset/actions.rb +322 -85
  112. data/lib/sequel/dataset/features.rb +96 -8
  113. data/lib/sequel/dataset/graph.rb +38 -11
  114. data/lib/sequel/dataset/misc.rb +50 -23
  115. data/lib/sequel/dataset/mutation.rb +12 -7
  116. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  117. data/lib/sequel/dataset/query.rb +237 -44
  118. data/lib/sequel/dataset/sql.rb +698 -278
  119. data/lib/sequel/dataset.rb +8 -0
  120. data/lib/sequel/exceptions.rb +4 -0
  121. data/lib/sequel/extensions/_pretty_table.rb +79 -0
  122. data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
  123. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  124. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
  125. data/lib/sequel/extensions/migration.rb +97 -11
  126. data/lib/sequel/extensions/named_timezones.rb +5 -0
  127. data/lib/sequel/extensions/null_dataset.rb +90 -0
  128. data/lib/sequel/extensions/pg_array.rb +460 -0
  129. data/lib/sequel/extensions/pg_array_ops.rb +220 -0
  130. data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
  131. data/lib/sequel/extensions/pg_hstore.rb +296 -0
  132. data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
  133. data/lib/sequel/extensions/pg_inet.rb +89 -0
  134. data/lib/sequel/extensions/pg_json.rb +178 -0
  135. data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
  136. data/lib/sequel/extensions/pretty_table.rb +5 -71
  137. data/lib/sequel/extensions/query.rb +1 -1
  138. data/lib/sequel/extensions/query_literals.rb +79 -0
  139. data/lib/sequel/extensions/schema_caching.rb +76 -0
  140. data/lib/sequel/extensions/schema_dumper.rb +251 -37
  141. data/lib/sequel/extensions/select_remove.rb +35 -0
  142. data/lib/sequel/extensions/server_block.rb +139 -0
  143. data/lib/sequel/extensions/sql_expr.rb +4 -110
  144. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  145. data/lib/sequel/extensions/to_dot.rb +95 -83
  146. data/lib/sequel/model/associations.rb +1187 -393
  147. data/lib/sequel/model/base.rb +578 -170
  148. data/lib/sequel/model/errors.rb +1 -1
  149. data/lib/sequel/model/exceptions.rb +5 -1
  150. data/lib/sequel/model/inflections.rb +1 -1
  151. data/lib/sequel/model.rb +30 -11
  152. data/lib/sequel/no_core_ext.rb +2 -0
  153. data/lib/sequel/plugins/active_model.rb +13 -1
  154. data/lib/sequel/plugins/association_pks.rb +22 -4
  155. data/lib/sequel/plugins/caching.rb +25 -18
  156. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  157. data/lib/sequel/plugins/composition.rb +44 -12
  158. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  159. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  160. data/lib/sequel/plugins/dirty.rb +214 -0
  161. data/lib/sequel/plugins/eager_each.rb +59 -0
  162. data/lib/sequel/plugins/force_encoding.rb +6 -6
  163. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  164. data/lib/sequel/plugins/identity_map.rb +123 -8
  165. data/lib/sequel/plugins/instance_filters.rb +10 -0
  166. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  167. data/lib/sequel/plugins/json_serializer.rb +58 -6
  168. data/lib/sequel/plugins/list.rb +12 -2
  169. data/lib/sequel/plugins/many_through_many.rb +79 -28
  170. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  171. data/lib/sequel/plugins/nested_attributes.rb +139 -63
  172. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  173. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  174. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  175. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  176. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  177. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  178. data/lib/sequel/plugins/schema.rb +7 -2
  179. data/lib/sequel/plugins/serialization.rb +98 -49
  180. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  181. data/lib/sequel/plugins/sharding.rb +21 -54
  182. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  183. data/lib/sequel/plugins/static_cache.rb +99 -0
  184. data/lib/sequel/plugins/subclasses.rb +10 -2
  185. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  186. data/lib/sequel/plugins/timestamps.rb +1 -1
  187. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  188. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  189. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  190. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  191. data/lib/sequel/sql.rb +526 -59
  192. data/lib/sequel/timezones.rb +57 -38
  193. data/lib/sequel/version.rb +1 -1
  194. data/spec/adapters/db2_spec.rb +146 -0
  195. data/spec/adapters/firebird_spec.rb +1 -1
  196. data/spec/adapters/mssql_spec.rb +142 -40
  197. data/spec/adapters/mysql_spec.rb +380 -234
  198. data/spec/adapters/oracle_spec.rb +67 -77
  199. data/spec/adapters/postgres_spec.rb +1050 -212
  200. data/spec/adapters/spec_helper.rb +8 -5
  201. data/spec/adapters/sqlite_spec.rb +139 -27
  202. data/spec/core/connection_pool_spec.rb +196 -93
  203. data/spec/core/database_spec.rb +879 -510
  204. data/spec/core/dataset_spec.rb +1415 -1086
  205. data/spec/core/expression_filters_spec.rb +554 -109
  206. data/spec/core/mock_adapter_spec.rb +449 -0
  207. data/spec/core/object_graph_spec.rb +86 -114
  208. data/spec/core/schema_generator_spec.rb +4 -4
  209. data/spec/core/schema_spec.rb +482 -38
  210. data/spec/core/spec_helper.rb +6 -48
  211. data/spec/extensions/active_model_spec.rb +13 -0
  212. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  213. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  214. data/spec/extensions/association_dependencies_spec.rb +15 -25
  215. data/spec/extensions/association_pks_spec.rb +66 -32
  216. data/spec/extensions/association_proxies_spec.rb +4 -4
  217. data/spec/extensions/caching_spec.rb +47 -51
  218. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  219. data/spec/extensions/columns_introspection_spec.rb +91 -0
  220. data/spec/extensions/composition_spec.rb +18 -13
  221. data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
  222. data/spec/extensions/dataset_associations_spec.rb +199 -0
  223. data/spec/extensions/defaults_setter_spec.rb +64 -0
  224. data/spec/extensions/dirty_spec.rb +155 -0
  225. data/spec/extensions/eager_each_spec.rb +34 -0
  226. data/spec/extensions/force_encoding_spec.rb +4 -2
  227. data/spec/extensions/hook_class_methods_spec.rb +69 -92
  228. data/spec/extensions/identity_map_spec.rb +131 -22
  229. data/spec/extensions/inflector_spec.rb +0 -4
  230. data/spec/extensions/instance_filters_spec.rb +11 -21
  231. data/spec/extensions/instance_hooks_spec.rb +72 -0
  232. data/spec/extensions/json_serializer_spec.rb +49 -6
  233. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  234. data/spec/extensions/list_spec.rb +48 -39
  235. data/spec/extensions/many_through_many_spec.rb +283 -250
  236. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  237. data/spec/extensions/migration_spec.rb +140 -35
  238. data/spec/extensions/named_timezones_spec.rb +29 -11
  239. data/spec/extensions/nested_attributes_spec.rb +251 -89
  240. data/spec/extensions/null_dataset_spec.rb +85 -0
  241. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  242. data/spec/extensions/pg_array_ops_spec.rb +105 -0
  243. data/spec/extensions/pg_array_spec.rb +196 -0
  244. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  245. data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
  246. data/spec/extensions/pg_hstore_spec.rb +195 -0
  247. data/spec/extensions/pg_inet_spec.rb +44 -0
  248. data/spec/extensions/pg_json_spec.rb +101 -0
  249. data/spec/extensions/pg_statement_cache_spec.rb +209 -0
  250. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  251. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  252. data/spec/extensions/prepared_statements_spec.rb +87 -0
  253. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  254. data/spec/extensions/pretty_table_spec.rb +7 -6
  255. data/spec/extensions/query_literals_spec.rb +168 -0
  256. data/spec/extensions/query_spec.rb +6 -0
  257. data/spec/extensions/rcte_tree_spec.rb +50 -43
  258. data/spec/extensions/schema_caching_spec.rb +41 -0
  259. data/spec/extensions/schema_dumper_spec.rb +429 -22
  260. data/spec/extensions/schema_spec.rb +25 -21
  261. data/spec/extensions/select_remove_spec.rb +38 -0
  262. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  263. data/spec/extensions/serialization_spec.rb +85 -43
  264. data/spec/extensions/server_block_spec.rb +90 -0
  265. data/spec/extensions/sharding_spec.rb +69 -143
  266. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  267. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  268. data/spec/extensions/spec_helper.rb +22 -61
  269. data/spec/extensions/sql_expr_spec.rb +29 -60
  270. data/spec/extensions/static_cache_spec.rb +145 -0
  271. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  272. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  273. data/spec/extensions/timestamps_spec.rb +6 -6
  274. data/spec/extensions/to_dot_spec.rb +4 -7
  275. data/spec/extensions/touch_spec.rb +13 -14
  276. data/spec/extensions/tree_spec.rb +11 -26
  277. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  278. data/spec/extensions/update_primary_key_spec.rb +30 -24
  279. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  280. data/spec/extensions/validation_helpers_spec.rb +16 -35
  281. data/spec/extensions/xml_serializer_spec.rb +29 -4
  282. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  283. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  284. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  285. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  286. data/spec/integration/associations_test.rb +659 -21
  287. data/spec/integration/database_test.rb +9 -3
  288. data/spec/integration/dataset_test.rb +605 -91
  289. data/spec/integration/eager_loader_test.rb +19 -21
  290. data/spec/integration/migrator_test.rb +2 -3
  291. data/spec/integration/model_test.rb +81 -2
  292. data/spec/integration/plugin_test.rb +454 -143
  293. data/spec/integration/prepared_statement_test.rb +263 -128
  294. data/spec/integration/schema_test.rb +309 -43
  295. data/spec/integration/spec_helper.rb +40 -30
  296. data/spec/integration/timezone_test.rb +38 -12
  297. data/spec/integration/transaction_test.rb +183 -8
  298. data/spec/integration/type_test.rb +18 -4
  299. data/spec/model/association_reflection_spec.rb +201 -7
  300. data/spec/model/associations_spec.rb +1067 -661
  301. data/spec/model/base_spec.rb +329 -95
  302. data/spec/model/dataset_methods_spec.rb +7 -27
  303. data/spec/model/eager_loading_spec.rb +677 -676
  304. data/spec/model/hooks_spec.rb +349 -67
  305. data/spec/model/model_spec.rb +240 -168
  306. data/spec/model/plugins_spec.rb +24 -13
  307. data/spec/model/record_spec.rb +490 -232
  308. data/spec/model/spec_helper.rb +14 -71
  309. data/spec/model/validations_spec.rb +11 -0
  310. data/spec/rcov.opts +2 -0
  311. metadata +178 -80
@@ -1,9 +1,4 @@
1
1
  require 'sqlite3'
2
- begin
3
- SQLite3::Database.instance_method(:type_translation)
4
- rescue
5
- raise(Sequel::Error, "SQLite3::Database#type_translation is not defined. If you are using the sqlite3 gem, please install the sqlite3-ruby gem.")
6
- end
7
2
  Sequel.require 'adapters/shared/sqlite'
8
3
 
9
4
  module Sequel
@@ -11,21 +6,62 @@ module Sequel
11
6
  # for Sequel.
12
7
  module SQLite
13
8
  TYPE_TRANSLATOR = tt = Class.new do
14
- FALSE_VALUES = %w'0 false f no n'.freeze
15
- def boolean(s) !FALSE_VALUES.include?(s.downcase) end
16
- def blob(s) ::Sequel::SQL::Blob.new(s) end
17
- def integer(s) s.to_i end
18
- def float(s) s.to_f end
19
- def numeric(s) ::BigDecimal.new(s) rescue s end
20
- def date(s) ::Sequel.string_to_date(s) end
21
- def time(s) ::Sequel.string_to_time(s) end
22
- def timestamp(s) ::Sequel.database_to_application_timestamp(s) end
9
+ FALSE_VALUES = (%w'0 false f no n' + [0]).freeze
10
+
11
+ def blob(s)
12
+ Sequel::SQL::Blob.new(s.to_s)
13
+ end
14
+
15
+ def boolean(s)
16
+ s = s.downcase if s.is_a?(String)
17
+ !FALSE_VALUES.include?(s)
18
+ end
19
+
20
+ def date(s)
21
+ case s
22
+ when String
23
+ Sequel.string_to_date(s)
24
+ when Integer
25
+ Date.jd(s)
26
+ when Float
27
+ Date.jd(s.to_i)
28
+ else
29
+ raise Sequel::Error, "unhandled type when converting to date: #{s.inspect} (#{s.class.inspect})"
30
+ end
31
+ end
32
+
33
+ def integer(s)
34
+ s.to_i
35
+ end
36
+
37
+ def float(s)
38
+ s.to_f
39
+ end
40
+
41
+ def numeric(s)
42
+ s = s.to_s unless s.is_a?(String)
43
+ ::BigDecimal.new(s) rescue s
44
+ end
45
+
46
+ def time(s)
47
+ case s
48
+ when String
49
+ Sequel.string_to_time(s)
50
+ when Integer
51
+ Sequel::SQLTime.create(s/3600, (s % 3600)/60, s % 60)
52
+ when Float
53
+ s, f = s.divmod(1)
54
+ Sequel::SQLTime.create(s/3600, (s % 3600)/60, s % 60, (f*1000000).round)
55
+ else
56
+ raise Sequel::Error, "unhandled type when converting to date: #{s.inspect} (#{s.class.inspect})"
57
+ end
58
+ end
59
+
23
60
  end.new
24
61
 
25
62
  # Hash with string keys and callable values for converting SQLite types.
26
63
  SQLITE_TYPES = {}
27
64
  {
28
- %w'timestamp datetime' => tt.method(:timestamp),
29
65
  %w'date' => tt.method(:date),
30
66
  %w'time' => tt.method(:time),
31
67
  %w'bit bool boolean' => tt.method(:boolean),
@@ -51,6 +87,16 @@ module Sequel
51
87
  end
52
88
 
53
89
  private_class_method :uri_to_options
90
+
91
+ # The conversion procs to use for this database
92
+ attr_reader :conversion_procs
93
+
94
+ def initialize(opts={})
95
+ super
96
+ @conversion_procs = SQLITE_TYPES.dup
97
+ @conversion_procs['datetime'] = @conversion_procs['timestamp'] = method(:to_application_timestamp)
98
+ set_integer_booleans
99
+ end
54
100
 
55
101
  # Connect to the database. Since SQLite is a file based database,
56
102
  # the only options available are :database (to specify the database
@@ -72,11 +118,6 @@ module Sequel
72
118
  db
73
119
  end
74
120
 
75
- # Return instance of Sequel::SQLite::Dataset with the given options.
76
- def dataset(opts = nil)
77
- SQLite::Dataset.new(self, opts)
78
- end
79
-
80
121
  # Run the given SQL with the given arguments and yield each row.
81
122
  def execute(sql, opts={}, &block)
82
123
  _execute(:select, sql, opts, &block)
@@ -103,11 +144,20 @@ module Sequel
103
144
  _execute(:insert, sql, opts)
104
145
  end
105
146
 
106
- # Run the given SQL with the given arguments and return the first value of the first row.
107
- def single_value(sql, opts={})
108
- _execute(:single_value, sql, opts)
147
+ # Handle Integer and Float arguments, since SQLite can store timestamps as integers and floats.
148
+ def to_application_timestamp(s)
149
+ case s
150
+ when String
151
+ super
152
+ when Integer
153
+ super(Time.at(s).to_s)
154
+ when Float
155
+ super(DateTime.jd(s).to_s)
156
+ else
157
+ raise Sequel::Error, "unhandled type when converting to : #{s.inspect} (#{s.class.inspect})"
158
+ end
109
159
  end
110
-
160
+
111
161
  private
112
162
 
113
163
  # Yield an available connection. Rescue
@@ -117,12 +167,11 @@ module Sequel
117
167
  synchronize(opts[:server]) do |conn|
118
168
  return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
119
169
  log_args = opts[:arguments]
120
- args = opts.fetch(:arguments, [])
170
+ args = {}
171
+ opts.fetch(:arguments, {}).each{|k, v| args[k] = prepared_statement_argument(v)}
121
172
  case type
122
173
  when :select
123
174
  log_yield(sql, log_args){conn.query(sql, args, &block)}
124
- when :single_value
125
- log_yield(sql, log_args){conn.get_first_value(sql, args)}
126
175
  when :insert
127
176
  log_yield(sql, log_args){conn.execute(sql, args)}
128
177
  conn.last_insert_row_id
@@ -160,7 +209,7 @@ module Sequel
160
209
 
161
210
  # Execute a prepared statement on the database using the given name.
162
211
  def execute_prepared_statement(conn, type, name, opts, &block)
163
- ps = prepared_statements[name]
212
+ ps = prepared_statement(name)
164
213
  sql = ps.prepared_sql
165
214
  args = opts[:arguments]
166
215
  ps_args = {}
@@ -173,13 +222,19 @@ module Sequel
173
222
  end
174
223
  end
175
224
  unless cps
176
- cps = conn.prepare(sql)
225
+ cps = log_yield("PREPARE #{name}: #{sql}"){conn.prepare(sql)}
177
226
  conn.prepared_statements[name] = [cps, sql]
178
227
  end
228
+ log_sql = "EXECUTE #{name}"
229
+ if ps.log_sql
230
+ log_sql << " ("
231
+ log_sql << sql
232
+ log_sql << ")"
233
+ end
179
234
  if block
180
- log_yield("Executing prepared statement #{name}", args){cps.execute(ps_args, &block)}
235
+ log_yield(log_sql, args){cps.execute(ps_args, &block)}
181
236
  else
182
- log_yield("Executing prepared statement #{name}", args){cps.execute!(ps_args){|r|}}
237
+ log_yield(log_sql, args){cps.execute!(ps_args){|r|}}
183
238
  case type
184
239
  when :insert
185
240
  conn.last_insert_row_id
@@ -204,6 +259,8 @@ module Sequel
204
259
  # Dataset class for SQLite datasets that use the ruby-sqlite3 driver.
205
260
  class Dataset < Sequel::Dataset
206
261
  include ::Sequel::SQLite::DatasetMethods
262
+
263
+ Database::DatasetClass = self
207
264
 
208
265
  PREPARED_ARG_PLACEHOLDER = ':'.freeze
209
266
 
@@ -217,7 +274,7 @@ module Sequel
217
274
  # but with the keys converted to strings.
218
275
  def map_to_prepared_args(hash)
219
276
  args = {}
220
- hash.each{|k,v| args[k.to_s] = v}
277
+ hash.each{|k,v| args[k.to_s.gsub('.', '__')] = v}
221
278
  args
222
279
  end
223
280
 
@@ -226,7 +283,12 @@ module Sequel
226
283
  # SQLite uses a : before the name of the argument for named
227
284
  # arguments.
228
285
  def prepared_arg(k)
229
- LiteralString.new("#{prepared_arg_placeholder}#{k}")
286
+ LiteralString.new("#{prepared_arg_placeholder}#{k.to_s.gsub('.', '__')}")
287
+ end
288
+
289
+ # Always assume a prepared argument.
290
+ def prepared_arg?(k)
291
+ true
230
292
  end
231
293
  end
232
294
 
@@ -287,14 +349,15 @@ module Sequel
287
349
  def fetch_rows(sql)
288
350
  execute(sql) do |result|
289
351
  i = -1
290
- type_procs = result.types.map{|t| SQLITE_TYPES[base_type_name(t)]}
352
+ cps = db.conversion_procs
353
+ type_procs = result.types.map{|t| cps[base_type_name(t)]}
291
354
  cols = result.columns.map{|c| i+=1; [output_identifier(c), i, type_procs[i]]}
292
355
  @columns = cols.map{|c| c.first}
293
356
  result.each do |values|
294
357
  row = {}
295
358
  cols.each do |name,i,type_proc|
296
359
  v = values[i]
297
- if type_proc && v.is_a?(String)
360
+ if type_proc && v
298
361
  v = type_proc.call(v)
299
362
  end
300
363
  row[name] = v
@@ -312,9 +375,8 @@ module Sequel
312
375
  ps.extend(PreparedStatementMethods)
313
376
  if name
314
377
  ps.prepared_statement_name = name
315
- db.prepared_statements[name] = ps
378
+ db.set_prepared_statement(name, ps)
316
379
  end
317
- ps.prepared_sql
318
380
  ps
319
381
  end
320
382
 
@@ -326,8 +388,8 @@ module Sequel
326
388
  end
327
389
 
328
390
  # Quote the string using the adapter class method.
329
- def literal_string(v)
330
- "'#{::SQLite3::Database.quote(v)}'"
391
+ def literal_string_append(sql, v)
392
+ sql << "'" << ::SQLite3::Database.quote(v) << "'"
331
393
  end
332
394
 
333
395
  # SQLite uses a : before the name of the argument as a placeholder.
@@ -9,11 +9,6 @@ module Sequel
9
9
  module DatabaseMethods
10
10
  include Sequel::MySQL::DatabaseMethods
11
11
 
12
- # Return instance of Sequel::Swift::MySQL::Dataset with the given opts.
13
- def dataset(opts=nil)
14
- Sequel::Swift::MySQL::Dataset.new(self, opts)
15
- end
16
-
17
12
  private
18
13
 
19
14
  # The database name for the given database.
@@ -25,22 +20,24 @@ module Sequel
25
20
  def schema_column_type(db_type)
26
21
  db_type == 'tinyint(1)' ? :boolean : super
27
22
  end
23
+
24
+ # Apply the connectiong setting SQLs for every new connection.
25
+ def setup_connection(conn)
26
+ mysql_connection_setting_sqls.each{|sql| log_yield(sql){conn.execute(sql)}}
27
+ super
28
+ end
28
29
  end
29
30
 
30
31
  # Dataset class for MySQL datasets accessed via Swift.
31
32
  class Dataset < Swift::Dataset
32
33
  include Sequel::MySQL::DatasetMethods
33
-
34
- # Use execute_insert to execute the replace_sql.
35
- def replace(*args)
36
- execute_insert(replace_sql(*args))
37
- end
34
+ APOS = Dataset::APOS
38
35
 
39
36
  private
40
37
 
41
38
  # Use Swift's escape method for quoting.
42
- def literal_string(s)
43
- db.synchronize{|c| "'#{c.escape(s)}'"}
39
+ def literal_string_append(sql, s)
40
+ sql << APOS << db.synchronize{|c| c.escape(s)} << APOS
44
41
  end
45
42
  end
46
43
  end
@@ -7,27 +7,6 @@ module Sequel
7
7
  # Adapter, Database, and Dataset support for accessing a PostgreSQL
8
8
  # database via Swift.
9
9
  module Postgres
10
- # Methods to add to the Swift adapter/connection to allow it to work
11
- # with the shared PostgreSQL code.
12
- module AdapterMethods
13
- include Sequel::Postgres::AdapterMethods
14
-
15
- # Log all SQL that goes through the execute method to the related
16
- # database object.
17
- def execute(sql, *args)
18
- @db.log_yield(sql){super}
19
- rescue SwiftError => e
20
- @db.send(:raise_error, e)
21
- end
22
-
23
- private
24
-
25
- # Swift specific method of getting specific values from a result set.
26
- def single_value(row)
27
- row.values.at(0)
28
- end
29
- end
30
-
31
10
  # Methods to add to Database instances that access PostgreSQL via Swift.
32
11
  module DatabaseMethods
33
12
  include Sequel::Postgres::DatabaseMethods
@@ -41,69 +20,25 @@ module Sequel
41
20
  end
42
21
  end
43
22
 
44
- # Return instance of Sequel::Swift::Postgres::Dataset with the given opts.
45
- def dataset(opts=nil)
46
- Sequel::Swift::Postgres::Dataset.new(self, opts)
47
- end
48
-
49
- # Run the SELECT SQL on the database and yield the rows
50
- def execute(sql, opts={})
51
- synchronize(opts[:server]) do |conn|
52
- begin
53
- res = conn.execute(sql)
54
- yield res if block_given?
55
- nil
56
- rescue SwiftError => e
57
- raise_error(e)
58
- end
59
- end
60
- end
61
-
62
- # Run the DELETE/UPDATE SQL on the database and return the number
63
- # of matched rows.
64
- def execute_dui(sql, opts={})
65
- synchronize(opts[:server]) do |conn|
66
- begin
67
- conn.execute(sql).rows
68
- rescue SwiftError => e
69
- raise_error(e)
70
- end
71
- end
72
- end
73
-
74
- # Run the INSERT SQL on the database and return the primary key
75
- # for the record.
76
- def execute_insert(sql, opts={})
77
- synchronize(opts[:server]) do |conn|
78
- begin
79
- conn.execute(sql)
80
- insert_result(conn, opts[:table], opts[:values])
81
- rescue SwiftError => e
82
- raise_error(e)
83
- end
84
- end
85
- end
86
-
87
23
  private
88
24
 
89
- # Execute SQL on the connection.
90
- def log_connection_execute(conn, sql)
91
- conn.execute(sql)
25
+ # Remove all other options except for ones specifically handled, as
26
+ # otherwise swift passes them to dbic++ which passes them to PostgreSQL
27
+ # which can raise an error.
28
+ def server_opts(o)
29
+ o = super
30
+ so = {}
31
+ [:db, :user, :password, :host, :port].each{|s| so[s] = o[s] if o.has_key?(s)}
32
+ so
92
33
  end
93
34
 
94
35
  # Extend the adapter with the Swift PostgreSQL AdapterMethods.
95
36
  def setup_connection(conn)
96
37
  conn = super(conn)
97
- conn.extend(Sequel::Swift::Postgres::AdapterMethods)
98
- conn.db = self
99
- conn.apply_connection_settings
38
+ connection_configuration_sqls.each{|sql| log_yield(sql){conn.execute(sql)}}
100
39
  conn
101
40
  end
102
41
  end
103
-
104
- class Dataset < Swift::Dataset
105
- include Sequel::Postgres::DatasetMethods
106
- end
107
42
  end
108
43
  end
109
44
  end
@@ -8,10 +8,12 @@ module Sequel
8
8
  # Database instance methods for SQLite databases accessed via Swift.
9
9
  module DatabaseMethods
10
10
  include Sequel::SQLite::DatabaseMethods
11
-
12
- # Return instance of Sequel::Swift::SQL::Dataset with the given opts.
13
- def dataset(opts=nil)
14
- Sequel::Swift::SQLite::Dataset.new(self, opts)
11
+
12
+ # Set the correct pragmas on the connection.
13
+ def connect(opts)
14
+ c = super
15
+ connection_pragmas.each{|s| log_yield(s){c.execute(s)}}
16
+ c
15
17
  end
16
18
  end
17
19
 
@@ -22,8 +24,8 @@ module Sequel
22
24
  private
23
25
 
24
26
  # Use Swift's escape method for quoting.
25
- def literal_string(s)
26
- db.synchronize{|c| "#{c.escape(s)}"}
27
+ def literal_string_append(sql, s)
28
+ sql << db.synchronize{|c| c.escape(s)}
27
29
  end
28
30
  end
29
31
  end
@@ -15,17 +15,21 @@ module Sequel
15
15
  DATABASE_SETUP = {:postgres=>proc do |db|
16
16
  Sequel.ts_require 'adapters/swift/postgres'
17
17
  db.extend(Sequel::Swift::Postgres::DatabaseMethods)
18
+ db.extend_datasets Sequel::Postgres::DatasetMethods
18
19
  db.swift_class = ::Swift::DB::Postgres
19
20
  end,
20
21
  :mysql=>proc do |db|
21
22
  Sequel.ts_require 'adapters/swift/mysql'
22
23
  db.extend(Sequel::Swift::MySQL::DatabaseMethods)
24
+ db.dataset_class = Sequel::Swift::MySQL::Dataset
23
25
  db.swift_class = ::Swift::DB::Mysql
24
26
  end,
25
27
  :sqlite=>proc do |db|
26
28
  Sequel.ts_require 'adapters/swift/sqlite'
27
29
  db.extend(Sequel::Swift::SQLite::DatabaseMethods)
30
+ db.dataset_class = Sequel::Swift::SQLite::Dataset
28
31
  db.swift_class = ::Swift::DB::Sqlite3
32
+ db.set_integer_booleans
29
33
  end,
30
34
  }
31
35
 
@@ -59,11 +63,6 @@ module Sequel
59
63
  setup_connection(swift_class.new(server_opts(server)))
60
64
  end
61
65
 
62
- # Return a Sequel::Swift::Dataset object for this database.
63
- def dataset(opts = nil)
64
- Swift::Dataset.new(self, opts)
65
- end
66
-
67
66
  # Execute the given SQL, yielding a Swift::Result if a block is given.
68
67
  def execute(sql, opts={})
69
68
  synchronize(opts[:server]) do |conn|
@@ -134,11 +133,13 @@ module Sequel
134
133
  end
135
134
 
136
135
  class Dataset < Sequel::Dataset
136
+ Database::DatasetClass = self
137
+
137
138
  # Set the columns and yield the hashes to the block.
138
- def fetch_rows(sql, &block)
139
+ def fetch_rows(sql)
139
140
  execute(sql) do |res|
140
141
  @columns = res.fields
141
- res.each(&block)
142
+ res.each{|h| yield h}
142
143
  end
143
144
  self
144
145
  end