sequel 3.10.0 → 3.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/CHANGELOG +68 -0
  2. data/COPYING +1 -1
  3. data/README.rdoc +87 -27
  4. data/bin/sequel +2 -4
  5. data/doc/association_basics.rdoc +1383 -0
  6. data/doc/dataset_basics.rdoc +106 -0
  7. data/doc/opening_databases.rdoc +45 -16
  8. data/doc/querying.rdoc +210 -0
  9. data/doc/release_notes/3.11.0.txt +254 -0
  10. data/doc/virtual_rows.rdoc +217 -31
  11. data/lib/sequel/adapters/ado.rb +28 -12
  12. data/lib/sequel/adapters/ado/mssql.rb +33 -1
  13. data/lib/sequel/adapters/amalgalite.rb +13 -8
  14. data/lib/sequel/adapters/db2.rb +1 -2
  15. data/lib/sequel/adapters/dbi.rb +7 -4
  16. data/lib/sequel/adapters/do.rb +14 -15
  17. data/lib/sequel/adapters/do/postgres.rb +4 -5
  18. data/lib/sequel/adapters/do/sqlite.rb +9 -0
  19. data/lib/sequel/adapters/firebird.rb +5 -10
  20. data/lib/sequel/adapters/informix.rb +2 -4
  21. data/lib/sequel/adapters/jdbc.rb +111 -49
  22. data/lib/sequel/adapters/jdbc/mssql.rb +1 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +11 -0
  24. data/lib/sequel/adapters/jdbc/oracle.rb +4 -7
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +8 -1
  26. data/lib/sequel/adapters/jdbc/sqlite.rb +12 -0
  27. data/lib/sequel/adapters/mysql.rb +14 -5
  28. data/lib/sequel/adapters/odbc.rb +2 -4
  29. data/lib/sequel/adapters/odbc/mssql.rb +2 -4
  30. data/lib/sequel/adapters/openbase.rb +1 -2
  31. data/lib/sequel/adapters/oracle.rb +4 -8
  32. data/lib/sequel/adapters/postgres.rb +4 -11
  33. data/lib/sequel/adapters/shared/mssql.rb +22 -9
  34. data/lib/sequel/adapters/shared/mysql.rb +33 -30
  35. data/lib/sequel/adapters/shared/oracle.rb +0 -5
  36. data/lib/sequel/adapters/shared/postgres.rb +13 -11
  37. data/lib/sequel/adapters/shared/sqlite.rb +56 -10
  38. data/lib/sequel/adapters/sqlite.rb +16 -9
  39. data/lib/sequel/connection_pool.rb +6 -1
  40. data/lib/sequel/connection_pool/single.rb +1 -0
  41. data/lib/sequel/core.rb +6 -1
  42. data/lib/sequel/database.rb +52 -23
  43. data/lib/sequel/database/schema_generator.rb +6 -0
  44. data/lib/sequel/database/schema_methods.rb +5 -5
  45. data/lib/sequel/database/schema_sql.rb +1 -1
  46. data/lib/sequel/dataset.rb +4 -190
  47. data/lib/sequel/dataset/actions.rb +323 -1
  48. data/lib/sequel/dataset/features.rb +18 -2
  49. data/lib/sequel/dataset/graph.rb +7 -0
  50. data/lib/sequel/dataset/misc.rb +119 -0
  51. data/lib/sequel/dataset/mutation.rb +64 -0
  52. data/lib/sequel/dataset/prepared_statements.rb +6 -0
  53. data/lib/sequel/dataset/query.rb +272 -6
  54. data/lib/sequel/dataset/sql.rb +186 -394
  55. data/lib/sequel/model.rb +4 -2
  56. data/lib/sequel/model/associations.rb +31 -14
  57. data/lib/sequel/model/base.rb +32 -13
  58. data/lib/sequel/model/exceptions.rb +8 -4
  59. data/lib/sequel/model/plugins.rb +3 -13
  60. data/lib/sequel/plugins/active_model.rb +26 -7
  61. data/lib/sequel/plugins/instance_filters.rb +98 -0
  62. data/lib/sequel/plugins/many_through_many.rb +1 -1
  63. data/lib/sequel/plugins/optimistic_locking.rb +25 -9
  64. data/lib/sequel/version.rb +1 -1
  65. data/spec/adapters/mssql_spec.rb +26 -0
  66. data/spec/adapters/mysql_spec.rb +33 -4
  67. data/spec/adapters/postgres_spec.rb +24 -1
  68. data/spec/adapters/spec_helper.rb +6 -0
  69. data/spec/adapters/sqlite_spec.rb +28 -0
  70. data/spec/core/connection_pool_spec.rb +17 -5
  71. data/spec/core/database_spec.rb +101 -1
  72. data/spec/core/dataset_spec.rb +42 -4
  73. data/spec/core/schema_spec.rb +13 -0
  74. data/spec/extensions/active_model_spec.rb +34 -11
  75. data/spec/extensions/caching_spec.rb +2 -0
  76. data/spec/extensions/instance_filters_spec.rb +55 -0
  77. data/spec/extensions/spec_helper.rb +2 -0
  78. data/spec/integration/dataset_test.rb +12 -1
  79. data/spec/integration/model_test.rb +12 -0
  80. data/spec/integration/plugin_test.rb +61 -1
  81. data/spec/integration/schema_test.rb +14 -3
  82. data/spec/model/base_spec.rb +27 -0
  83. data/spec/model/plugins_spec.rb +0 -22
  84. data/spec/model/record_spec.rb +32 -1
  85. data/spec/model/spec_helper.rb +2 -0
  86. metadata +14 -3
  87. data/lib/sequel/dataset/convenience.rb +0 -326
@@ -0,0 +1,106 @@
1
+ = Dataset Basics
2
+
3
+ == Introduction
4
+
5
+ Datasets are probably the thing that separate Sequel from other database libraries. While most database libraries have specific support for updating all records or only a single record, Sequel's ability to represent SQL queries themselves as objects is what gives Sequel most of its power. However, if you haven't been exposed to the dataset concept before, it can be a little disorienting. This document aims to give a basic introduction to datasets and how to use them.
6
+
7
+ == What a Dataset Represents
8
+
9
+ A Dataset can be thought of representing one of two concepts:
10
+
11
+ * An SQL query
12
+ * An abstract set of rows and some related behavior
13
+
14
+ The first concept is more easily understood, so you should probably start with that assumption.
15
+
16
+ == Basics
17
+
18
+ The most basic dataset is the simple selection of all columns in a table:
19
+
20
+ ds = DB[:posts]
21
+ # SELECT * FROM posts
22
+
23
+ Here, DB represents your Sequel::Database object, and ds is your dataset, with the SQL query it represents below it.
24
+
25
+ One of the core dataset ideas that should be understood is that datasets use a functional style of modification, in which methods called on the dataset return modified copies of the dataset, they don't modify the dataset themselves:
26
+
27
+ ds2 = ds.filter(:id=>1)
28
+ ds2
29
+ # SELECT * FROM posts WHERE id = 1
30
+ ds
31
+ # SELECT * FROM posts
32
+
33
+ Note how ds itself is not modified. This is because ds.filter returns a modified copy of ds, instead of modifying ds itself. This makes using datasets both thread safe and easy to chain:
34
+
35
+ # Thread safe:
36
+ 100.times do |i|
37
+ Thread.new do
38
+ ds.filter(:id=>i).first
39
+ end
40
+ end
41
+
42
+ # Easy to chain:
43
+ ds3 = ds.select(:id, :name).order(:name).filter{id < 100}
44
+ # SELECT id, name FROM posts WHERE id < 100 ORDER BY name
45
+
46
+ Thread safety you don't really need to worry about, but chainability is core to how Sequel is generally used. Almost all dataset methods that affect the SQL produced return modified copies of the receiving dataset.
47
+
48
+ Another important thing to realize is that dataset methods that return modified datasets do not execute the dataset's code on the database. Only dataset methods that return or yield results will execute the code on the database:
49
+
50
+ # No SQL queries sent:
51
+ ds3 = ds.select(:id, :name).order(:name).filter{id < 100}
52
+
53
+ # Until you call a method that returns results
54
+ results = ds3.all
55
+
56
+ One important consequence of this API style is that if you use a method chain that includes both methods that return modified copies and a method that executes the SQL, the method that executes the SQL should generally be the last method in the chain:
57
+
58
+ # Good
59
+ ds.select(:id, :name).order(:name).filter{id < 100}.all
60
+
61
+ # Bad
62
+ ds.all.select(:id, :name).order(:name).filter{id < 100}
63
+
64
+ This is because all will return an array of hashes, and select, order, and filter are dataset methods, not array methods.
65
+
66
+ == Methods
67
+
68
+ Most Dataset methods that users will use can be broken down into two types:
69
+
70
+ * Methods that return modified datasets
71
+ * Methods that execute code on the database
72
+
73
+ === Methods that return modified datasets
74
+
75
+ Most dataset methods fall into this category, which can be further broken down by the clause they affect:
76
+
77
+ SELECT:: select, select_all, select_append, select_more
78
+ FROM:: from, from_self
79
+ JOIN:: join, join_table,
80
+ WHERE:: where, filter, exclude, and, or, grep, invert, unfiltered
81
+ GROUP:: group, group_by, group_and_count, ungrouped
82
+ HAVING:: having, filter, exclude, and, or, grep, invert, unfiltered
83
+ ORDER:: order, order_by, order_more, reverse, reverse_order, unordered
84
+ LIMIT:: limit
85
+ compounds:: union, intersect, except
86
+ locking:: for_update, lock_style
87
+ common table expressions:: with, with_recursive
88
+ qualification:: qualify, qualify_to, qualify_to_first_source
89
+ inserting:: set_defaults, set_overrides
90
+ other:: clone, distinct, naked, server, with_sql
91
+
92
+ === Methods that execute code on the database
93
+
94
+ Most other dataset methods commonly used will execute the dataset's SQL on the database:
95
+
96
+ SELECT (All Records):: all, each, map, to_hash, select_map, select_order_map, select_hash, to_csv
97
+ SELECT (First Record):: first, last, get, []
98
+ SELECT (Aggregates):: count, avg, max, min, sum, range, interval
99
+ INSERT:: insert, <<, import, multi_insert, insert_multiple
100
+ UPDATE:: update, set, []=
101
+ DELETE:: delete
102
+ other:: columns, columns!, truncate
103
+
104
+ === Other methods
105
+
106
+ See the Sequel::Dataset RDoc for other methods that are less commonly used.
@@ -49,8 +49,8 @@ unless the first argument is a hash. So the following statements are equivalent
49
49
  == Passing a block to either method
50
50
 
51
51
  Both the Sequel.connect method and the specialized adapter methods take a block. If you
52
- provide a block to the method, Sequel will open the connection and pass it as an argument
53
- to the block. When the block is exited, Sequel will disconnect the database connection.
52
+ provide a block to the method, Sequel will create a Database object and pass it as an argument
53
+ to the block. When the block returns, Sequel will disconnect the database connection.
54
54
  For example:
55
55
 
56
56
  Sequel.connect('sqlite://blog.db'){|db| puts db[:users].count}
@@ -67,11 +67,13 @@ These options are shared by all adapters unless otherwise noted.
67
67
  * :loggers - An array of SQL loggers to log to
68
68
  * :password - The password for the user account
69
69
  * :servers - A hash with symbol keys and hash or proc values, used with master/slave/partitioned database configurations
70
- * :single_threaded - Whether to use the single-threaded (non-thread safe) connection pool
70
+ * :single_threaded - Whether to use a single-threaded (non-thread safe) connection pool
71
+ * :test - Whether to test that a valid database connection can be made (false by default)
71
72
  * :user - The user account name to use logging in
72
73
 
73
74
  The following options can be specified and are passed to the the database's internal connection pool.
74
75
 
76
+ * :after_connect - A proc called after a new connection is made, with the connection object (default: nil)
75
77
  * :max_connections - The maximum size of the connection pool (default: 4 connections on most databases)
76
78
  * :pool_sleep_time - The number of seconds to sleep before trying to acquire a connection again (default: 0.001 seconds)
77
79
  * :pool_timeout - The number of seconds to wait if a connection cannot be acquired before raising an error (default: 5 seconds)
@@ -92,14 +94,24 @@ on WIN32OLE library, so it isn't usable on other operating systems (except
92
94
  possibly through WINE, but that's fairly unlikely).
93
95
 
94
96
  The following options are supported:
95
- * :driver - The driver to use. The default if not specified is 'SQL Server'.
96
- * :command_timeout - Sets the time in seconds to wait while attempting
97
- to execute a command before cancelling the attempt and generating
98
- an error. Specifically, it sets the ADO CommandTimeout property.
99
- If this property is not set, the default of 30 seconds is used.
100
- * :conn_string - The full ADO connection string. If this is provided,
101
- the general connection options are ignored.
102
- * :provider - Sets the Provider of this ADO connection (for example, "SQLOLEDB")
97
+
98
+ :command_timeout :: Sets the time in seconds to wait while attempting
99
+ to execute a command before cancelling the attempt and generating
100
+ an error. Specifically, it sets the ADO CommandTimeout property.
101
+ If this property is not set, the default of 30 seconds is used.
102
+ :driver :: The driver to use in the ADO connection string. If not provided, a default
103
+ of "SQL Server" is used.
104
+ :conn_string :: The full ADO connection string. If this is provided,
105
+ the usual options are ignored.
106
+ :provider :: Sets the Provider of this ADO connection (for example, "SQLOLEDB").
107
+ If you don't specify a provider, the default one used by WIN32OLE
108
+ has major problems, such as creating a new native database connection
109
+ for every query, which breaks things such as transactions and temporary tables.
110
+
111
+ Pay special attention to the :provider option, as without specifying a provider,
112
+ many things will be broken. The SQLNCLI10 provider appears to work well if you
113
+ are connecting to Microsoft SQL Server, but it is not the default as that would
114
+ break backwards compatability.
103
115
 
104
116
  === amalgalite
105
117
 
@@ -188,9 +200,9 @@ Requires: java
188
200
  Houses Sequel's JDBC support when running on JRuby.
189
201
  Support for individual database types is done using sub adapters.
190
202
  There are currently subadapters for PostgreSQL, MySQL, SQLite, H2,
191
- Oracle, and MSSQL. All except Oracle and MSSQL can load the
192
- JDBC gem, for those you need to have the .jar in your CLASSPATH
193
- or load the Java class manually.
203
+ Oracle, MSSQL, JTDS, and AS400. All except Oracle, MSSQL, and AS400 can load the
204
+ jdbc-* gem, for those you need to have the .jar in your CLASSPATH
205
+ or load the Java class manually before calling Sequel.connect.
194
206
 
195
207
  You just use the JDBC connection string directly, which can be specified
196
208
  via the string given to Sequel.connect or via the :uri, :url, or :database options.
@@ -198,12 +210,27 @@ Sequel does no preprocessing of the string, it passes it directly to JDBC.
198
210
  So if you have problems getting a connection string to work, look up the JDBC
199
211
  documentation.
200
212
 
201
- Example connections strings:
213
+ Note that when using a JDBC adapter, the best way to use Sequel
214
+ is via Sequel.connect, NOT Sequel.jdbc. Use the JDBC connection
215
+ string when connecting, which will be in a different format than
216
+ the native connection string. The connection string should start
217
+ with 'jdbc:'. For PostgreSQL, use 'jdbc:postgresql:', and for
218
+ SQLite you do not need 2 preceding slashes for the database name
219
+ (use no preceding slashes for a relative path, and one preceding
220
+ slash for an absolute path).
221
+
222
+ Example connection strings:
202
223
 
203
224
  jdbc:sqlite::memory:
204
225
  jdbc:postgresql://localhost/database?user=username
205
226
  jdbc:mysql://localhost/test?user=root&password=root
206
227
  jdbc:h2:mem:
228
+ jdbc:sqlserver://localhost;database=sequel_test;integratedSecurity=true
229
+ jdbc:jtds:sqlserver://localhost/sequel_test;user=sequel_test;password=sequel_test
230
+
231
+ You can also use JNDI connection strings:
232
+
233
+ jdbc:jndi:java:comp/env/jndi_resource_name
207
234
 
208
235
  The following additional options are supported:
209
236
 
@@ -214,7 +241,7 @@ The following additional options are supported:
214
241
 
215
242
  === mysql
216
243
 
217
- The MySQL adapter does not support the pure-ruby MySQL adapter that ships with
244
+ The MySQL adapter does not support the pure-ruby MySQL adapter that used to ship with
218
245
  ActiveRecord, it requires the native adapter.
219
246
 
220
247
  The following additional options are supported:
@@ -222,6 +249,8 @@ The following additional options are supported:
222
249
  * :auto_is_null - If set to true, makes "WHERE primary_key IS NULL" select the last inserted id.
223
250
  * :charset - Same as :encoding, :encoding takes precedence.
224
251
  * :compress - Whether to compress data sent/received via the socket connection.
252
+ * :config_default_group - The default group to read from the in the MySQL config file.
253
+ * :config_local_infile - If provided, sets the Mysql::OPT_LOCAL_INFILE option on the connection with the given value.
225
254
  * :encoding - Specify the encoding/character set to use for the connection.
226
255
  * :socket - Can be used to specify a Unix socket file to connect to instead of a TCP host and port.
227
256
  * :timeout - Sets the wait_timeout for the connection, defaults to 1 month.
data/doc/querying.rdoc ADDED
@@ -0,0 +1,210 @@
1
+ = Querying in Sequel
2
+
3
+ This guide is based on http://guides.rubyonrails.org/active_record_querying.html
4
+
5
+ == Purpose of this Guide
6
+
7
+ Sequel is a simple to use, very flexible, and powerful database library
8
+ that supports a wide variety of different querying methods. This guide
9
+ aims to be a gentle introduction to Sequel's querying support.
10
+
11
+ While you can easily use raw SQL with Sequel, a large part of the
12
+ advantage you get from using Sequel is Sequel's ability to abstract
13
+ SQL from you and give you a much nicer interface.
14
+
15
+ == Setup
16
+
17
+ Some examples in this guide assume you will be using Sequel::Model
18
+ for modeling, but most should work with plain datasets. The examples
19
+ specific to Sequel::Model will have [Sequel::Model] in the heading.
20
+
21
+ Many of the examples in this guide will refer to the following model
22
+ classes:
23
+
24
+ # All classes use :id as the primary key column
25
+
26
+ class Artist < Sequel::Model
27
+ one_to_many :albums
28
+ one_to_one :address
29
+ end
30
+
31
+ class Album < Sequel::Model
32
+ many_to_one :artist
33
+ one_to_many :tracks
34
+ many_to_many :tags
35
+ end
36
+
37
+ class Address < Sequel::Model
38
+ many_to_one :artist
39
+ end
40
+
41
+ class Tag < Sequel::Model
42
+ many_to_many :albums
43
+ end
44
+
45
+ class Track < Sequel::Model
46
+ many_to_one :album
47
+ end
48
+
49
+ If you want to play with the code examples, here's some Sequel code
50
+ that will set up the database structure for you:
51
+
52
+ DB.create_table(:artists) do
53
+ primary_key :id
54
+ String :name
55
+ end
56
+
57
+ DB.create_table(:albums) do
58
+ primary_key :id
59
+ foreign_key :artist_id, :artists
60
+ String :name
61
+ end
62
+
63
+ DB.create_table(:addresses) do
64
+ primary_key :id
65
+ foreign_key :artist_id, :artists, :unique=>true
66
+ String :street
67
+ String :city
68
+ String :state
69
+ String :zip
70
+ end
71
+
72
+ DB.create_table(:tags) do
73
+ primary_key :id
74
+ String :tag
75
+ end
76
+
77
+ DB.create_table(:albums_tags) do
78
+ foreign_key :album_id, :albums
79
+ foreign_key :tag_id, :tags
80
+ end
81
+
82
+ DB.create_table(:tracks) do
83
+ primary_key :id
84
+ foreign_key :album_id, :albums
85
+ Integer :number
86
+ String :name
87
+ end
88
+
89
+ == Retrieving Objects
90
+
91
+ Sequel provides a few separate methods for retrieving objects from the
92
+ database. The underlying method is Sequel::Dataset#each, which yields each
93
+ row as the Sequel::Database provides it. However, while Dataset#each can and
94
+ often is used directly, in many cases there is a more convenient retrieval
95
+ method you can use.
96
+
97
+ === Sequel::Dataset
98
+
99
+ If you are new to Sequel and aren't familiar with Sequel, you should probably
100
+ read the {"Dataset Basics" guide}[link:files/doc/dataset_basics_rdoc.html],
101
+ then come back here.
102
+
103
+ === Retrieving a Single Object
104
+
105
+ Sequel offers quite a few ways to to retrieve a single object.
106
+
107
+ ==== Using a Primary Key [Sequel::Model]
108
+
109
+ The <tt>Sequel::Model.[]</tt> is the easiest method to use to find a model instance
110
+ by its primary key value:
111
+
112
+ # Find artist with primary key (id) 1
113
+ artist = Artist[1]
114
+ # SQL: SELECT * FROM artists WHERE id = 1
115
+ => #<Artist @values={:name=>"YJM", :id=>1}>
116
+
117
+ If there is no record with the given primary key, nil will be returned.
118
+
119
+ ==== Using +first+
120
+
121
+ If you just want the first record in the dataset,
122
+ <tt>Sequel::Dataset#first</tt> is probably the most obvious method to use:
123
+
124
+ artist = Artist.first
125
+ # SQL: SELECT * FROM artists LIMIT 1
126
+ => #<Artist @values={:name=>"YJM", :id=>1}>
127
+
128
+ Any options you pass to +first+ will be used as a filter:
129
+
130
+ artist = Artist.first(:name => 'YJM')
131
+ # SQL: SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
132
+ => #<Artist @values={:name=>"YJM", :id=>1}>
133
+
134
+ artist = Artist.first(:name.like('Y%'))
135
+ # SQL: SELECT * FROM artists WHERE (name LIKE 'Y%') LIMIT 1
136
+ => #<Artist @values={:name=>"YJM", :id=>1}>
137
+
138
+ <tt>Sequel::Dataset#[]</tt> is basically an alias for +first+, except it
139
+ requires an argument:
140
+
141
+ DB[:artists][:name => 'YJM']
142
+ # SQL: SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
143
+ => {:name=>"YJM", :id=>1}
144
+
145
+ Note that while Model.[] allows you to pass a primary key directly,
146
+ Dataset#[] does not.
147
+
148
+ ==== Using +last+
149
+
150
+ If you want the last record in the dataset,
151
+ <tt>Sequel::Dataset#last</tt> is an obvious method to use. Note first
152
+ that last requires that the dataset be ordered. Without an order, any
153
+ object can be considered the first as well as the last.
154
+
155
+ artist = Artist.order(:name).last
156
+ # SQL: SELECT * FROM artists ORDER BY name DESC LIMIT 1
157
+ => #<Artist @values={:name=>"YJM", :id=>1}>
158
+
159
+ Note that all +last+ does is reverse the order of the dataset and then
160
+ call +first+. This is why +last+ raises a Sequel::Error if there is no
161
+ order on the dataset, because otherwise it would provide the same record
162
+ as +first+, and most users would fine that confusing.
163
+
164
+ Note that +last+ is not necessarily going to give you the last record
165
+ in the dataset unless you give the dataset an unambiguous order.
166
+
167
+ ==== Retrieving a Single Column Value
168
+
169
+ Sometimes, intead of wanting an entire row, you only want the value of
170
+ a specific column. For this <tt>Sequel::Dataset#get</tt> is the method
171
+ you want:
172
+
173
+ artist_name = Artist.get(:name)
174
+ # SQL: SELECT name FROM artists LIMIT 1
175
+ => "YJM"
176
+
177
+ === Retrieving Multiple Objects
178
+
179
+ ==== As a Array of Hashes or Model Objects
180
+
181
+ In many cases, you want an array of all of the rows associated with the
182
+ dataset, in which case <tt>Sequel::Dataset#all</tt> is the method you
183
+ want to use:
184
+
185
+ artists = Artist.all
186
+ # SQL: SELECT * FROM artists
187
+ => [#<Artist @values={:name=>"YJM", :id=>1}>,
188
+ #<Artist @values={:name=>"AS", :id=>2}>]
189
+
190
+ ==== Using an Enumerable Interface
191
+
192
+ <tt>Sequel::Dataset</tt> uses an Enumerable Interface, so it provides a
193
+ method named each that yields hashes or model objects as they are retrieved
194
+ from the database:
195
+
196
+ Artist.each{|x| p x.name}
197
+ # SQL: SELECT * FROM artists
198
+ "YJM"
199
+ "AS"
200
+
201
+ This means that all of the methods in the Enumerable module are available,
202
+ such as +map+:
203
+
204
+ artist_names = Artist.map{|x| x.name}
205
+ # SQL: SELECT * FROM artists
206
+ => ["YJM", "AS"]
207
+
208
+ ==== As an Array of Column Values
209
+
210
+ At 1.2.2 in Rails Guide
@@ -0,0 +1,254 @@
1
+ = New Features
2
+
3
+ * A few new features were added to query logging. Sequel now
4
+ includes execution time when logging queries. Queries that
5
+ raise exceptions are now logged at ERROR level. You can now
6
+ set the log_warn_duration attribute on the Database instance
7
+ and queries that take longer than that will be logged at WARN
8
+ level. By using different log levels, you can now only log
9
+ queries that raise errors, or only log queries that take a long
10
+ time.
11
+
12
+ # The default - Log all successful queries at INFO level
13
+ DB.log_warn_duration = nil
14
+
15
+ # Log all successful queries at WARN level
16
+ DB.log_warn_duration = 0
17
+
18
+ # Log successful queries that take the database more than half a
19
+ # second at WARN level, other successful queries at INFO level
20
+ DB.log_warn_duration = 0.5
21
+
22
+ All adapters included with Sequel have been modified to support
23
+ the new logging API. The previous API is still available, so
24
+ any external adapters should still work, though switching to the
25
+ new logging API is encouraged.
26
+
27
+ * Sequel::Model now has a require_modification flag. If not set
28
+ explicitly, it is enabled by default if the dataset provides an
29
+ accurate number of rows matched by an update or delete statement.
30
+ When this setting is enabled, Sequel will raise an exception if
31
+ you attempt to update or delete a model object and it doesn't end
32
+ up affecting exactly one row. For example:
33
+
34
+ DB.create_table(:as){primary_key :id}
35
+ class A < Sequel::Model; end
36
+ a = A.create
37
+
38
+ # delete object from database
39
+ a.delete
40
+
41
+ a.require_modification = false
42
+ a.save # no error!
43
+ a.delete # no error!
44
+
45
+ a.require_modification = true
46
+ a.save # Sequel::NoExistingObject exception raised
47
+ a.delete # Sequel::NoExistingObject exception raised
48
+
49
+ Like many other Sequel::Model settings, this can be set on a
50
+ global, per class, and per instance level:
51
+
52
+ Sequel::Model.require_modification = false # global
53
+ Album.require_modification = true # class
54
+ album.require_modification = false # instance
55
+
56
+ * An instance_filters plugin was added to the list of built in
57
+ plugins, allowing you to add arbitrary filters when updating or
58
+ destroying an instance. This allows you to continue using models
59
+ when previously you would have had to drop down to using datasets
60
+ to get the desired behavior:
61
+
62
+ class Item < Sequel::Model
63
+ plugin :instance_filters
64
+ end
65
+
66
+ # These are two separate objects that represent the same
67
+ # database row.
68
+ i1 = Item.first(:id=>1, :delete_allowed=>false)
69
+ i2 = Item.first(:id=>1, :delete_allowed=>false)
70
+
71
+ # Add an instance filter to the object. This filter is in effect
72
+ # until the object is successfully updated or deleted.
73
+ i1.instance_filter(:delete_allowed=>true)
74
+
75
+ # Attempting to delete the object where the filter doesn't
76
+ # match any rows raises an error.
77
+ i1.delete # raises Sequel::Error
78
+
79
+ # The other object that represents the same row has no
80
+ # instance filters, and can be updated normally.
81
+ i2.update(:delete_allowed=>true)
82
+
83
+ # Even though the filter is now still in effect, since the
84
+ # database row has been updated to allow deleting,
85
+ # delete now works.
86
+ i1.delete
87
+
88
+ * An :after_connect database option is now supported. If provided,
89
+ the option value should be a proc that takes a single argument.
90
+ It will be called with the underlying connection object before
91
+ connection object is added to the connection pool, allowing you
92
+ to set per connection options in a thread-safe manner.
93
+
94
+ This is useful for customizations you want set on every connection
95
+ that Sequel doesn't already support. For example, on PostgreSQL
96
+ if you wanted to set the schema search_path on every connection:
97
+
98
+ DB = Sequel.postgres('dbname', :after_connect=>(proc do |conn|
99
+ conn.execute('SET search_path TO schema1,schema2')
100
+ end))
101
+
102
+ * A :test database option is now supported. If set to true, it
103
+ automatically calls test_connection to make sure a connection can
104
+ be made before returning a Database instance. For backwards
105
+ compatibility reasons, this is not set to true by default, but it
106
+ is possible that the default will change in a future version of
107
+ Sequel.
108
+
109
+ * The Dataset#select_append method was added, which always appends
110
+ to the existing selected columns. It operates identically to
111
+ select_more, except in the case that no columns are currently
112
+ selected:
113
+
114
+ ds = DB[:a]
115
+ # SELECT * FROM items
116
+ ds.select_more({:id=>DB[:b].select(:a_id)}.as(:in_b))
117
+ # SELECT id IN (SELECT a_id FROM b) AS in_b FROM a
118
+ ds.select_append({:id=>DB[:b].select(:a_id)}.as(:in_b))
119
+ # SELECT *, id IN (SELECT a_id FROM b) AS in_b FROM a
120
+
121
+ * The Dataset#provides_accurate_rows_matched? method was added which
122
+ allows you to see if the dataset will return the actual number of
123
+ rows matched/affected by an update or delete call.
124
+
125
+ * Sequel will now emulate DISTINCT ON support using GROUP BY on
126
+ MySQL. On MySQL, GROUP BY is similar to DISTINCT ON, except that
127
+ the order of returned rows is not deterministic.
128
+
129
+ * Support for connecting to Microsoft SQL Server using the JTDS JDBC
130
+ driver was added to the jdbc adapter.
131
+
132
+ * JDNI connection strings are now supported in the JDBC adapter.
133
+
134
+ * The JDBC adapter should now work in situations where driver
135
+ auto-loading has problems, just as when using Tomcat or Trinidad.
136
+
137
+ * Sequel's JDBC adapter schema parsing now supports a :scale option,
138
+ useful for numeric/decimal columns.
139
+
140
+ * Sequel's schema parsing on Microsoft SQL Server now supports
141
+ :column_size and :scale options.
142
+
143
+ * When connecting to SQLite, a Database#sqlite_version method is
144
+ available that gives you the SQLite version as an integer (e.g.
145
+ 30613 for 3.6.13).
146
+
147
+ = Other Improvements
148
+
149
+ * Sequel no longer raises an error if you give Dataset#filter or
150
+ related method an empty argument such as {}, [], or ''. This allows
151
+ code such as the following to work:
152
+
153
+ h = {}
154
+ h[:name] = name if name
155
+ h[:number] = number if number
156
+ ds = ds.filter(h)
157
+
158
+ Before, this would raise an error if both name and number were
159
+ nil.
160
+
161
+ * Numeric and decimal columns with a 0 scale are now treated as
162
+ integer columns by the model typecasting code, since such columns
163
+ cannot store non-integer values.
164
+
165
+ * Calling Database#disconnect when using the single threaded
166
+ connection pool no longer raises an error if there is no current
167
+ connection.
168
+
169
+ * When using the :ignore_index_errors options to
170
+ Database#create_table, correctly swallow errors raised by Sequel
171
+ due to the adapter not supporting the given index type.
172
+
173
+ * The JDBC adapter no longer leaks ResultSets when retrieving
174
+ metadata.
175
+
176
+ * You can now connect to PostgreSQL when using ruby 1.9 with the
177
+ -Ku switch.
178
+
179
+ * When using the native MySQL adapter, only tinyint(1) columns are
180
+ now returned as booleans when using the convert_tinyint_to_bool
181
+ setting (the default). Previously, all tinyint columns would
182
+ be converted to booleans if the setting was enabled.
183
+
184
+ * Correctly handle inserts returning the autogenerated keys when
185
+ using MySQL JDBC Driver version 5.1.12 with the jdbc adapter.
186
+
187
+ * The native MySQL adapter now supports :config_default_group and
188
+ :config_local_infile options.
189
+
190
+ * When connecting to SQLite, you can provide the :auto_vacuum,
191
+ :foreign_keys, :synchronous, and :temp_store options for
192
+ making the appropriate PRAGMA setting on the database in a
193
+ thread-safe manner. The previous thread-unsafe PRAGMA setting
194
+ methods are available, but their use is discouraged.
195
+
196
+ * Sequel will not enable savepoints when connecting to SQLite
197
+ unless the version is 3.6.8 or greater.
198
+
199
+ * Using limit with distinct now works correctly on Microsoft SQL
200
+ Server.
201
+
202
+ * Database#rename_table now works correctly on Microsoft SQL Server.
203
+
204
+ * If you specify an explicit :provider when using the ADO adapter,
205
+ transactions will now work correctly. The default :provider uses
206
+ a new native connection for each query, so it cannot work with
207
+ transactions, or things like temporary tables.
208
+
209
+ * If you specify an explicit :provider when connecting to Microsoft
210
+ SQL Server using the ADO adapter (e.g. SQLNCLI10 or SQLNCLI),
211
+ Sequel is now able to provide an accurate number of rows modified
212
+ and deleted.
213
+
214
+ * Using set_column_allow_null with a decimal column with a precision
215
+ and scale now works correctly when connecting to Microsoft SQL
216
+ Server.
217
+
218
+ * You can now connect to Microsoft SQL Server using the dbi adapter.
219
+
220
+ * Sequel now recognizes the NUMBER database type as a synonym for
221
+ NUMERIC and DECIMAL, which may help some Oracle users.
222
+
223
+ * Transactions can now be rolled back correctly when connecting to
224
+ Oracle via JDBC.
225
+
226
+ * The active_model plugin now supports ActiveModel 3.0.0beta2.
227
+
228
+ * Many documentation improvements were made, including the addition
229
+ of a dataset basics guide, an association basics guide, an expanded
230
+ virtual row guide, and the separation of the Sequel::Dataset RDoc
231
+ page into sections. Additional, the RDoc class/method
232
+ documentation now contains links to the appropriate guides.
233
+
234
+ = Backwards Compatibility
235
+
236
+ * When connecting to SQLite, Sequel now automatically sets the
237
+ foreign_keys PRAGMA to true, which will make SQLite 3.6.19+ use
238
+ database enforced foreign key constraints. If you do not want
239
+ the database to enforce the foreign key constraints, you should
240
+ use the :foreign_keys=>false option when connecting to the
241
+ database.
242
+
243
+ * Sequel no longer creates #{plugin_name}_opts class, instance, and
244
+ dataset methods for each plugin loaded. No built-in plugin used
245
+ them, and I couldn't find an external plugin that did either.
246
+
247
+ * The Model#associations method is no longer available if the
248
+ default Associations plugin is not loaded due to the
249
+ SEQUEL_NO_ASSOCIATIONS constant or environment variable being set.
250
+
251
+ * DISTINCT ON support is turned off by default, and only enabled when
252
+ using PostgreSQL, since that appears to be the only database that
253
+ supports it. Previously, it was enabled by default and most common
254
+ adapters turned it off.