sequel 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1551 -4
- data/README +306 -19
- data/Rakefile +84 -56
- data/bin/sequel +106 -0
- data/doc/cheat_sheet.rdoc +225 -0
- data/doc/dataset_filtering.rdoc +182 -0
- data/lib/sequel_core.rb +136 -0
- data/lib/sequel_core/adapters/adapter_skeleton.rb +54 -0
- data/lib/sequel_core/adapters/ado.rb +80 -0
- data/lib/sequel_core/adapters/db2.rb +148 -0
- data/lib/sequel_core/adapters/dbi.rb +117 -0
- data/lib/sequel_core/adapters/informix.rb +78 -0
- data/lib/sequel_core/adapters/jdbc.rb +186 -0
- data/lib/sequel_core/adapters/jdbc/mysql.rb +55 -0
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +66 -0
- data/lib/sequel_core/adapters/jdbc/sqlite.rb +47 -0
- data/lib/sequel_core/adapters/mysql.rb +231 -0
- data/lib/sequel_core/adapters/odbc.rb +155 -0
- data/lib/sequel_core/adapters/odbc_mssql.rb +106 -0
- data/lib/sequel_core/adapters/openbase.rb +64 -0
- data/lib/sequel_core/adapters/oracle.rb +170 -0
- data/lib/sequel_core/adapters/postgres.rb +199 -0
- data/lib/sequel_core/adapters/shared/mysql.rb +275 -0
- data/lib/sequel_core/adapters/shared/postgres.rb +351 -0
- data/lib/sequel_core/adapters/shared/sqlite.rb +146 -0
- data/lib/sequel_core/adapters/sqlite.rb +138 -0
- data/lib/sequel_core/connection_pool.rb +194 -0
- data/lib/sequel_core/core_ext.rb +203 -0
- data/lib/sequel_core/core_sql.rb +184 -0
- data/lib/sequel_core/database.rb +471 -0
- data/lib/sequel_core/database/schema.rb +156 -0
- data/lib/sequel_core/dataset.rb +457 -0
- data/lib/sequel_core/dataset/callback.rb +13 -0
- data/lib/sequel_core/dataset/convenience.rb +245 -0
- data/lib/sequel_core/dataset/pagination.rb +96 -0
- data/lib/sequel_core/dataset/query.rb +41 -0
- data/lib/sequel_core/dataset/schema.rb +15 -0
- data/lib/sequel_core/dataset/sql.rb +889 -0
- data/lib/sequel_core/deprecated.rb +26 -0
- data/lib/sequel_core/exceptions.rb +42 -0
- data/lib/sequel_core/migration.rb +187 -0
- data/lib/sequel_core/object_graph.rb +216 -0
- data/lib/sequel_core/pretty_table.rb +71 -0
- data/lib/sequel_core/schema.rb +2 -0
- data/lib/sequel_core/schema/generator.rb +239 -0
- data/lib/sequel_core/schema/sql.rb +325 -0
- data/lib/sequel_core/sql.rb +812 -0
- data/lib/sequel_model.rb +5 -1
- data/lib/sequel_model/association_reflection.rb +3 -8
- data/lib/sequel_model/base.rb +15 -10
- data/lib/sequel_model/inflector.rb +3 -5
- data/lib/sequel_model/plugins.rb +1 -1
- data/lib/sequel_model/record.rb +11 -3
- data/lib/sequel_model/schema.rb +4 -4
- data/lib/sequel_model/validations.rb +6 -1
- data/spec/adapters/ado_spec.rb +17 -0
- data/spec/adapters/informix_spec.rb +96 -0
- data/spec/adapters/mysql_spec.rb +764 -0
- data/spec/adapters/oracle_spec.rb +222 -0
- data/spec/adapters/postgres_spec.rb +441 -0
- data/spec/adapters/spec_helper.rb +7 -0
- data/spec/adapters/sqlite_spec.rb +400 -0
- data/spec/integration/dataset_test.rb +51 -0
- data/spec/integration/eager_loader_test.rb +702 -0
- data/spec/integration/schema_test.rb +102 -0
- data/spec/integration/spec_helper.rb +44 -0
- data/spec/integration/type_test.rb +43 -0
- data/spec/rcov.opts +2 -0
- data/spec/sequel_core/connection_pool_spec.rb +363 -0
- data/spec/sequel_core/core_ext_spec.rb +156 -0
- data/spec/sequel_core/core_sql_spec.rb +427 -0
- data/spec/sequel_core/database_spec.rb +964 -0
- data/spec/sequel_core/dataset_spec.rb +2977 -0
- data/spec/sequel_core/expression_filters_spec.rb +346 -0
- data/spec/sequel_core/migration_spec.rb +261 -0
- data/spec/sequel_core/object_graph_spec.rb +234 -0
- data/spec/sequel_core/pretty_table_spec.rb +58 -0
- data/spec/sequel_core/schema_generator_spec.rb +122 -0
- data/spec/sequel_core/schema_spec.rb +497 -0
- data/spec/sequel_core/spec_helper.rb +51 -0
- data/spec/{association_reflection_spec.rb → sequel_model/association_reflection_spec.rb} +6 -6
- data/spec/{associations_spec.rb → sequel_model/associations_spec.rb} +47 -18
- data/spec/{base_spec.rb → sequel_model/base_spec.rb} +2 -1
- data/spec/{caching_spec.rb → sequel_model/caching_spec.rb} +0 -0
- data/spec/{dataset_methods_spec.rb → sequel_model/dataset_methods_spec.rb} +13 -1
- data/spec/{eager_loading_spec.rb → sequel_model/eager_loading_spec.rb} +75 -14
- data/spec/{hooks_spec.rb → sequel_model/hooks_spec.rb} +4 -4
- data/spec/sequel_model/inflector_spec.rb +119 -0
- data/spec/{model_spec.rb → sequel_model/model_spec.rb} +30 -11
- data/spec/{plugins_spec.rb → sequel_model/plugins_spec.rb} +0 -0
- data/spec/{record_spec.rb → sequel_model/record_spec.rb} +47 -6
- data/spec/{schema_spec.rb → sequel_model/schema_spec.rb} +18 -4
- data/spec/{spec_helper.rb → sequel_model/spec_helper.rb} +3 -2
- data/spec/{validations_spec.rb → sequel_model/validations_spec.rb} +37 -17
- data/spec/spec_config.rb +9 -0
- data/spec/spec_config.rb.example +10 -0
- metadata +110 -37
- data/spec/inflector_spec.rb +0 -34
data/README
CHANGED
@@ -1,3 +1,309 @@
|
|
1
|
+
== Sequel: The Database Toolkit for Ruby
|
2
|
+
|
3
|
+
Sequel is a lightweight database access toolkit for Ruby.
|
4
|
+
|
5
|
+
* Sequel provides thread safety, connection pooling and a concise DSL
|
6
|
+
for constructing database queries and table schemas.
|
7
|
+
* Sequel also includes a lightweight but comprehensive ORM layer for
|
8
|
+
mapping records to Ruby objects and handling associated records.
|
9
|
+
* Sequel makes it easy to deal with multiple records without having
|
10
|
+
to break your teeth on SQL.
|
11
|
+
* Sequel currently has adapters for ADO, DB2, DBI, Informix, JDBC,
|
12
|
+
MySQL, ODBC, OpenBase, Oracle, PostgreSQL and SQLite3.
|
13
|
+
|
14
|
+
== Resources
|
15
|
+
|
16
|
+
* {Source code}[http://github.com/jeremyevans/sequel]
|
17
|
+
* {Bug tracking}[http://code.google.com/p/ruby-sequel/issues/list]
|
18
|
+
* {Google group}[http://groups.google.com/group/sequel-talk]
|
19
|
+
* {RDoc}[http://sequel.rubyforge.org]
|
20
|
+
|
21
|
+
To check out the source code:
|
22
|
+
|
23
|
+
git clone git://github.com/jeremyevans/sequel.git
|
24
|
+
|
25
|
+
=== Contact
|
26
|
+
|
27
|
+
If you have any comments or suggestions please post to the Google group.
|
28
|
+
|
29
|
+
== Installation
|
30
|
+
|
31
|
+
sudo gem install sequel
|
32
|
+
|
33
|
+
== A Short Example
|
34
|
+
|
35
|
+
require 'rubygems'
|
36
|
+
require 'sequel'
|
37
|
+
|
38
|
+
DB = Sequel.sqlite # memory database
|
39
|
+
|
40
|
+
DB.create_table :items do # Create a new table
|
41
|
+
column :name, :text
|
42
|
+
column :price, :float
|
43
|
+
end
|
44
|
+
|
45
|
+
items = DB[:items] # Create a dataset
|
46
|
+
|
47
|
+
# Populate the table
|
48
|
+
items << {:name => 'abc', :price => rand * 100}
|
49
|
+
items << {:name => 'def', :price => rand * 100}
|
50
|
+
items << {:name => 'ghi', :price => rand * 100}
|
51
|
+
|
52
|
+
# Print out the number of records
|
53
|
+
puts "Item count: #{items.count}"
|
54
|
+
|
55
|
+
# Print out the records in descending order by price
|
56
|
+
items.reverse_order(:price).print
|
57
|
+
|
58
|
+
# Print out the average price
|
59
|
+
puts "The average price is: #{items.avg(:price)}"
|
60
|
+
|
61
|
+
== The Sequel Console
|
62
|
+
|
63
|
+
Sequel includes an IRB console for quick'n'dirty access to databases. You can use it like this:
|
64
|
+
|
65
|
+
sequel sqlite://test.db # test.db in current directory
|
66
|
+
|
67
|
+
You get an IRB session with the database object stored in DB.
|
68
|
+
|
69
|
+
== An Introduction
|
70
|
+
|
71
|
+
Sequel is designed to take the hassle away from connecting to databases and manipulating them. Sequel deals with all the boring stuff like maintaining connections, formatting SQL correctly and fetching records so you can concentrate on your application.
|
72
|
+
|
73
|
+
Sequel uses the concept of datasets to retrieve data. A Dataset object encapsulates an SQL query and supports chainability, letting you fetch data using a convenient Ruby DSL that is both concise and infinitely flexible.
|
74
|
+
|
75
|
+
For example, the following one-liner returns the average GDP for the five biggest countries in the middle east region:
|
76
|
+
|
77
|
+
DB[:countries].filter(:region => 'Middle East').reverse_order(:area).limit(5).avg(:GDP)
|
78
|
+
|
79
|
+
Which is equivalent to:
|
80
|
+
|
81
|
+
SELECT avg(GDP) FROM countries WHERE region = 'Middle East' ORDER BY area DESC LIMIT 5
|
82
|
+
|
83
|
+
Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes (they can also be fetched as custom model objects), and are accessed using an Enumerable interface:
|
84
|
+
|
85
|
+
middle_east = DB[:countries].filter(:region => 'Middle East')
|
86
|
+
middle_east.order(:name).each {|r| puts r[:name]}
|
87
|
+
|
88
|
+
Sequel also offers convenience methods for extracting data from Datasets, such as an extended map method:
|
89
|
+
|
90
|
+
middle_east.map(:name) #=> ['Egypt', 'Greece', 'Israel', ...]
|
91
|
+
|
92
|
+
Or getting results as a transposed hash, with one column as key and another as value:
|
93
|
+
|
94
|
+
middle_east.to_hash(:name, :area) #=> {'Israel' => 20000, 'Greece' => 120000, ...}
|
95
|
+
|
96
|
+
== Getting Started
|
97
|
+
|
98
|
+
=== Connecting to a database
|
99
|
+
|
100
|
+
To connect to a database you simply provide Sequel with a URL:
|
101
|
+
|
102
|
+
require 'sequel'
|
103
|
+
DB = Sequel.connect('sqlite://blog.db')
|
104
|
+
|
105
|
+
The connection URL can also include such stuff as the user name and password:
|
106
|
+
|
107
|
+
DB = Sequel.connect('postgres://cico:12345@localhost:5432/mydb')
|
108
|
+
|
109
|
+
You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
|
110
|
+
|
111
|
+
DB = Sequel.connect("postgres://postgres:postgres@localhost/my_db",
|
112
|
+
:max_connections => 10, :loggers => [Logger.new('log/db.log']))
|
113
|
+
|
114
|
+
You can specify a block to connect, which will disconnect from the database after it completes:
|
115
|
+
|
116
|
+
Sequel.connect('postgres://cico:12345@localhost:5432/mydb'){|db| db[:posts].delete}
|
117
|
+
|
118
|
+
=== Arbitrary SQL queries
|
119
|
+
|
120
|
+
DB.execute("create table t (a text, b text)")
|
121
|
+
DB.execute("insert into t values ('a', 'b')")
|
122
|
+
|
123
|
+
Or more succinctly:
|
124
|
+
|
125
|
+
DB << "create table t (a text, b text)"
|
126
|
+
DB << "insert into t values ('a', 'b')"
|
127
|
+
|
128
|
+
You can also create datasets based on raw SQL:
|
129
|
+
|
130
|
+
dataset = DB['select * from items']
|
131
|
+
dataset.count # will return the number of records in the result set
|
132
|
+
dataset.map(:id) # will return an array containing all values of the id column in the result set
|
133
|
+
|
134
|
+
You can also fetch records with raw SQL through the dataset:
|
135
|
+
|
136
|
+
DB['select * from items'].each do |row|
|
137
|
+
p row
|
138
|
+
end
|
139
|
+
|
140
|
+
=== Getting Dataset Instances
|
141
|
+
|
142
|
+
Dataset is the primary means through which records are retrieved and manipulated. You can create an blank dataset by using the dataset method:
|
143
|
+
|
144
|
+
dataset = DB.dataset
|
145
|
+
|
146
|
+
Or by using the from methods:
|
147
|
+
|
148
|
+
posts = DB.from(:posts)
|
149
|
+
|
150
|
+
The recommended way is the equivalent shorthand:
|
151
|
+
|
152
|
+
posts = DB[:posts]
|
153
|
+
|
154
|
+
Datasets will only fetch records when you explicitly ask for them. Datasets can be manipulated to filter through records, change record order, join tables, etc..
|
155
|
+
|
156
|
+
=== Retrieving Records
|
157
|
+
|
158
|
+
You can retrieve records by using the all method:
|
159
|
+
|
160
|
+
posts.all
|
161
|
+
|
162
|
+
The all method returns an array of hashes, where each hash corresponds to a record.
|
163
|
+
|
164
|
+
You can also iterate through records one at a time:
|
165
|
+
|
166
|
+
posts.each{|row| p row}
|
167
|
+
|
168
|
+
Or perform more advanced stuff:
|
169
|
+
|
170
|
+
posts.map(:id)
|
171
|
+
posts.inject({}){|h, r| h[r[:id]] = r[:name]}
|
172
|
+
|
173
|
+
You can also retrieve the first record in a dataset:
|
174
|
+
|
175
|
+
posts.first
|
176
|
+
|
177
|
+
Or retrieve a single record with a specific value:
|
178
|
+
|
179
|
+
posts[:id => 1]
|
180
|
+
|
181
|
+
If the dataset is ordered, you can also ask for the last record:
|
182
|
+
|
183
|
+
posts.order(:stamp).last
|
184
|
+
|
185
|
+
=== Filtering Records
|
186
|
+
|
187
|
+
The simplest way to filter records is to provide a hash of values to match:
|
188
|
+
|
189
|
+
my_posts = posts.filter(:category => 'ruby', :author => 'david')
|
190
|
+
|
191
|
+
You can also specify ranges:
|
192
|
+
|
193
|
+
my_posts = posts.filter(:stamp => (Date.today - 14)..(Date.today - 7))
|
194
|
+
|
195
|
+
Or lists of values:
|
196
|
+
|
197
|
+
my_posts = posts.filter(:category => ['ruby', 'postgres', 'linux'])
|
198
|
+
|
199
|
+
Sequel also accepts expressions:
|
200
|
+
|
201
|
+
my_posts = posts.filter(:stamp > Date.today << 1)
|
202
|
+
|
203
|
+
Some adapters (like postgresql) will also let you specify Regexps:
|
204
|
+
|
205
|
+
my_posts = posts.filter(:category => /ruby/i)
|
206
|
+
|
207
|
+
You can also use an inverse filter:
|
208
|
+
|
209
|
+
my_posts = posts.exclude(:category => /ruby/i)
|
210
|
+
my_posts = posts.filter(:category => /ruby/i).invert # same as above
|
211
|
+
|
212
|
+
You can also specify a custom WHERE clause using a string:
|
213
|
+
|
214
|
+
posts.filter('stamp IS NOT NULL')
|
215
|
+
|
216
|
+
You can use parameters in your string, as well (ActiveRecord style):
|
217
|
+
|
218
|
+
posts.filter('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
|
219
|
+
posts.filter((:stamp < Date.today - 3) & ~(:author => author_name)) # same as above
|
220
|
+
|
221
|
+
Datasets can also be used as subqueries:
|
222
|
+
|
223
|
+
DB[:items].filter('price > ?', DB[:items].select('AVG(price) + 100'))
|
224
|
+
|
225
|
+
After filtering you can retrieve the matching records by using any of the retrieval methods:
|
226
|
+
|
227
|
+
my_posts.each{|row| p row}
|
228
|
+
|
229
|
+
See the doc/dataset_filtering.rdoc file for more details.
|
230
|
+
|
231
|
+
=== Summarizing Records
|
232
|
+
|
233
|
+
Counting records is easy:
|
234
|
+
posts.filter(:category => /ruby/i).count
|
235
|
+
|
236
|
+
And you can also query maximum/minimum values:
|
237
|
+
max_value = DB[:history].max(:value)
|
238
|
+
|
239
|
+
Or calculate a sum:
|
240
|
+
total = DB[:items].sum(:price)
|
241
|
+
|
242
|
+
=== Ordering Records
|
243
|
+
|
244
|
+
Ordering datasets is simple:
|
245
|
+
|
246
|
+
posts.order(:stamp) # ORDER BY stamp
|
247
|
+
posts.order(:stamp, :name) # ORDER BY stamp, name
|
248
|
+
|
249
|
+
You can also specify descending order
|
250
|
+
|
251
|
+
posts.order(:stamp.desc) # ORDER BY stamp DESC
|
252
|
+
|
253
|
+
=== Deleting Records
|
254
|
+
|
255
|
+
Deleting records from the table is done with delete:
|
256
|
+
|
257
|
+
posts.filter('stamp < ?', Date.today - 3).delete
|
258
|
+
|
259
|
+
=== Inserting Records
|
260
|
+
|
261
|
+
Inserting records into the table is done with insert:
|
262
|
+
|
263
|
+
posts.insert(:category => 'ruby', :author => 'david')
|
264
|
+
posts << {:category => 'ruby', :author => 'david'} # same as above
|
265
|
+
|
266
|
+
=== Updating Records
|
267
|
+
|
268
|
+
Updating records in the table is done with update:
|
269
|
+
|
270
|
+
posts.filter('stamp < ?', Date.today - 7).update(:state => 'archived')
|
271
|
+
|
272
|
+
=== Joining Tables
|
273
|
+
|
274
|
+
Joining is very useful in a variety of scenarios, for example many-to-many relationships. With Sequel it's really easy:
|
275
|
+
|
276
|
+
order_items = DB[:items].join(:order_items, :item_id => :id).
|
277
|
+
filter(:order_items__order_id => 1234)
|
278
|
+
|
279
|
+
This is equivalent to the SQL:
|
280
|
+
|
281
|
+
SELECT * FROM items LEFT OUTER JOIN order_items
|
282
|
+
ON order_items.item_id = items.id
|
283
|
+
WHERE order_items.order_id = 1234
|
284
|
+
|
285
|
+
You can then do anything you like with the dataset:
|
286
|
+
|
287
|
+
order_total = order_items.sum(:price)
|
288
|
+
|
289
|
+
Which is equivalent to the SQL:
|
290
|
+
|
291
|
+
SELECT sum(price) FROM items LEFT OUTER JOIN order_items
|
292
|
+
ON order_items.item_id = items.id
|
293
|
+
WHERE order_items.order_id = 1234
|
294
|
+
|
295
|
+
=== Graphing Datasets
|
296
|
+
|
297
|
+
When retrieving records from joined datasets, you get the results in a single hash, which is subject to clobbering:
|
298
|
+
|
299
|
+
DB[:items].join(:order_items, :item_id => :id).first
|
300
|
+
=> {:id=>(could be items.id or order_items.id), :item_id=>order_items.order_id}
|
301
|
+
|
302
|
+
Using graph, you can split the result hashes into subhashes, one per join:
|
303
|
+
|
304
|
+
DB[:items].graph(:order_items, :item_id => :id).first
|
305
|
+
=> {:items=>{:id=>items.id}, :order_items=>{:id=>order_items.id, :item_id=>order_items.item_id}}
|
306
|
+
|
1
307
|
== Sequel Models
|
2
308
|
|
3
309
|
Models in Sequel are based on the Active Record pattern described by Martin Fowler (http://www.martinfowler.com/eaaCatalog/activeRecord.html). A model class corresponds to a table or a dataset, and an instance of that class wraps a single record in the model's underlying dataset.
|
@@ -21,25 +327,6 @@ You can, however, explicitly set the table name or even the dataset used:
|
|
21
327
|
# or:
|
22
328
|
Post.set_dataset DB[:my_posts].where(:category => 'ruby')
|
23
329
|
|
24
|
-
=== Resources
|
25
|
-
|
26
|
-
* {Source code}[http://github.com/jeremyevans/sequel]
|
27
|
-
* {Bug tracking}[http://code.google.com/p/ruby-sequel/issues/list]
|
28
|
-
* {Google group}[http://groups.google.com/group/sequel-talk]
|
29
|
-
* {RDoc}[http://sequel.rubyforge.org]
|
30
|
-
|
31
|
-
To check out the source code:
|
32
|
-
|
33
|
-
git clone git://github.com/jeremyevans/sequel.git
|
34
|
-
|
35
|
-
=== Contact
|
36
|
-
|
37
|
-
If you have any comments or suggestions please post to the Google group.
|
38
|
-
|
39
|
-
=== Installation
|
40
|
-
|
41
|
-
sudo gem install sequel
|
42
|
-
|
43
330
|
=== Model instances
|
44
331
|
|
45
332
|
Model instance are identified by a primary key. By default, Sequel assumes the primary key column to be :id. The Model#[] method can be used to fetch records by their primary key:
|
data/Rakefile
CHANGED
@@ -3,33 +3,21 @@ require "rake/clean"
|
|
3
3
|
require "rake/gempackagetask"
|
4
4
|
require "rake/rdoctask"
|
5
5
|
require "fileutils"
|
6
|
+
require "spec/rake/spectask"
|
7
|
+
|
6
8
|
include FileUtils
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
##############################################################################
|
11
|
-
NAME = "sequel"
|
12
|
-
VERS = "2.2.0"
|
13
|
-
SEQUEL_CORE_VERS= "2.2.0"
|
10
|
+
NAME = 'sequel'
|
11
|
+
VERS = '2.3.0'
|
14
12
|
CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
|
15
13
|
RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
|
16
|
-
'Sequel: The Database Toolkit for Ruby
|
17
|
-
|
18
|
-
##############################################################################
|
19
|
-
# RDoc
|
20
|
-
##############################################################################
|
21
|
-
Rake::RDocTask.new do |rdoc|
|
22
|
-
rdoc.rdoc_dir = "rdoc"
|
23
|
-
rdoc.options += RDOC_OPTS
|
24
|
-
rdoc.rdoc_files.add ["README", "COPYING", "doc/*.rdoc", "lib/**/*.rb"]
|
25
|
-
end
|
14
|
+
'Sequel: The Database Toolkit for Ruby', '--main', 'README']
|
26
15
|
|
27
16
|
##############################################################################
|
28
|
-
#
|
17
|
+
# gem packaging and release
|
29
18
|
##############################################################################
|
30
|
-
desc "Packages
|
31
|
-
task :package
|
32
|
-
|
19
|
+
desc "Packages sequel"
|
20
|
+
task :package=>[:clean]
|
33
21
|
spec = Gem::Specification.new do |s|
|
34
22
|
s.name = NAME
|
35
23
|
s.rubyforge_project = 'sequel'
|
@@ -37,80 +25,120 @@ spec = Gem::Specification.new do |s|
|
|
37
25
|
s.platform = Gem::Platform::RUBY
|
38
26
|
s.has_rdoc = true
|
39
27
|
s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"] + Dir["doc/*.rdoc"]
|
40
|
-
s.rdoc_options += RDOC_OPTS
|
41
|
-
s.summary = "The Database Toolkit for Ruby
|
28
|
+
s.rdoc_options += RDOC_OPTS
|
29
|
+
s.summary = "The Database Toolkit for Ruby"
|
42
30
|
s.description = s.summary
|
43
31
|
s.author = "Jeremy Evans"
|
44
32
|
s.email = "code@jeremyevans.net"
|
45
33
|
s.homepage = "http://sequel.rubyforge.org"
|
46
34
|
s.required_ruby_version = ">= 1.8.4"
|
47
|
-
s.
|
48
|
-
s.files = %w(COPYING README Rakefile) + Dir.glob("{doc,spec,lib}/**/*")
|
35
|
+
s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
|
49
36
|
s.require_path = "lib"
|
37
|
+
s.bindir = 'bin'
|
38
|
+
s.executables << 'sequel'
|
50
39
|
end
|
51
|
-
|
52
40
|
Rake::GemPackageTask.new(spec) do |p|
|
53
41
|
p.need_tar = true
|
54
42
|
p.gem_spec = spec
|
55
43
|
end
|
56
44
|
|
57
|
-
##############################################################################
|
58
|
-
# installation & removal
|
59
|
-
##############################################################################
|
60
45
|
desc "Install sequel gem"
|
61
|
-
task :install do
|
62
|
-
sh %{rake package}
|
46
|
+
task :install=>[:package] do
|
63
47
|
sh %{sudo gem install pkg/#{NAME}-#{VERS} --local}
|
64
48
|
end
|
65
49
|
|
66
|
-
desc "Install sequel gem without
|
67
|
-
task :install_no_docs do
|
68
|
-
sh %{rake package}
|
50
|
+
desc "Install sequel gem without RDoc"
|
51
|
+
task :install_no_docs=>[:package] do
|
69
52
|
sh %{sudo gem install pkg/#{NAME}-#{VERS} --no-rdoc --no-ri --local}
|
70
53
|
end
|
71
54
|
|
72
55
|
desc "Uninstall sequel gem"
|
73
|
-
task :uninstall
|
56
|
+
task :uninstall=>[:clean] do
|
74
57
|
sh %{sudo gem uninstall #{NAME}}
|
75
58
|
end
|
76
59
|
|
77
|
-
|
78
|
-
|
79
|
-
##############################################################################
|
80
|
-
desc "Upload sequel gem to rubyforge"
|
81
|
-
task :release => [:package] do
|
60
|
+
desc "Upload sequel and sequel_core gems to rubyforge"
|
61
|
+
task :release=>[:package] do
|
82
62
|
sh %{rubyforge login}
|
83
63
|
sh %{rubyforge add_release sequel #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.tgz}
|
84
|
-
sh %{rubyforge add_file sequel #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.gem}
|
64
|
+
sh %{rubyforge add_file sequel #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.gem}
|
65
|
+
end
|
66
|
+
|
67
|
+
##############################################################################
|
68
|
+
# rdoc
|
69
|
+
##############################################################################
|
70
|
+
Rake::RDocTask.new do |rdoc|
|
71
|
+
rdoc.rdoc_dir = "rdoc"
|
72
|
+
rdoc.options += RDOC_OPTS
|
73
|
+
rdoc.rdoc_files.add %w"README CHANGELOG COPYING lib/**/*.rb doc/*.rdoc"
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Update docs and upload to rubyforge.org"
|
77
|
+
task :doc_rforge => [:rdoc]
|
78
|
+
task :doc_rforge do
|
79
|
+
sh %{chmod -R g+w rdoc/*}
|
80
|
+
sh %{scp -rp rdoc/* rubyforge.org:/var/www/gforge-projects/sequel}
|
85
81
|
end
|
86
82
|
|
87
83
|
##############################################################################
|
88
84
|
# specs
|
89
85
|
##############################################################################
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
lib_dir = File.join(File.dirname(__FILE__), 'lib')
|
87
|
+
fixRUBYLIB = Proc.new{ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)}
|
88
|
+
sequel_core_specs = "spec/sequel_core/*_spec.rb"
|
89
|
+
sequel_model_specs = "spec/sequel_model/*_spec.rb"
|
90
|
+
spec_opts = proc{File.read("spec/spec.opts").split("\n")}
|
91
|
+
rcov_opts = proc{File.read("spec/rcov.opts").split("\n")}
|
92
|
+
|
93
|
+
desc "Run core and model specs with coverage"
|
94
|
+
Spec::Rake::SpecTask.new("spec_coverage") do |t|
|
95
|
+
fixRUBYLIB.call
|
96
|
+
t.spec_files = FileList[sequel_core_specs, sequel_model_specs]
|
97
|
+
t.spec_opts = spec_opts.call
|
98
|
+
t.rcov_opts = rcov_opts.call
|
99
|
+
t.rcov = true
|
100
|
+
end
|
93
101
|
|
94
|
-
desc "Run
|
102
|
+
desc "Run core and model specs"
|
103
|
+
task :default => [:spec]
|
95
104
|
Spec::Rake::SpecTask.new("spec") do |t|
|
96
105
|
fixRUBYLIB.call
|
97
|
-
t.spec_files = FileList[
|
98
|
-
t.spec_opts =
|
99
|
-
t.rcov_opts = File.read("spec/rcov.opts").split("\n")
|
100
|
-
t.rcov = true
|
106
|
+
t.spec_files = FileList[sequel_core_specs, sequel_model_specs]
|
107
|
+
t.spec_opts = spec_opts.call
|
101
108
|
end
|
102
109
|
|
103
|
-
desc "Run specs
|
104
|
-
|
105
|
-
Spec::Rake::SpecTask.new("spec_no_cov") do |t|
|
110
|
+
desc "Run core specs"
|
111
|
+
Spec::Rake::SpecTask.new("spec_core") do |t|
|
106
112
|
fixRUBYLIB.call
|
107
|
-
t.spec_files = FileList[
|
108
|
-
t.spec_opts =
|
113
|
+
t.spec_files = FileList[sequel_core_specs]
|
114
|
+
t.spec_opts = spec_opts.call
|
115
|
+
end
|
116
|
+
|
117
|
+
desc "Run model specs"
|
118
|
+
Spec::Rake::SpecTask.new("spec_model") do |t|
|
119
|
+
fixRUBYLIB.call
|
120
|
+
t.spec_files = FileList[sequel_model_specs]
|
121
|
+
t.spec_opts = spec_opts.call
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "Run integration tests"
|
125
|
+
Spec::Rake::SpecTask.new("integration") do |t|
|
126
|
+
fixRUBYLIB.call
|
127
|
+
t.spec_files = FileList["spec/integration/*_test.rb"]
|
128
|
+
t.spec_opts = spec_opts.call
|
129
|
+
end
|
130
|
+
|
131
|
+
%w'postgres sqlite mysql informix oracle ado'.each do |adapter|
|
132
|
+
desc "Run #{adapter} specs without coverage"
|
133
|
+
Spec::Rake::SpecTask.new("spec_#{adapter}") do |t|
|
134
|
+
t.spec_files = ["spec/adapters/#{adapter}_spec.rb"]
|
135
|
+
t.spec_opts = spec_opts.call
|
136
|
+
end
|
109
137
|
end
|
110
138
|
|
111
139
|
desc "check documentation coverage"
|
112
140
|
task :dcov do
|
113
|
-
sh
|
141
|
+
sh %{find lib -name '*.rb' | xargs dcov}
|
114
142
|
end
|
115
143
|
|
116
144
|
##############################################################################
|
@@ -119,12 +147,12 @@ end
|
|
119
147
|
|
120
148
|
STATS_DIRECTORIES = [
|
121
149
|
%w(Code lib/),
|
122
|
-
%w(Spec spec
|
150
|
+
%w(Spec spec),
|
123
151
|
].collect { |name, dir| [ name, "./#{dir}" ] }.select { |name, dir| File.directory?(dir) }
|
124
152
|
|
125
153
|
desc "Report code statistics (KLOCs, etc) from the application"
|
126
154
|
task :stats do
|
127
|
-
require "
|
155
|
+
require "extra/stats"
|
128
156
|
verbose = true
|
129
157
|
CodeStatistics.new(*STATS_DIRECTORIES).to_s
|
130
158
|
end
|