sequel 3.2.0 → 3.3.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.
- 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
|