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
@@ -32,47 +32,96 @@ module Sequel
32
32
  DATABASE_SETUP = {:postgresql=>proc do |db|
33
33
  Sequel.ts_require 'adapters/jdbc/postgresql'
34
34
  db.extend(Sequel::JDBC::Postgres::DatabaseMethods)
35
+ db.dataset_class = Sequel::JDBC::Postgres::Dataset
35
36
  JDBC.load_gem('postgres')
36
37
  org.postgresql.Driver
37
38
  end,
38
39
  :mysql=>proc do |db|
39
40
  Sequel.ts_require 'adapters/jdbc/mysql'
40
41
  db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
42
+ db.extend_datasets Sequel::MySQL::DatasetMethods
41
43
  JDBC.load_gem('mysql')
42
44
  com.mysql.jdbc.Driver
43
45
  end,
44
46
  :sqlite=>proc do |db|
45
47
  Sequel.ts_require 'adapters/jdbc/sqlite'
46
48
  db.extend(Sequel::JDBC::SQLite::DatabaseMethods)
49
+ db.extend_datasets Sequel::SQLite::DatasetMethods
50
+ db.set_integer_booleans
47
51
  JDBC.load_gem('sqlite3')
48
52
  org.sqlite.JDBC
49
53
  end,
50
54
  :oracle=>proc do |db|
51
55
  Sequel.ts_require 'adapters/jdbc/oracle'
52
56
  db.extend(Sequel::JDBC::Oracle::DatabaseMethods)
57
+ db.dataset_class = Sequel::JDBC::Oracle::Dataset
53
58
  Java::oracle.jdbc.driver.OracleDriver
54
59
  end,
55
60
  :sqlserver=>proc do |db|
56
- Sequel.ts_require 'adapters/jdbc/mssql'
57
- db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
61
+ Sequel.ts_require 'adapters/jdbc/sqlserver'
62
+ db.extend(Sequel::JDBC::SQLServer::DatabaseMethods)
63
+ db.extend_datasets Sequel::MSSQL::DatasetMethods
64
+ db.send(:set_mssql_unicode_strings)
58
65
  com.microsoft.sqlserver.jdbc.SQLServerDriver
59
66
  end,
60
67
  :jtds=>proc do |db|
61
- Sequel.ts_require 'adapters/jdbc/mssql'
68
+ Sequel.ts_require 'adapters/jdbc/jtds'
62
69
  db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
70
+ db.dataset_class = Sequel::JDBC::JTDS::Dataset
71
+ db.send(:set_mssql_unicode_strings)
63
72
  JDBC.load_gem('jtds')
64
73
  Java::net.sourceforge.jtds.jdbc.Driver
65
74
  end,
66
75
  :h2=>proc do |db|
67
76
  Sequel.ts_require 'adapters/jdbc/h2'
68
77
  db.extend(Sequel::JDBC::H2::DatabaseMethods)
78
+ db.dataset_class = Sequel::JDBC::H2::Dataset
69
79
  JDBC.load_gem('h2')
70
80
  org.h2.Driver
71
81
  end,
82
+ :hsqldb=>proc do |db|
83
+ Sequel.ts_require 'adapters/jdbc/hsqldb'
84
+ db.extend(Sequel::JDBC::HSQLDB::DatabaseMethods)
85
+ db.dataset_class = Sequel::JDBC::HSQLDB::Dataset
86
+ # Current gem is 1.8.1.3, but Sequel supports 2.2.5
87
+ org.hsqldb.jdbcDriver
88
+ end,
89
+ :derby=>proc do |db|
90
+ Sequel.ts_require 'adapters/jdbc/derby'
91
+ db.extend(Sequel::JDBC::Derby::DatabaseMethods)
92
+ db.dataset_class = Sequel::JDBC::Derby::Dataset
93
+ JDBC.load_gem('derby')
94
+ org.apache.derby.jdbc.EmbeddedDriver
95
+ end,
72
96
  :as400=>proc do |db|
73
97
  Sequel.ts_require 'adapters/jdbc/as400'
74
98
  db.extend(Sequel::JDBC::AS400::DatabaseMethods)
99
+ db.dataset_class = Sequel::JDBC::AS400::Dataset
75
100
  com.ibm.as400.access.AS400JDBCDriver
101
+ end,
102
+ :"informix-sqli"=>proc do |db|
103
+ Sequel.ts_require 'adapters/jdbc/informix'
104
+ db.extend(Sequel::JDBC::Informix::DatabaseMethods)
105
+ db.extend_datasets Sequel::Informix::DatasetMethods
106
+ com.informix.jdbc.IfxDriver
107
+ end,
108
+ :db2=>proc do |db|
109
+ Sequel.ts_require 'adapters/jdbc/db2'
110
+ db.extend(Sequel::JDBC::DB2::DatabaseMethods)
111
+ db.extend_datasets Sequel::DB2::DatasetMethods
112
+ com.ibm.db2.jcc.DB2Driver
113
+ end,
114
+ :firebirdsql=>proc do |db|
115
+ Sequel.ts_require 'adapters/jdbc/firebird'
116
+ db.extend(Sequel::JDBC::Firebird::DatabaseMethods)
117
+ db.extend_datasets Sequel::Firebird::DatasetMethods
118
+ org.firebirdsql.jdbc.FBDriver
119
+ end,
120
+ :jdbcprogress=>proc do |db|
121
+ Sequel.ts_require 'adapters/jdbc/progress'
122
+ db.extend(Sequel::JDBC::Progress::DatabaseMethods)
123
+ db.extend_datasets Sequel::Progress::DatasetMethods
124
+ com.progress.sql.jdbc.JdbcProgressDriver
76
125
  end
77
126
  }
78
127
 
@@ -101,13 +150,15 @@ module Sequel
101
150
  # True by default, can be set to false to roughly double performance when
102
151
  # fetching rows.
103
152
  attr_accessor :convert_types
104
-
153
+
105
154
  # Call the DATABASE_SETUP proc directly after initialization,
106
155
  # so the object always uses sub adapter specific code. Also,
107
156
  # raise an error immediately if the connection doesn't have a
108
157
  # uri, since JDBC requires one.
109
158
  def initialize(opts)
110
159
  super
160
+ @connection_prepared_statements = {}
161
+ @connection_prepared_statements_mutex = Mutex.new
111
162
  @convert_types = typecast_value_boolean(@opts.fetch(:convert_types, true))
112
163
  raise(Error, "No connection string specified") unless uri
113
164
 
@@ -158,8 +209,9 @@ module Sequel
158
209
  args = [uri(opts)]
159
210
  args.concat([opts[:user], opts[:password]]) if opts[:user] && opts[:password]
160
211
  begin
212
+ JavaSQL::DriverManager.setLoginTimeout(opts[:login_timeout]) if opts[:login_timeout]
161
213
  JavaSQL::DriverManager.getConnection(*args)
162
- rescue => e
214
+ rescue JavaSQL::SQLException, NativeException, StandardError => e
163
215
  raise e unless driver
164
216
  # If the DriverManager can't get the connection - use the connect
165
217
  # method of the driver. (This happens under Tomcat for instance)
@@ -171,7 +223,9 @@ module Sequel
171
223
  opts[:jdbc_properties].each{|k,v| props.setProperty(k.to_s, v)} if opts[:jdbc_properties]
172
224
  begin
173
225
  driver.new.connect(args[0], props)
174
- rescue => e2
226
+ raise(Sequel::DatabaseError, 'driver.new.connect returned nil: probably bad JDBC connection string') unless c
227
+ c
228
+ rescue JavaSQL::SQLException, NativeException, StandardError => e2
175
229
  e.message << "\n#{e2.class.name}: #{e2.message}"
176
230
  raise e
177
231
  end
@@ -180,11 +234,6 @@ module Sequel
180
234
  setup_connection(conn)
181
235
  end
182
236
 
183
- # Return instances of JDBC::Dataset with the given opts.
184
- def dataset(opts = nil)
185
- JDBC::Dataset.new(self, opts)
186
- end
187
-
188
237
  # Execute the given SQL. If a block is given, if should be a SELECT
189
238
  # statement or something else that returns rows.
190
239
  def execute(sql, opts={}, &block)
@@ -246,12 +295,14 @@ module Sequel
246
295
  indexes
247
296
  end
248
297
 
298
+ # Whether or not JNDI is being used for this connection.
299
+ def jndi?
300
+ !!(uri =~ JNDI_URI_REGEXP)
301
+ end
302
+
249
303
  # All tables in this database
250
304
  def tables(opts={})
251
- ts = []
252
- m = output_identifier_meth
253
- metadata(:getTables, nil, nil, nil, ['TABLE'].to_java(:string)){|h| ts << m.call(h[:table_name])}
254
- ts
305
+ get_tables('TABLE', opts)
255
306
  end
256
307
 
257
308
  # The uri for this connection. You can specify the uri
@@ -264,18 +315,31 @@ module Sequel
264
315
  ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
265
316
  end
266
317
 
267
- # Whether or not JNDI is being used for this connection.
268
- def jndi?
269
- !!(uri =~ JNDI_URI_REGEXP)
318
+ # All views in this database
319
+ def views(opts={})
320
+ get_tables('VIEW', opts)
270
321
  end
271
-
322
+
272
323
  private
273
324
 
274
- # Close given adapter connections
325
+ # Yield the native prepared statements hash for the given connection
326
+ # to the block in a thread-safe manner.
327
+ def cps_sync(conn, &block)
328
+ @connection_prepared_statements_mutex.synchronize{yield(@connection_prepared_statements[conn] ||= {})}
329
+ end
330
+
331
+ # Close given adapter connections, and delete any related prepared statements.
275
332
  def disconnect_connection(c)
333
+ @connection_prepared_statements_mutex.synchronize{@connection_prepared_statements.delete(c)}
276
334
  c.close
277
335
  end
278
336
 
337
+ # Raise a disconnect error if the SQL state of the cause of the exception indicates so.
338
+ def disconnect_error?(exception, opts)
339
+ cause = exception.respond_to?(:cause) ? exception.cause : exception
340
+ super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
341
+ end
342
+
279
343
  # Execute the prepared statement. If the provided name is a
280
344
  # dataset, use that as the prepared statement, otherwise use
281
345
  # it as a key to look it up in the prepared_statements hash.
@@ -289,20 +353,25 @@ module Sequel
289
353
  ps = name
290
354
  name = ps.prepared_statement_name
291
355
  else
292
- ps = prepared_statements[name]
356
+ ps = prepared_statement(name)
293
357
  end
294
358
  sql = ps.prepared_sql
295
359
  synchronize(opts[:server]) do |conn|
296
- if name and cps = conn.prepared_statements[name] and cps[0] == sql
360
+ if name and cps = cps_sync(conn){|cpsh| cpsh[name]} and cps[0] == sql
297
361
  cps = cps[1]
298
362
  else
299
- log_yield("Closing #{name}"){cps[1].close} if cps
300
- cps = log_yield("Preparing#{" #{name}:" if name} #{sql}"){conn.prepareStatement(sql)}
301
- conn.prepared_statements[name] = [sql, cps] if name
363
+ log_yield("CLOSE #{name}"){cps[1].close} if cps
364
+ cps = log_yield("PREPARE#{" #{name}:" if name} #{sql}"){conn.prepareStatement(sql)}
365
+ cps_sync(conn){|cpsh| cpsh[name] = [sql, cps]} if name
302
366
  end
303
367
  i = 0
304
368
  args.each{|arg| set_ps_arg(cps, arg, i+=1)}
305
- msg = "Executing#{" #{name}" if name}"
369
+ msg = "EXECUTE#{" #{name}" if name}"
370
+ if ps.log_sql
371
+ msg << " ("
372
+ msg << sql
373
+ msg << ")"
374
+ end
306
375
  begin
307
376
  if block_given?
308
377
  yield log_yield(msg, args){cps.executeQuery}
@@ -325,6 +394,12 @@ module Sequel
325
394
  end
326
395
  end
327
396
 
397
+ # Gets the connection from JNDI.
398
+ def get_connection_from_jndi
399
+ jndi_name = JNDI_URI_REGEXP.match(uri)[1]
400
+ JavaxNaming::InitialContext.new.lookup(jndi_name).connection
401
+ end
402
+
328
403
  # Gets the JDBC connection uri from the JNDI resource.
329
404
  def get_uri_from_jndi
330
405
  conn = get_connection_from_jndi
@@ -333,12 +408,14 @@ module Sequel
333
408
  conn.close if conn
334
409
  end
335
410
 
336
- # Gets the connection from JNDI.
337
- def get_connection_from_jndi
338
- jndi_name = JNDI_URI_REGEXP.match(uri)[1]
339
- JavaxNaming::InitialContext.new.lookup(jndi_name).connection
411
+ # Backbone of the tables and views support.
412
+ def get_tables(type, opts)
413
+ ts = []
414
+ m = output_identifier_meth
415
+ metadata(:getTables, nil, nil, nil, [type].to_java(:string)){|h| ts << m.call(h[:table_name])}
416
+ ts
340
417
  end
341
-
418
+
342
419
  # Support Date objects used in bound variables
343
420
  def java_sql_date(date)
344
421
  java.sql.Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
@@ -383,12 +460,6 @@ module Sequel
383
460
  end
384
461
  end
385
462
 
386
- # Treat SQLExceptions with a "Connection Error" SQLState as disconnects
387
- def raise_error(exception, opts={})
388
- cause = exception.respond_to?(:cause) ? exception.cause : exception
389
- super(exception, {:disconnect => cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/}.merge(opts))
390
- end
391
-
392
463
  # Java being java, you need to specify the type of each argument
393
464
  # for the prepared statement, and bind it individually. This
394
465
  # guesses which JDBC method to use, and hopefully JRuby will convert
@@ -405,8 +476,8 @@ module Sequel
405
476
  cps.setDouble(i, arg)
406
477
  when TrueClass, FalseClass
407
478
  cps.setBoolean(i, arg)
408
- when nil
409
- cps.setNull(i, JavaSQL::Types::NULL)
479
+ when NilClass
480
+ cps.setString(i, nil)
410
481
  when DateTime
411
482
  cps.setTimestamp(i, java_sql_datetime(arg))
412
483
  when Date
@@ -422,21 +493,16 @@ module Sequel
422
493
  end
423
494
  end
424
495
 
425
- # Add a prepared_statements accessor to the connection,
426
- # and set it to an empty hash. This is used to store
427
- # adapter specific prepared statements.
496
+ # Return the connection. Used to do configuration on the
497
+ # connection object before adding it to the connection pool.
428
498
  def setup_connection(conn)
429
- class << conn
430
- attr_accessor :prepared_statements
431
- end
432
- conn.prepared_statements = {}
433
499
  conn
434
500
  end
435
501
 
436
502
  # Parse the table schema for the given table.
437
503
  def schema_parse_table(table, opts={})
438
- m = output_identifier_meth
439
- im = input_identifier_meth
504
+ m = output_identifier_meth(opts[:dataset])
505
+ im = input_identifier_meth(opts[:dataset])
440
506
  ds = dataset
441
507
  schema, table = schema_and_table(table)
442
508
  schema ||= opts[:schema]
@@ -444,9 +510,11 @@ module Sequel
444
510
  table = im.call(table)
445
511
  pks, ts = [], []
446
512
  metadata(:getPrimaryKeys, nil, schema, table) do |h|
513
+ next if schema_parse_table_skip?(h, schema)
447
514
  pks << h[:column_name]
448
515
  end
449
516
  metadata(:getColumns, nil, schema, table, nil) do |h|
517
+ next if schema_parse_table_skip?(h, schema)
450
518
  s = {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size], :scale=>h[:decimal_digits]}
451
519
  if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
452
520
  s[:type] = :integer
@@ -456,6 +524,12 @@ module Sequel
456
524
  ts
457
525
  end
458
526
 
527
+ # Whether schema_parse_table should skip the given row when
528
+ # parsing the schema.
529
+ def schema_parse_table_skip?(h, schema)
530
+ h[:table_schem] == 'INFORMATION_SCHEMA'
531
+ end
532
+
459
533
  # Yield a new statement object, and ensure that it is closed before returning.
460
534
  def statement(conn)
461
535
  stmt = conn.createStatement
@@ -476,6 +550,8 @@ module Sequel
476
550
 
477
551
  class Dataset < Sequel::Dataset
478
552
  include StoredProcedures
553
+
554
+ Database::DatasetClass = self
479
555
 
480
556
  # Use JDBC PreparedStatements instead of emulated ones. Statements
481
557
  # created using #prepare are cached at the connection level to allow
@@ -489,17 +565,17 @@ module Sequel
489
565
  # Execute the prepared SQL using the stored type and
490
566
  # arguments derived from the hash passed to call.
491
567
  def execute(sql, opts={}, &block)
492
- super(self, {:arguments=>bind_arguments, :type=>sql_query_type}.merge(opts), &block)
568
+ super(self, {:arguments=>bind_arguments}.merge(opts), &block)
493
569
  end
494
570
 
495
571
  # Same as execute, explicit due to intricacies of alias and super.
496
572
  def execute_dui(sql, opts={}, &block)
497
- super(self, {:arguments=>bind_arguments, :type=>sql_query_type}.merge(opts), &block)
573
+ super(self, {:arguments=>bind_arguments}.merge(opts), &block)
498
574
  end
499
575
 
500
576
  # Same as execute, explicit due to intricacies of alias and super.
501
577
  def execute_insert(sql, opts={}, &block)
502
- super(self, {:arguments=>bind_arguments, :type=>sql_query_type}.merge(opts), &block)
578
+ super(self, {:arguments=>bind_arguments, :type=>:insert}.merge(opts), &block)
503
579
  end
504
580
  end
505
581
 
@@ -512,17 +588,17 @@ module Sequel
512
588
 
513
589
  # Execute the database stored procedure with the stored arguments.
514
590
  def execute(sql, opts={}, &block)
515
- super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>sql_query_type}.merge(opts), &block)
591
+ super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
516
592
  end
517
593
 
518
594
  # Same as execute, explicit due to intricacies of alias and super.
519
595
  def execute_dui(sql, opts={}, &block)
520
- super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>sql_query_type}.merge(opts), &block)
596
+ super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
521
597
  end
522
598
 
523
599
  # Same as execute, explicit due to intricacies of alias and super.
524
600
  def execute_insert(sql, opts={}, &block)
525
- super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>sql_query_type}.merge(opts), &block)
601
+ super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>:insert}.merge(opts), &block)
526
602
  end
527
603
  end
528
604
 
@@ -530,13 +606,7 @@ module Sequel
530
606
  # Uses the database's setting by default, can be set to false to roughly
531
607
  # double performance when fetching rows.
532
608
  attr_accessor :convert_types
533
-
534
- # Use the convert_types default setting from the database
535
- def initialize(db, opts={})
536
- @convert_types = db.convert_types
537
- super
538
- end
539
-
609
+
540
610
  # Correctly return rows from the database and return them as hashes.
541
611
  def fetch_rows(sql, &block)
542
612
  execute(sql){|result| process_result_set(result, &block)}
@@ -550,32 +620,83 @@ module Sequel
550
620
  ps.extend(PreparedStatementMethods)
551
621
  if name
552
622
  ps.prepared_statement_name = name
553
- db.prepared_statements[name] = ps
623
+ db.set_prepared_statement(name, ps)
554
624
  end
555
625
  ps
556
626
  end
557
627
 
558
628
  private
559
-
560
- # Convert the type. Used for converting Java types to ruby types.
561
- def convert_type(v)
629
+
630
+ # Cache Java class constants to speed up lookups
631
+ JAVA_SQL_TIMESTAMP = Java::JavaSQL::Timestamp
632
+ JAVA_SQL_TIME = Java::JavaSQL::Time
633
+ JAVA_SQL_DATE = Java::JavaSQL::Date
634
+ JAVA_SQL_BLOB = Java::JavaSQL::Blob
635
+ JAVA_SQL_CLOB = Java::JavaSQL::Clob
636
+ JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
637
+ JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
638
+ JAVA_BYTE_ARRAY = Java::byte[]
639
+
640
+ # Handle type conversions for common Java types.
641
+ class TYPE_TRANSLATOR
642
+ LF = "\n".freeze
643
+ def time(v) Sequel.string_to_time("#{v.to_string}.#{sprintf('%03i', v.getTime.divmod(1000).last)}") end
644
+ def date(v) Date.civil(v.getYear + 1900, v.getMonth + 1, v.getDate) end
645
+ def decimal(v) BigDecimal.new(v.to_string) end
646
+ def byte_array(v) Sequel::SQL::Blob.new(String.from_java_bytes(v)) end
647
+ def blob(v) Sequel::SQL::Blob.new(String.from_java_bytes(v.getBytes(1, v.length))) end
648
+ def clob(v) Sequel::SQL::Blob.new(v.getSubString(1, v.length)) end
649
+ def buffered_reader(v)
650
+ lines = ""
651
+ c = false
652
+ while(line = v.read_line) do
653
+ lines << LF if c
654
+ lines << line
655
+ c ||= true
656
+ end
657
+ lines
658
+ end
659
+ end
660
+ TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
661
+
662
+ # Cache type translator methods so that duplicate Method
663
+ # objects are not created.
664
+ DECIMAL_METHOD = tt.method(:decimal)
665
+ TIME_METHOD = tt.method(:time)
666
+ DATE_METHOD = tt.method(:date)
667
+ BUFFERED_READER_METHOD = tt.method(:buffered_reader)
668
+ BYTE_ARRAY_METHOD = tt.method(:byte_array)
669
+ BLOB_METHOD = tt.method(:blob)
670
+ CLOB_METHOD = tt.method(:clob)
671
+
672
+ # Convert the given Java timestamp to an instance of Sequel.datetime_class.
673
+ def convert_type_timestamp(v)
674
+ db.to_application_timestamp([v.getYear + 1900, v.getMonth + 1, v.getDate, v.getHours, v.getMinutes, v.getSeconds, v.getNanos])
675
+ end
676
+
677
+ # Return a callable object that will convert any value of <tt>v</tt>'s
678
+ # class to a ruby object. If no callable object can handle <tt>v</tt>'s
679
+ # class, return false so that the negative lookup is cached.
680
+ def convert_type_proc(v)
562
681
  case v
563
- when Java::JavaSQL::Timestamp, Java::JavaSQL::Time
564
- Sequel.database_to_application_timestamp(v.to_string)
565
- when Java::JavaSQL::Date
566
- Sequel.string_to_date(v.to_string)
567
- when Java::JavaIo::BufferedReader
568
- lines = []
569
- while(line = v.read_line) do lines << line end
570
- lines.join("\n")
571
- when Java::JavaMath::BigDecimal
572
- BigDecimal.new(v.to_string)
573
- when Java::byte[]
574
- Sequel::SQL::Blob.new(String.from_java_bytes(v))
575
- when Java::JavaSQL::Blob
576
- convert_type(v.getBytes(1, v.length))
682
+ when JAVA_BIG_DECIMAL
683
+ DECIMAL_METHOD
684
+ when JAVA_SQL_TIMESTAMP
685
+ method(:convert_type_timestamp)
686
+ when JAVA_SQL_TIME
687
+ TIME_METHOD
688
+ when JAVA_SQL_DATE
689
+ DATE_METHOD
690
+ when JAVA_BUFFERED_READER
691
+ BUFFERED_READER_METHOD
692
+ when JAVA_BYTE_ARRAY
693
+ BYTE_ARRAY_METHOD
694
+ when JAVA_SQL_BLOB
695
+ BLOB_METHOD
696
+ when JAVA_SQL_CLOB
697
+ CLOB_METHOD
577
698
  else
578
- v
699
+ false
579
700
  end
580
701
  end
581
702
 
@@ -586,32 +707,82 @@ module Sequel
586
707
 
587
708
  # Split out from fetch rows to allow processing of JDBC result sets
588
709
  # that don't come from issuing an SQL string.
589
- def process_result_set(result)
710
+ def process_result_set(result, &block)
590
711
  # get column names
591
712
  meta = result.getMetaData
592
713
  cols = []
593
714
  i = 0
594
715
  meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
595
- @columns = cols.map{|c| c.at(0)}
596
- blk = result_set_object_getter
597
- # get rows
716
+ columns = cols.map{|c| c.at(0)}
717
+ if opts[:offset] && offset_returns_row_number_column?
718
+ rn = row_number_column
719
+ columns.delete(rn)
720
+ end
721
+ @columns = columns
722
+ ct = @convert_types
723
+ if (ct.nil? ? db.convert_types : ct)
724
+ cols.each{|c| c << nil}
725
+ process_result_set_convert(cols, result, rn, &block)
726
+ else
727
+ process_result_set_no_convert(cols, result, rn, &block)
728
+ end
729
+ ensure
730
+ result.close
731
+ end
732
+
733
+ # Use conversion procs to convert data retrieved
734
+ # from the database. This has been optimized, the algorithm it uses
735
+ # is roughly, for each column value in each row:
736
+ # * check if the value is truthy (not false/nil)
737
+ # * if not truthy, return object
738
+ # * otherwise, see if a conversion method exists for
739
+ # the column. All columns start with a nil conversion proc,
740
+ # since unlike other adapters, Sequel doesn't get the type of
741
+ # the column when parsing the column metadata.
742
+ # * if a conversion proc is not false/nil, call it with the object
743
+ # and return the result.
744
+ # * if a conversion proc has already been looked up and doesn't
745
+ # exist (false value), return object.
746
+ # * if a conversion proc hasn't been looked up yet (nil value),
747
+ # call convert_type_proc to get the conversion method. Cache
748
+ # the result of as the column's conversion proc to speed up
749
+ # later processing. If the conversion proc exists, call it
750
+ # and return the result, otherwise, return the object.
751
+ def process_result_set_convert(cols, result, rn)
598
752
  while result.next
599
753
  row = {}
600
- cols.each do |n, i|
601
- row[n] = blk.call(result, n, i)
754
+ cols.each do |n, i, p|
755
+ v = result.getObject(i)
756
+ row[n] = if v
757
+ if p
758
+ p.call(v)
759
+ elsif p.nil?
760
+ cols[i-1][2] = p = convert_type_proc(v)
761
+ if p
762
+ p.call(v)
763
+ else
764
+ v
765
+ end
766
+ else
767
+ v
768
+ end
769
+ else
770
+ v
771
+ end
602
772
  end
773
+ row.delete(rn) if rn
603
774
  yield row
604
775
  end
605
776
  end
606
777
 
607
- # Proc that takes the ResultSet and an integer field number and returns
608
- # the object for that field. Respects the @convert_types setting to
609
- # convert Java types to ruby types.
610
- def result_set_object_getter
611
- if @convert_types
612
- lambda {|result, n, i| convert_type(result.getObject(i))}
613
- else
614
- lambda {|result, n, i| result.getObject(i)}
778
+ # Yield rows without calling any conversion procs. This
779
+ # may yield Java values and not ruby values.
780
+ def process_result_set_no_convert(cols, result, rn)
781
+ while result.next
782
+ row = {}
783
+ cols.each{|n, i| row[n] = result.getObject(i)}
784
+ row.delete(rn) if rn
785
+ yield row
615
786
  end
616
787
  end
617
788
  end