sequel 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +40 -0
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +7 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/lib/sequel/adapters/ado.rb +34 -39
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/jdbc.rb +27 -4
- data/lib/sequel/adapters/jdbc/h2.rb +14 -3
- data/lib/sequel/adapters/jdbc/mssql.rb +51 -0
- data/lib/sequel/adapters/mysql.rb +28 -12
- data/lib/sequel/adapters/odbc.rb +36 -30
- data/lib/sequel/adapters/odbc/mssql.rb +44 -0
- data/lib/sequel/adapters/shared/mssql.rb +185 -10
- data/lib/sequel/adapters/shared/mysql.rb +9 -9
- data/lib/sequel/adapters/shared/sqlite.rb +45 -47
- data/lib/sequel/connection_pool.rb +8 -5
- data/lib/sequel/core.rb +2 -8
- data/lib/sequel/database.rb +9 -10
- data/lib/sequel/database/schema_sql.rb +3 -2
- data/lib/sequel/dataset.rb +1 -0
- data/lib/sequel/dataset/sql.rb +15 -6
- data/lib/sequel/extensions/schema_dumper.rb +7 -7
- data/lib/sequel/model/associations.rb +16 -14
- data/lib/sequel/model/base.rb +25 -7
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/many_through_many.rb +0 -1
- data/lib/sequel/sql.rb +8 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +42 -38
- data/spec/adapters/sqlite_spec.rb +0 -4
- data/spec/core/database_spec.rb +22 -1
- data/spec/core/dataset_spec.rb +37 -12
- data/spec/core/expression_filters_spec.rb +5 -0
- data/spec/core/schema_spec.rb +15 -8
- data/spec/extensions/association_proxies_spec.rb +47 -0
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +6 -6
- data/spec/extensions/many_through_many_spec.rb +13 -0
- data/spec/extensions/schema_dumper_spec.rb +12 -4
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/integration/dataset_test.rb +47 -17
- data/spec/integration/prepared_statement_test.rb +5 -5
- data/spec/integration/schema_test.rb +111 -34
- data/spec/model/associations_spec.rb +128 -11
- data/spec/model/hooks_spec.rb +7 -6
- data/spec/model/model_spec.rb +54 -4
- data/spec/model/record_spec.rb +2 -3
- data/spec/model/validations_spec.rb +4 -4
- metadata +109 -101
- data/spec/adapters/ado_spec.rb +0 -93
data/CHANGELOG
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
=== 3.3.0 (2009-08-03)
|
2
|
+
|
3
|
+
* Add an assocation_proxies plugin that uses proxies for associations (jeremyevans)
|
4
|
+
|
5
|
+
* Have the add/remove/remove_all methods take additional arguments and pass them to the internal methods (clivecrous)
|
6
|
+
|
7
|
+
* Move convert_tinyint_to_bool method from Sequel to Sequel::MySQL (jeremyevans)
|
8
|
+
|
9
|
+
* Model associations now default to associating to classes in the same scope (jeremyevans, nougad) (#274)
|
10
|
+
|
11
|
+
* Add Dataset#unlimited, similar to unfiltered and unordered (jeremyevans)
|
12
|
+
|
13
|
+
* Make Dataset#from_self take an options hash and respect an :alias option, giving the alias to use (Phrogz)
|
14
|
+
|
15
|
+
* Make the JDBC adapter accept a :convert_types option to turn off Java type conversion and double performance (jeremyevans)
|
16
|
+
|
17
|
+
* Slight increase in ConnectionPool performance (jeremyevans)
|
18
|
+
|
19
|
+
* SQL::WindowFunction can now be aliased/casted etc. just like SQL::Function (jeremyevans)
|
20
|
+
|
21
|
+
* Model#save no longer attempts to update primary key columns (jeremyevans)
|
22
|
+
|
23
|
+
* Sequel will now unescape values provided in connection strings (e.g. ado:///db?host=server%5cinstance) (jeremyevans)
|
24
|
+
|
25
|
+
* Significant improvements to the ODBC and ADO adapters in general (jeremyevans)
|
26
|
+
|
27
|
+
* The ADO adapter no longer attempts to use database transactions, since they never worked (jeremyevans)
|
28
|
+
|
29
|
+
* Much better support for Microsoft SQL Server using the ADO, ODBC, and JDBC adapters (jeremyevans)
|
30
|
+
|
31
|
+
* Support rename_column, set_column_null, set_column_type, and add_foreign_key on H2 (jeremyevans)
|
32
|
+
|
33
|
+
* Support adding a column with a primary key or unique constraint to an existing table on SQLite (jeremyevans)
|
34
|
+
|
35
|
+
* Support altering a column's type, null status, or default on SQLite (jeremyevans)
|
36
|
+
|
37
|
+
* Fix renaming a NOT NULL column without a default on MySQL (nougad, jeremyevans) (#273)
|
38
|
+
|
39
|
+
* Don't swallow DatabaseConnectionErrors when creating model subclasses (tommy.midttveit)
|
40
|
+
|
1
41
|
=== 3.2.0 (2009-07-02)
|
2
42
|
|
3
43
|
* In the STI plugin, don't overwrite the STI field if it is already set (jeremyevans)
|
data/Rakefile
CHANGED
@@ -168,7 +168,7 @@ begin
|
|
168
168
|
t.spec_opts = spec_opts.call
|
169
169
|
end
|
170
170
|
|
171
|
-
%w'postgres sqlite mysql informix oracle
|
171
|
+
%w'postgres sqlite mysql informix oracle firebird'.each do |adapter|
|
172
172
|
desc "Run #{adapter} specs without coverage"
|
173
173
|
Spec::Rake::SpecTask.new("spec_#{adapter}") do |t|
|
174
174
|
t.spec_files = ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"]
|
data/doc/opening_databases.rdoc
CHANGED
@@ -203,6 +203,13 @@ Example connections strings:
|
|
203
203
|
jdbc:mysql://localhost/test?user=root&password=root
|
204
204
|
jdbc:h2:mem:
|
205
205
|
|
206
|
+
The following additional options are supported:
|
207
|
+
|
208
|
+
* :convert_types - If set to false, does not attempt to convert some Java types to ruby types.
|
209
|
+
Setting to false roughly doubles performance when selecting large numbers of rows.
|
210
|
+
Note that you can't provide this option inside the connection string (as that is passed
|
211
|
+
directly to JDBC), you have to pass it as a separate option.
|
212
|
+
|
206
213
|
=== mysql
|
207
214
|
|
208
215
|
The MySQL adapter does not support the pure-ruby MySQL adapter that ships with
|
@@ -0,0 +1,192 @@
|
|
1
|
+
New Features
|
2
|
+
------------
|
3
|
+
|
4
|
+
* An association_proxies plugin has been added. This is not a
|
5
|
+
full-blown proxy implemention, but it allows you to write code
|
6
|
+
such as:
|
7
|
+
|
8
|
+
artist.albums.filter{num_tracks > 10}
|
9
|
+
|
10
|
+
Without the plugin, you have to call filter specifically on the
|
11
|
+
association's dataset:
|
12
|
+
|
13
|
+
artist.albums_dataset.filter{num_tracks > 10}
|
14
|
+
|
15
|
+
The plugin works by proxying array methods to the array of
|
16
|
+
associated objects, and all other methods to the association's
|
17
|
+
dataset. This results in the following behavior:
|
18
|
+
|
19
|
+
# Will load the associated objects (unless they are already
|
20
|
+
# cached), and return the length of the array
|
21
|
+
artist.albums.length
|
22
|
+
|
23
|
+
# Will issue an SQL query with COUNT (even if the association
|
24
|
+
# is already cached), and return the result
|
25
|
+
artist.albums.count
|
26
|
+
|
27
|
+
* The add_*/remove_*/remove_all_* association methods now take
|
28
|
+
additional arguments that are passed down to the
|
29
|
+
_add_*/_remove_*/_remove_all_* methods. One of the things this
|
30
|
+
allows you to do is update additional columns in join tables for
|
31
|
+
many_to_many associations:
|
32
|
+
|
33
|
+
class Album
|
34
|
+
many_to_many :artists
|
35
|
+
def _add_artist(artist, values={})
|
36
|
+
DB[:albums_artists].
|
37
|
+
insert(values.merge(:album_id=>id,
|
38
|
+
:artist_id=>artist.id))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
album = Album[1]
|
43
|
+
artist1 = Artist[2]
|
44
|
+
artist2 = Artist[3]
|
45
|
+
album.add_artist(artist1, :relationship=>'composer')
|
46
|
+
album.add_artist(artist2, :relationship=>'arranger')
|
47
|
+
|
48
|
+
* The JDBC adapter now accepts a :convert_types option to turn off
|
49
|
+
Java type conversion. The option is true by default for
|
50
|
+
backwards compatibility and correctness, but can be set to false
|
51
|
+
to double performance. The option can be set at the database
|
52
|
+
and dataset levels:
|
53
|
+
|
54
|
+
DB = Sequel.jdbc('jdbc:postgresql://host/database',
|
55
|
+
:convert_types=>false)
|
56
|
+
DB.convert_types = true
|
57
|
+
ds = DB[:table]
|
58
|
+
ds.convert_types = false
|
59
|
+
|
60
|
+
* Dataset#from_self now takes an option hash and respects an
|
61
|
+
:alias option, giving the table alias to use.
|
62
|
+
|
63
|
+
* Dataset#unlimited was added, similar to unfiltered and unordered.
|
64
|
+
|
65
|
+
* SQL::WindowFunction is now a subclass of SQL::GenericExpression,
|
66
|
+
so you can alias it and treat it like any other SQL::Function.
|
67
|
+
|
68
|
+
Other Improvements
|
69
|
+
------------------
|
70
|
+
|
71
|
+
* Microsoft SQL Server support is much, much better in Sequel 3.3.0
|
72
|
+
than in previous versions. Support is pretty good with the ODBC,
|
73
|
+
ADO, and JDBC adapters, close to the level of support for
|
74
|
+
PostreSQL, MySQL, SQLite, and H2. Improvements are too numerous
|
75
|
+
to list, but here are some highlights:
|
76
|
+
|
77
|
+
* Dataset#insert now returns the primary key (identity field), so
|
78
|
+
it can be used easier with models.
|
79
|
+
|
80
|
+
* Transactions can now use savepoints (except on ADO).
|
81
|
+
|
82
|
+
* Offsets are supported when using SQL Server 2005 or 2008, using
|
83
|
+
a ROW_NUMBER window function. However, you must specify an
|
84
|
+
order for your dataset (which you probably are already doing if
|
85
|
+
you are using offsets).
|
86
|
+
|
87
|
+
* Schema parsing has been implemented, though it doesn't support
|
88
|
+
primary key parsing (except on JDBC, since the JDBC support is
|
89
|
+
used there).
|
90
|
+
|
91
|
+
* The SQL syntax Sequel uses is now much more compatible, and
|
92
|
+
most schema modification methods and database types now work
|
93
|
+
correctly.
|
94
|
+
|
95
|
+
* The ADO and ODBC adapters both work much better now. The ADO
|
96
|
+
adapter no longer attempts to use transactions, since I've found
|
97
|
+
that ADO does not give a stable native connection (and hence
|
98
|
+
transactions weren't possible). I strongly recommend against
|
99
|
+
using the ADO adapter in production.
|
100
|
+
|
101
|
+
* The H2 JDBC subadapter now supports rename_column, set_column_null,
|
102
|
+
set_column_type, and add_foreign_key.
|
103
|
+
|
104
|
+
* Altering a columns type, null status, or default is now supported
|
105
|
+
on SQLite. You can also add primary keys and unique columns.
|
106
|
+
|
107
|
+
* Both the ADO and ODBC adapters now catch the native exception
|
108
|
+
classes and raise Sequel::DatabaseErrors.
|
109
|
+
|
110
|
+
* Model classes now default to associating to other classes in the
|
111
|
+
same scope. This makes it easier to use namespaced models.
|
112
|
+
|
113
|
+
* The schema parser and schema dumper now support the following
|
114
|
+
types: nchar, nvarchar, ntext, smalldatetime, smallmoney, binary,
|
115
|
+
and varbinary.
|
116
|
+
|
117
|
+
* You can now specify the null status for a column using :allow_null
|
118
|
+
in addition to :null. This is to make it easier to use the
|
119
|
+
table creation methods with the results of the schema parser.
|
120
|
+
|
121
|
+
* Renaming a NOT NULL column without a default now works on MySQL.
|
122
|
+
|
123
|
+
* Model class initialization now raises an exception if there is a
|
124
|
+
problem connecting to the database.
|
125
|
+
|
126
|
+
* Connection pool performance has been increased slightly.
|
127
|
+
|
128
|
+
* The literal_time method in the ODBC adapter has been fixed.
|
129
|
+
|
130
|
+
* An unlikely but potential bug in the MySQL adapter has been fixed.
|
131
|
+
|
132
|
+
Backwards Compatibility
|
133
|
+
-----------------------
|
134
|
+
|
135
|
+
* The convert_tinyint_to_bool setting moved from the main Sequel
|
136
|
+
module to the Sequel::MySQL module. The native MySQL adapter is
|
137
|
+
the only adapter that converted tinyint columns to booleans when
|
138
|
+
the rows are returned, so you can only use the setting with the
|
139
|
+
native MySQL adapter.
|
140
|
+
|
141
|
+
Additionally, the setting's behavior has changed. When parsing
|
142
|
+
the schema, now only tinyint(1) columns are now considered as
|
143
|
+
boolean, instead of all tinyint columns. This allows you to use
|
144
|
+
tinyint(4) columns for storing small integers and tinyint(1)
|
145
|
+
columns as booleans, and not have the schema parsing support
|
146
|
+
consider the tinyint(4) columns as booleans. Unfortunately,
|
147
|
+
due to limitations in the native MySQL driver, all tinyint
|
148
|
+
column values are converted to booleans upon retrieval, not just
|
149
|
+
tinyint(1) column values.
|
150
|
+
|
151
|
+
Unfortunately, the previous Sequel behavior was to use the
|
152
|
+
default tinyint size (tinyint(4)) when creating boolean columns
|
153
|
+
(using the TrueClass or FalseClass generic types). If you were
|
154
|
+
using the generic type support to create the columns, you should
|
155
|
+
modify your database to change the column type from tinyint(4) to
|
156
|
+
tinyint(1).
|
157
|
+
|
158
|
+
If you use MySQL with tinyint columns, these changes have the
|
159
|
+
potential to break applications. Care should be taken when
|
160
|
+
upgrading if these changes apply to you.
|
161
|
+
|
162
|
+
* Model classes now default to associating to other classes in the
|
163
|
+
same scope. It's highly unlikely anyone was relying on the
|
164
|
+
previous behavior, but if you have a model inside a module that
|
165
|
+
you are associating to a model outside of a module, you now need
|
166
|
+
to specify the associated class using the :class option.
|
167
|
+
|
168
|
+
* Model#save no longer includes the primary key fields in the SET
|
169
|
+
clause of the UPDATE query, only in the WHERE clause. I'm not
|
170
|
+
sure if this affects backwards compatibility of production code,
|
171
|
+
but it can break tests that expect specific SQL.
|
172
|
+
|
173
|
+
* Behavior to handle empty identifiers has now been standardized.
|
174
|
+
If any database adapter returns an empty identifier, Sequel will
|
175
|
+
use 'untitled' as the identifier. This can break backwards
|
176
|
+
compatibility if the adapter previously used another default and
|
177
|
+
you were relying on that default. This was necessary to fix any
|
178
|
+
possible "interning empty string" exceptions.
|
179
|
+
|
180
|
+
* On MSSQL, Sequel now uses the datetime type instead of the
|
181
|
+
timestamp type for generic DateTimes. It now uses bit for the
|
182
|
+
TrueClass and FalseClass generic types, and image for the File
|
183
|
+
generic type.
|
184
|
+
|
185
|
+
* Sequel now unescapes URL parts:
|
186
|
+
|
187
|
+
Sequel.connect(ado:///db?host=server%5cinstance)
|
188
|
+
|
189
|
+
However, this can break backward compatibility if you previously
|
190
|
+
expected it not to be unescaped.
|
191
|
+
|
192
|
+
* The columns_for private SQLite Database method has been removed.
|
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
require 'win32ole'
|
2
2
|
|
3
3
|
module Sequel
|
4
|
-
# The ADO adapter provides connectivity to ADO databases in Windows.
|
5
|
-
# databases can be opened using a URL with the ado schema:
|
6
|
-
#
|
7
|
-
# DB = Sequel.connect('ado://mydb')
|
8
|
-
#
|
9
|
-
# or using the Sequel.ado method:
|
10
|
-
#
|
11
|
-
# DB = Sequel.ado('mydb')
|
12
|
-
#
|
4
|
+
# The ADO adapter provides connectivity to ADO databases in Windows.
|
13
5
|
module ADO
|
14
6
|
class Database < Sequel::Database
|
15
7
|
set_adapter_scheme :ado
|
@@ -19,20 +11,19 @@ module Sequel
|
|
19
11
|
opts[:driver] ||= 'SQL Server'
|
20
12
|
case opts[:driver]
|
21
13
|
when 'SQL Server'
|
22
|
-
Sequel.require 'adapters/
|
23
|
-
extend Sequel::MSSQL::DatabaseMethods
|
14
|
+
Sequel.require 'adapters/ado/mssql'
|
15
|
+
extend Sequel::ADO::MSSQL::DatabaseMethods
|
24
16
|
end
|
25
17
|
end
|
26
18
|
|
27
19
|
# Connect to the database. In addition to the usual database options,
|
28
|
-
# the following
|
20
|
+
# the following options have an effect:
|
29
21
|
#
|
30
22
|
# * :command_timeout - Sets the time in seconds to wait while attempting
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
23
|
+
# to execute a command before cancelling the attempt and generating
|
24
|
+
# an error. Specifically, it sets the ADO CommandTimeout property.
|
25
|
+
# If this property is not set, the default of 30 seconds is used.
|
34
26
|
# * :provider - Sets the Provider of this ADO connection (for example, "SQLOLEDB")
|
35
|
-
|
36
27
|
def connect(server)
|
37
28
|
opts = server_opts(server)
|
38
29
|
s = "driver=#{opts[:driver]};server=#{opts[:host]};database=#{opts[:database]}#{";uid=#{opts[:user]};pwd=#{opts[:password]}" if opts[:user]}"
|
@@ -50,14 +41,35 @@ module Sequel
|
|
50
41
|
def execute(sql, opts={})
|
51
42
|
log_info(sql)
|
52
43
|
synchronize(opts[:server]) do |conn|
|
53
|
-
|
54
|
-
|
55
|
-
|
44
|
+
begin
|
45
|
+
r = conn.Execute(sql)
|
46
|
+
yield(r) if block_given?
|
47
|
+
rescue ::WIN32OLERuntimeError => e
|
48
|
+
raise_error(e)
|
49
|
+
end
|
56
50
|
end
|
51
|
+
nil
|
57
52
|
end
|
58
|
-
|
53
|
+
alias do execute
|
59
54
|
|
60
55
|
private
|
56
|
+
|
57
|
+
# The ADO adapter doesn't support transactions, since it appears not to
|
58
|
+
# use a single native connection for each connection in the pool
|
59
|
+
def _transaction(conn)
|
60
|
+
th = Thread.current
|
61
|
+
begin
|
62
|
+
@transactions << th
|
63
|
+
yield conn
|
64
|
+
rescue Sequel::Rollback
|
65
|
+
ensure
|
66
|
+
@transactions.delete(th)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def connection_pool_default_options
|
71
|
+
super.merge(:pool_convert_exceptions=>false)
|
72
|
+
end
|
61
73
|
|
62
74
|
def disconnect_connection(conn)
|
63
75
|
conn.Close
|
@@ -67,25 +79,8 @@ module Sequel
|
|
67
79
|
class Dataset < Sequel::Dataset
|
68
80
|
def fetch_rows(sql)
|
69
81
|
execute(sql) do |s|
|
70
|
-
@columns = s.Fields.extend(Enumerable).map
|
71
|
-
|
72
|
-
output_identifier(name)
|
73
|
-
end
|
74
|
-
|
75
|
-
unless s.eof
|
76
|
-
s.moveFirst
|
77
|
-
s.getRows.transpose.each {|r| yield hash_row(r)}
|
78
|
-
end
|
79
|
-
end
|
80
|
-
self
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def hash_row(row)
|
86
|
-
@columns.inject({}) do |m, c|
|
87
|
-
m[c] = row.shift
|
88
|
-
m
|
82
|
+
@columns = cols = s.Fields.extend(Enumerable).map{|column| output_identifier(column.Name)}
|
83
|
+
s.getRows.transpose.each{|r| yield cols.inject({}){|m,c| m[c] = r.shift; m}} unless s.eof
|
89
84
|
end
|
90
85
|
end
|
91
86
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Sequel.require 'adapters/shared/mssql'
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module ADO
|
5
|
+
# Database and Dataset instance methods for MSSQL specific
|
6
|
+
# support via ADO.
|
7
|
+
module MSSQL
|
8
|
+
module DatabaseMethods
|
9
|
+
include Sequel::MSSQL::DatabaseMethods
|
10
|
+
|
11
|
+
# Return instance of Sequel::ADO::MSSQL::Dataset with the given opts.
|
12
|
+
def dataset(opts=nil)
|
13
|
+
Sequel::ADO::MSSQL::Dataset.new(self, opts)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Dataset < ADO::Dataset
|
18
|
+
include Sequel::MSSQL::DatasetMethods
|
19
|
+
|
20
|
+
# Use a nasty hack of multiple SQL statements in the same call and
|
21
|
+
# having the last one return the most recently inserted id. This
|
22
|
+
# is necessary as ADO doesn't provide a consistent native connection.
|
23
|
+
def insert(values={})
|
24
|
+
return super if @opts[:sql]
|
25
|
+
with_sql("SET NOCOUNT ON; #{insert_sql(values)}; SELECT CAST(SCOPE_IDENTITY() AS INTEGER)").single_value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -58,8 +58,8 @@ module Sequel
|
|
58
58
|
Java::oracle.jdbc.driver.OracleDriver
|
59
59
|
end,
|
60
60
|
:sqlserver=>proc do |db|
|
61
|
-
Sequel.require 'adapters/
|
62
|
-
db.extend(Sequel::MSSQL::DatabaseMethods)
|
61
|
+
Sequel.require 'adapters/jdbc/mssql'
|
62
|
+
db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
|
63
63
|
com.microsoft.sqlserver.jdbc.SQLServerDriver
|
64
64
|
end,
|
65
65
|
:h2=>proc do |db|
|
@@ -88,12 +88,18 @@ module Sequel
|
|
88
88
|
# The type of database we are connecting to
|
89
89
|
attr_reader :database_type
|
90
90
|
|
91
|
+
# Whether to convert some Java types to ruby types when retrieving rows.
|
92
|
+
# True by default, can be set to false to roughly double performance when
|
93
|
+
# fetching rows.
|
94
|
+
attr_accessor :convert_types
|
95
|
+
|
91
96
|
# Call the DATABASE_SETUP proc directly after initialization,
|
92
97
|
# so the object always uses sub adapter specific code. Also,
|
93
98
|
# raise an error immediately if the connection doesn't have a
|
94
99
|
# uri, since JDBC requires one.
|
95
100
|
def initialize(opts)
|
96
101
|
@opts = opts
|
102
|
+
@convert_types = opts.include?(:convert_types) ? typecast_value_boolean(opts[:convert_types]) : true
|
97
103
|
raise(Error, "No connection string specified") unless uri
|
98
104
|
if match = /\Ajdbc:([^:]+)/.match(uri) and prok = DATABASE_SETUP[match[1].to_sym]
|
99
105
|
prok.call(self)
|
@@ -279,7 +285,7 @@ module Sequel
|
|
279
285
|
cps.execute
|
280
286
|
when :insert
|
281
287
|
cps.executeUpdate
|
282
|
-
last_insert_id(conn, opts)
|
288
|
+
last_insert_id(conn, opts.merge(:prepared=>true))
|
283
289
|
else
|
284
290
|
cps.executeUpdate
|
285
291
|
end
|
@@ -418,6 +424,17 @@ module Sequel
|
|
418
424
|
end
|
419
425
|
end
|
420
426
|
|
427
|
+
# Whether to convert some Java types to ruby types when retrieving rows.
|
428
|
+
# Uses the database's setting by default, can be set to false to roughly
|
429
|
+
# double performance when fetching rows.
|
430
|
+
attr_accessor :convert_types
|
431
|
+
|
432
|
+
# Use the convert_types default setting from the database
|
433
|
+
def initialize(db, opts={})
|
434
|
+
@convert_types = db.convert_types
|
435
|
+
super
|
436
|
+
end
|
437
|
+
|
421
438
|
# Correctly return rows from the database and return them as hashes.
|
422
439
|
def fetch_rows(sql, &block)
|
423
440
|
execute(sql){|result| process_result_set(result, &block)}
|
@@ -470,10 +487,16 @@ module Sequel
|
|
470
487
|
i = 0
|
471
488
|
meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
|
472
489
|
@columns = cols.map{|c| c.at(0)}
|
490
|
+
row = {}
|
491
|
+
blk = if @convert_types
|
492
|
+
lambda{|n, i| row[n] = convert_type(result.getObject(i))}
|
493
|
+
else
|
494
|
+
lambda{|n, i| row[n] = result.getObject(i)}
|
495
|
+
end
|
473
496
|
# get rows
|
474
497
|
while result.next
|
475
498
|
row = {}
|
476
|
-
cols.each
|
499
|
+
cols.each(&blk)
|
477
500
|
yield row
|
478
501
|
end
|
479
502
|
end
|