sequel 3.13.0 → 3.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +36 -0
- data/doc/release_notes/3.14.0.txt +118 -0
- data/lib/sequel/adapters/oracle.rb +7 -2
- data/lib/sequel/adapters/shared/mssql.rb +9 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/threaded.rb +3 -3
- data/lib/sequel/database/connecting.rb +47 -11
- data/lib/sequel/database/dataset.rb +17 -6
- data/lib/sequel/database/dataset_defaults.rb +15 -3
- data/lib/sequel/database/logging.rb +4 -3
- data/lib/sequel/database/misc.rb +33 -21
- data/lib/sequel/database/query.rb +61 -22
- data/lib/sequel/database/schema_generator.rb +108 -45
- data/lib/sequel/database/schema_methods.rb +8 -5
- data/lib/sequel/dataset/actions.rb +194 -45
- data/lib/sequel/dataset/features.rb +1 -1
- data/lib/sequel/dataset/graph.rb +51 -43
- data/lib/sequel/dataset/misc.rb +29 -5
- data/lib/sequel/dataset/mutation.rb +0 -1
- data/lib/sequel/dataset/prepared_statements.rb +14 -2
- data/lib/sequel/dataset/query.rb +268 -125
- data/lib/sequel/dataset/sql.rb +33 -44
- data/lib/sequel/extensions/migration.rb +3 -2
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/model/associations.rb +89 -87
- data/lib/sequel/model/base.rb +386 -109
- data/lib/sequel/model/errors.rb +15 -1
- data/lib/sequel/model/exceptions.rb +3 -3
- data/lib/sequel/model/inflections.rb +2 -2
- data/lib/sequel/model/plugins.rb +9 -5
- data/lib/sequel/plugins/rcte_tree.rb +43 -15
- data/lib/sequel/plugins/schema.rb +6 -5
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/tree.rb +33 -1
- data/lib/sequel/timezones.rb +16 -10
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +36 -2
- data/spec/adapters/mysql_spec.rb +4 -4
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +2 -2
- data/spec/core/database_spec.rb +8 -1
- data/spec/core/dataset_spec.rb +36 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +40 -8
- data/spec/extensions/schema_spec.rb +5 -0
- data/spec/extensions/serialization_spec.rb +4 -4
- data/spec/extensions/single_table_inheritance_spec.rb +7 -0
- data/spec/extensions/tree_spec.rb +36 -0
- data/spec/integration/dataset_test.rb +19 -0
- data/spec/integration/prepared_statement_test.rb +2 -2
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/spec_helper.rb +4 -4
- data/spec/integration/timezone_test.rb +27 -21
- data/spec/model/associations_spec.rb +5 -5
- data/spec/model/dataset_methods_spec.rb +13 -0
- data/spec/model/hooks_spec.rb +31 -0
- data/spec/model/record_spec.rb +24 -7
- data/spec/model/validations_spec.rb +9 -4
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
=== 3.14.0 (2010-08-02)
|
2
|
+
|
3
|
+
* Handle OCIInvalidHandle errors when disconnecting in the Oracle adapter (jeremyevans)
|
4
|
+
|
5
|
+
* Allow calling Model.create_table, .create_table! and .create_table? with blocks containing the schema in the schema plugin (jfirebaugh)
|
6
|
+
|
7
|
+
* Fix handling of a :conditions options in the rcte plugin (mluu)
|
8
|
+
|
9
|
+
* Fix aggregate methods such as Dataset#sum and #avg on MSSQL on datasets with an order but no limit (mluu)
|
10
|
+
|
11
|
+
* Fix rename_table on MSSQL for case sensitive collations and schemas (mluu)
|
12
|
+
|
13
|
+
* Add a :single_root option to the tree plugin, for enforcing a single root value via a before_save hook (jfirebaugh)
|
14
|
+
|
15
|
+
* Add a Model#root? method to the tree plugin, for checking if the current node is a root (jfirebaugh)
|
16
|
+
|
17
|
+
* Add a :raise_on_failure option to Model#save to override the raise_on_save_failure setting (jfirebaugh)
|
18
|
+
|
19
|
+
* Handle class discriminator column names that are existing ruby method names in the single table inheritance plugin (jeremyevans)
|
20
|
+
|
21
|
+
* Fix times and datetimes when timezone support is used and you are loading a standard time when in daylight time or vice versa (gcampbell)
|
22
|
+
|
23
|
+
* Handle literalization of OCI8::CLOB objects in the native oracle adapter (jeremyevans)
|
24
|
+
|
25
|
+
* Raise a Sequel::Error instead of an ArgumentError if the migration current or target version does not exist (jeremyevans)
|
26
|
+
|
27
|
+
* Fix Database#schema on Oracle when the same table exists in multiple schemas (djwhitt)
|
28
|
+
|
29
|
+
* Fix Database#each_server when using a connection string to connect (jeremyevans)
|
30
|
+
|
31
|
+
* Make Model dataset's destroy method respect the model's use_transactions setting, instead of always using a transaction (jeremyevans)
|
32
|
+
|
33
|
+
* Add Database#adapter_scheme, for checking which adapter a Database uses (jeremyevans)
|
34
|
+
|
35
|
+
* Allow Dataset#grep to take :all_patterns, :all_columns, and :case_insensitive options (mighub, jeremyevans)
|
36
|
+
|
1
37
|
=== 3.13.0 (2010-07-01)
|
2
38
|
|
3
39
|
* Allow Model.find_or_create to take a block which is yielded the object to be created, if no object is found (zaius, jeremyevans)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Dataset#grep now accepts :all_patterns, :all_columns, and
|
4
|
+
:case_insensitive options. Previously, grep would use a case
|
5
|
+
sensitive search where it would match if any pattern matched any
|
6
|
+
column. These three options give you more control over how the
|
7
|
+
pattern matching will work:
|
8
|
+
|
9
|
+
dataset.grep([:a, :b], %w'%test% foo')
|
10
|
+
# WHERE ((a LIKE '%test%') OR (a LIKE 'foo')
|
11
|
+
# OR (b LIKE '%test%') OR (b LIKE 'foo'))
|
12
|
+
|
13
|
+
dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true)
|
14
|
+
# WHERE (((a LIKE '%foo%') OR (b LIKE '%foo%'))
|
15
|
+
# AND ((a LIKE '%bar%') OR (b LIKE '%bar%')))
|
16
|
+
|
17
|
+
dataset.grep([:a, :b], %w'%foo% %bar%', :all_columns=>true)
|
18
|
+
# WHERE (((a LIKE '%foo%') OR (a LIKE '%bar%'))
|
19
|
+
# AND ((b LIKE '%foo%') OR (b LIKE '%bar%')))
|
20
|
+
|
21
|
+
dataset.grep([:a, :b], %w'%foo% %bar%',
|
22
|
+
:all_patterns=>true,:all_columns=>true)
|
23
|
+
# WHERE ((a LIKE '%foo%') AND (b LIKE '%foo%')
|
24
|
+
# AND (a LIKE '%bar%') AND (b LIKE '%bar%'))
|
25
|
+
|
26
|
+
dataset.grep([:a, :b], %w'%test% foo', :case_insensitive=>true)
|
27
|
+
# WHERE ((a ILIKE '%test%') OR (a ILIKE 'foo')
|
28
|
+
# OR (b ILIKE '%test%') OR (b ILIKE 'foo'))
|
29
|
+
|
30
|
+
* When using the schema plugin, you can now provide a block to the
|
31
|
+
create_table methods to set the schema and create the table
|
32
|
+
in the same call:
|
33
|
+
|
34
|
+
class Artist < Sequel::Model
|
35
|
+
create_table do
|
36
|
+
primary_key :id
|
37
|
+
String :name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
* The tree plugin now accepts a :single_root option, which uses a
|
42
|
+
before_save hook to attempt to ensure that there is only a single
|
43
|
+
root in the tree. It also adds a Model.root method to get the
|
44
|
+
single root of the tree.
|
45
|
+
|
46
|
+
* The tree plugin now adds a Model#root? instance method to check
|
47
|
+
if the current node is a root of the tree.
|
48
|
+
|
49
|
+
* Model#save now takes a :raise_on_failure option which will
|
50
|
+
override the object's raise_on_save_failure setting. This makes
|
51
|
+
it easier to get the desired behavior (raise or just return false)
|
52
|
+
in library code without using a begin/ensure block.
|
53
|
+
|
54
|
+
* The Database#adapter_scheme instance method was added, which
|
55
|
+
operates the same as the class method.
|
56
|
+
|
57
|
+
* Sequel now handles the literalization of OCI8::CLOB objects in
|
58
|
+
the Oracle adapter.
|
59
|
+
|
60
|
+
= Other Improvements
|
61
|
+
|
62
|
+
* When using the timezone support, Sequel will now correctly load
|
63
|
+
times and datetimes in standard time when the current timezone is
|
64
|
+
in daylight time, or vice versa. Previously, if you tried to
|
65
|
+
to load a time or datetime in December when in July in a timezone
|
66
|
+
that used daylight time, it would be off by an hour.
|
67
|
+
|
68
|
+
* The rcte_tree plugin now works correctly when a :conditions option
|
69
|
+
is used.
|
70
|
+
|
71
|
+
* The single_table_inheritance plugin now works correctly when the
|
72
|
+
class discriminator column has the same name as an existing ruby
|
73
|
+
method (such as type).
|
74
|
+
|
75
|
+
* Database#each_server now works correctly when a connection string
|
76
|
+
is used to connect, instead of an options hash.
|
77
|
+
|
78
|
+
* Model#destroy now respects the object's use_transactions setting,
|
79
|
+
instead of always using a transaction.
|
80
|
+
|
81
|
+
* Model#exists? now uses a simpler and faster query.
|
82
|
+
|
83
|
+
* Sequel now handles the aggregate methods such as count and sum
|
84
|
+
correctly on Microsoft SQL Server when using an ordered dataset
|
85
|
+
with a clause such as DISTINCT or GROUP and without a limit.
|
86
|
+
|
87
|
+
* Sequel now handles rename_table correctly on Microsoft SQL Server
|
88
|
+
when using a case sensitive collation, or when qualifying the
|
89
|
+
table with a schema.
|
90
|
+
|
91
|
+
* Sequel now parses the schema correctly on Oracle when the same
|
92
|
+
table name is used in multiple schemas.
|
93
|
+
|
94
|
+
* Sequel now handles OCIInvalidHandle errors when disconnecting
|
95
|
+
in the Oracle adapter.
|
96
|
+
|
97
|
+
* Sequel now raises a Sequel::Error instead of an ArgumentError
|
98
|
+
if the current or target migration version does not exist.
|
99
|
+
|
100
|
+
* When a mismatched number of composite keys are used in
|
101
|
+
associations, Sequel now uses a more detailed error message.
|
102
|
+
|
103
|
+
* Significant improvements were made to the Dataset and Model
|
104
|
+
RDoc documentation.
|
105
|
+
|
106
|
+
= Backwards Compatibility
|
107
|
+
|
108
|
+
* Model#valid? now must accept an optional options hash.
|
109
|
+
|
110
|
+
* The Model#save_failure private method was renamed to
|
111
|
+
raise_hook_failure.
|
112
|
+
|
113
|
+
* The LOCAL_DATETIME_OFFSET_SECS and LOCAL_DATETIME_OFFSET constants
|
114
|
+
have been removed from the Sequel module.
|
115
|
+
|
116
|
+
* Sequel now uses obj.to_json instead of JSON.generate(obj). This
|
117
|
+
shouldn't affect backwards compatibility, but did fix a bug in
|
118
|
+
certain cases.
|
@@ -34,9 +34,9 @@ module Sequel
|
|
34
34
|
def schema_parse_table(table, opts={})
|
35
35
|
ds = dataset
|
36
36
|
ds.identifier_output_method = :downcase
|
37
|
-
|
37
|
+
schema_and_table = "#{"#{quote_identifier(opts[:schema])}." if opts[:schema]}#{quote_identifier(table)}"
|
38
38
|
table_schema = []
|
39
|
-
metadata = transaction(opts){|conn| conn.describe_table(
|
39
|
+
metadata = transaction(opts){|conn| conn.describe_table(schema_and_table)}
|
40
40
|
metadata.columns.each do |column|
|
41
41
|
table_schema << [
|
42
42
|
column.name.downcase.to_sym,
|
@@ -85,6 +85,8 @@ module Sequel
|
|
85
85
|
|
86
86
|
def disconnect_connection(c)
|
87
87
|
c.logoff
|
88
|
+
rescue OCIInvalidHandle
|
89
|
+
nil
|
88
90
|
end
|
89
91
|
|
90
92
|
def remove_transaction(conn)
|
@@ -122,6 +124,9 @@ module Sequel
|
|
122
124
|
case v
|
123
125
|
when OraDate
|
124
126
|
literal(Sequel.database_to_application_timestamp(v))
|
127
|
+
when OCI8::CLOB
|
128
|
+
v.rewind
|
129
|
+
literal(v.read)
|
125
130
|
else
|
126
131
|
super
|
127
132
|
end
|
@@ -67,7 +67,7 @@ module Sequel
|
|
67
67
|
when :add_column
|
68
68
|
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
69
69
|
when :rename_column
|
70
|
-
"
|
70
|
+
"sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(op[:new_name].to_s)}, 'COLUMN'"
|
71
71
|
when :set_column_type
|
72
72
|
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(op)}"
|
73
73
|
when :set_column_null
|
@@ -124,9 +124,9 @@ module Sequel
|
|
124
124
|
ds
|
125
125
|
end
|
126
126
|
|
127
|
-
# Use
|
127
|
+
# Use sp_rename to rename the table
|
128
128
|
def rename_table_sql(name, new_name)
|
129
|
-
"
|
129
|
+
"sp_rename #{literal(quote_schema_table(name))}, #{quote_identifier(schema_and_table(new_name).pop)}"
|
130
130
|
end
|
131
131
|
|
132
132
|
# SQL to rollback to a savepoint
|
@@ -373,6 +373,12 @@ module Sequel
|
|
373
373
|
def supports_window_functions?
|
374
374
|
true
|
375
375
|
end
|
376
|
+
|
377
|
+
protected
|
378
|
+
# MSSQL does not allow ordering in sub-clauses unless 'top' (limit) is specified
|
379
|
+
def aggregate_dataset
|
380
|
+
(options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
|
381
|
+
end
|
376
382
|
|
377
383
|
private
|
378
384
|
|
@@ -56,7 +56,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
56
56
|
@allocated[server].length + @available_connections[server].length
|
57
57
|
end
|
58
58
|
|
59
|
-
# Removes all
|
59
|
+
# Removes all connections currently available on all servers, optionally
|
60
60
|
# yielding each connection to the given block. This method has the effect of
|
61
61
|
# disconnecting from the database, assuming that no connections are currently
|
62
62
|
# being used. If connections are being used, they are scheduled to be
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# A connection pool allowing multi-threaded access to a pool of connections.
|
2
|
+
# This is the default connection pool used by Sequel.
|
2
3
|
class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
3
4
|
# The maximum number of connections this pool will create (per shard/server
|
4
5
|
# if sharding).
|
@@ -35,11 +36,10 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
35
36
|
@allocated.length + @available_connections.length
|
36
37
|
end
|
37
38
|
|
38
|
-
# Removes all
|
39
|
+
# Removes all connections currently available on all servers, optionally
|
39
40
|
# yielding each connection to the given block. This method has the effect of
|
40
41
|
# disconnecting from the database, assuming that no connections are currently
|
41
|
-
# being used.
|
42
|
-
# disconnected as soon as they are returned to the pool.
|
42
|
+
# being used.
|
43
43
|
#
|
44
44
|
# Once a connection is requested using #hold, the connection pool
|
45
45
|
# creates new connections to the database.
|
@@ -27,13 +27,13 @@ module Sequel
|
|
27
27
|
|
28
28
|
# make sure we actually loaded the adapter
|
29
29
|
unless klass = ADAPTER_MAP[scheme]
|
30
|
-
raise AdapterNotFound, "Could not load #{scheme} adapter"
|
30
|
+
raise AdapterNotFound, "Could not load #{scheme} adapter: adapter class not registered in ADAPTER_MAP"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
klass
|
34
34
|
end
|
35
35
|
|
36
|
-
# Returns the scheme for the Database class.
|
36
|
+
# Returns the scheme symbol for the Database class.
|
37
37
|
def self.adapter_scheme
|
38
38
|
@scheme
|
39
39
|
end
|
@@ -54,6 +54,7 @@ module Sequel
|
|
54
54
|
uri.query.split('&').collect{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
|
55
55
|
uri_options.entries.each{|k,v| uri_options[k] = URI.unescape(v) if v.is_a?(String)}
|
56
56
|
opts = uri_options.merge(opts)
|
57
|
+
opts[:adapter] = scheme
|
57
58
|
end
|
58
59
|
when Hash
|
59
60
|
opts = conn_string.merge(opts)
|
@@ -62,7 +63,7 @@ module Sequel
|
|
62
63
|
raise Error, "Sequel::Database.connect takes either a Hash or a String, given: #{conn_string.inspect}"
|
63
64
|
end
|
64
65
|
# process opts a bit
|
65
|
-
opts = opts.inject({}) do |m,
|
66
|
+
opts = opts.inject({}) do |m, (k,v)|
|
66
67
|
k = :user if k.to_s == 'username'
|
67
68
|
m[k.to_sym] = v
|
68
69
|
m
|
@@ -104,9 +105,20 @@ module Sequel
|
|
104
105
|
end
|
105
106
|
private_class_method :set_adapter_scheme
|
106
107
|
|
107
|
-
# The connection pool for this
|
108
|
+
# The connection pool for this Database instance. All Database instances have
|
109
|
+
# their own connection pools.
|
108
110
|
attr_reader :pool
|
109
111
|
|
112
|
+
# Returns the scheme symbol for this instance's class, which reflects which
|
113
|
+
# adapter is being used. In some cases, this can be the same as the
|
114
|
+
# +database_type+ (for native adapters), in others (i.e. adapters with
|
115
|
+
# subadapters), it will be different.
|
116
|
+
#
|
117
|
+
# Sequel.connect('jdbc:postgres://...').adapter_scheme # => :jdbc
|
118
|
+
def adapter_scheme
|
119
|
+
self.class.adapter_scheme
|
120
|
+
end
|
121
|
+
|
110
122
|
# Dynamically add new servers or modify server options at runtime. Also adds new
|
111
123
|
# servers to the connection pool. Intended for use with master/slave or shard
|
112
124
|
# configurations where it is useful to add new server hosts at runtime.
|
@@ -115,7 +127,7 @@ module Sequel
|
|
115
127
|
# proc values. If a servers key is already in use, it's value is overridden
|
116
128
|
# with the value provided.
|
117
129
|
#
|
118
|
-
#
|
130
|
+
# DB.add_servers(:f=>{:host=>"hash_host_f"})
|
119
131
|
def add_servers(servers)
|
120
132
|
@opts[:servers] = @opts[:servers] ? @opts[:servers].merge(servers) : servers
|
121
133
|
@pool.add_servers(servers.keys)
|
@@ -133,19 +145,27 @@ module Sequel
|
|
133
145
|
# type. Even better, you can tell that two Database objects that are using
|
134
146
|
# the same adapter are connecting to different database types (think JDBC or
|
135
147
|
# DataObjects).
|
148
|
+
#
|
149
|
+
# Sequel.connect('jdbc:postgres://...').database_type # => :postgres
|
136
150
|
def database_type
|
137
|
-
|
151
|
+
adapter_scheme
|
138
152
|
end
|
139
153
|
|
140
154
|
# Disconnects all available connections from the connection pool. Any
|
141
155
|
# connections currently in use will not be disconnected. Options:
|
142
156
|
# * :servers - Should be a symbol specifing the server to disconnect from,
|
143
157
|
# or an array of symbols to specify multiple servers.
|
158
|
+
#
|
159
|
+
# Example:
|
160
|
+
#
|
161
|
+
# DB.disconnect # All servers
|
162
|
+
# DB.disconnect(:servers=>:server1) # Single server
|
163
|
+
# DB.disconnect(:servers=>[:server1, :server2]) # Multiple servers
|
144
164
|
def disconnect(opts = {})
|
145
165
|
pool.disconnect(opts)
|
146
166
|
end
|
147
167
|
|
148
|
-
# Yield a new
|
168
|
+
# Yield a new Database instance for every server in the connection pool.
|
149
169
|
# Intended for use in sharded environments where there is a need to make schema
|
150
170
|
# modifications (DDL queries) on each shard.
|
151
171
|
#
|
@@ -175,6 +195,9 @@ module Sequel
|
|
175
195
|
end
|
176
196
|
|
177
197
|
# An array of servers/shards for this Database object.
|
198
|
+
#
|
199
|
+
# DB.servers # Unsharded: => [:default]
|
200
|
+
# DB.servers # Sharded: => [:default, :server1, :server2]
|
178
201
|
def servers
|
179
202
|
pool.servers
|
180
203
|
end
|
@@ -184,13 +207,27 @@ module Sequel
|
|
184
207
|
@single_threaded
|
185
208
|
end
|
186
209
|
|
187
|
-
# Acquires a database connection, yielding it to the passed block.
|
210
|
+
# Acquires a database connection, yielding it to the passed block. This is
|
211
|
+
# useful if you want to make sure the same connection is used for all
|
212
|
+
# database queries in the block. It is also useful if you want to gain
|
213
|
+
# direct access to the underlying connection object if you need to do
|
214
|
+
# something Sequel does not natively support.
|
215
|
+
#
|
216
|
+
# If a server option is given, acquires a connection for that specific
|
217
|
+
# server, instead of the :default server.
|
218
|
+
#
|
219
|
+
#
|
220
|
+
# DB.synchronize do |conn|
|
221
|
+
# ...
|
222
|
+
# end
|
188
223
|
def synchronize(server=nil, &block)
|
189
224
|
@pool.hold(server || :default, &block)
|
190
225
|
end
|
191
226
|
|
192
227
|
# Attempts to acquire a database connection. Returns true if successful.
|
193
|
-
# Will probably raise an
|
228
|
+
# Will probably raise an Error if unsuccessful. If a server argument
|
229
|
+
# is given, attempts to acquire a database connection to the given
|
230
|
+
# server/shard.
|
194
231
|
def test_connection(server=nil)
|
195
232
|
synchronize(server){|conn|}
|
196
233
|
true
|
@@ -207,7 +244,7 @@ module Sequel
|
|
207
244
|
# options for all server with the specific options for the given
|
208
245
|
# server specified in the :servers option.
|
209
246
|
def server_opts(server)
|
210
|
-
opts = if @opts[:servers]
|
247
|
+
opts = if @opts[:servers] and server_options = @opts[:servers][server]
|
211
248
|
case server_options
|
212
249
|
when Hash
|
213
250
|
@opts.merge(server_options)
|
@@ -222,6 +259,5 @@ module Sequel
|
|
222
259
|
opts.delete(:servers)
|
223
260
|
opts
|
224
261
|
end
|
225
|
-
|
226
262
|
end
|
227
263
|
end
|
@@ -5,10 +5,11 @@ module Sequel
|
|
5
5
|
# These methods all return instances of this database's dataset class.
|
6
6
|
# ---------------------
|
7
7
|
|
8
|
-
# Returns a dataset
|
8
|
+
# Returns a dataset for the database. If the first argument is a string,
|
9
9
|
# the method acts as an alias for Database#fetch, returning a dataset for
|
10
|
-
# arbitrary SQL:
|
10
|
+
# arbitrary SQL, with or without placeholders:
|
11
11
|
#
|
12
|
+
# DB['SELECT * FROM items'].all
|
12
13
|
# DB['SELECT * FROM items WHERE name = ?', my_name].all
|
13
14
|
#
|
14
15
|
# Otherwise, acts as an alias for Database#from, setting the primary
|
@@ -19,7 +20,10 @@ module Sequel
|
|
19
20
|
(String === args.first) ? fetch(*args) : from(*args)
|
20
21
|
end
|
21
22
|
|
22
|
-
# Returns a blank dataset for this database
|
23
|
+
# Returns a blank dataset for this database.
|
24
|
+
#
|
25
|
+
# DB.dataset # SELECT *
|
26
|
+
# DB.dataset.from(:items) # SELECT * FROM items
|
23
27
|
def dataset
|
24
28
|
ds = Sequel::Dataset.new(self)
|
25
29
|
end
|
@@ -29,11 +33,11 @@ module Sequel
|
|
29
33
|
#
|
30
34
|
# DB.fetch('SELECT * FROM items'){|r| p r}
|
31
35
|
#
|
32
|
-
# The method returns a dataset instance:
|
36
|
+
# The +fetch+ method returns a dataset instance:
|
33
37
|
#
|
34
38
|
# DB.fetch('SELECT * FROM items').all
|
35
39
|
#
|
36
|
-
#
|
40
|
+
# +fetch+ can also perform parameterized queries for protection against SQL
|
37
41
|
# injection:
|
38
42
|
#
|
39
43
|
# DB.fetch('SELECT * FROM items WHERE name = ?', my_name).all
|
@@ -43,14 +47,21 @@ module Sequel
|
|
43
47
|
ds
|
44
48
|
end
|
45
49
|
|
46
|
-
# Returns a new dataset with the from method invoked. If a block is given,
|
50
|
+
# Returns a new dataset with the +from+ method invoked. If a block is given,
|
47
51
|
# it is used as a filter on the dataset.
|
52
|
+
#
|
53
|
+
# DB.from(:items) # SELECT * FROM items
|
54
|
+
# DB.from(:items){id > 2} # SELECT * FROM items WHERE (id > 2)
|
48
55
|
def from(*args, &block)
|
49
56
|
ds = dataset.from(*args)
|
50
57
|
block ? ds.filter(&block) : ds
|
51
58
|
end
|
52
59
|
|
53
60
|
# Returns a new dataset with the select method invoked.
|
61
|
+
#
|
62
|
+
# DB.select(1) # SELECT 1
|
63
|
+
# DB.select{server_version{}} # SELECT server_version()
|
64
|
+
# DB.select(:id).from(:items) # SELECT id FROM items
|
54
65
|
def select(*args, &block)
|
55
66
|
dataset.select(*args, &block)
|
56
67
|
end
|