sequel 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +56 -0
  2. data/{README → README.rdoc} +85 -57
  3. data/Rakefile +10 -5
  4. data/bin/sequel +7 -16
  5. data/doc/advanced_associations.rdoc +5 -17
  6. data/doc/cheat_sheet.rdoc +18 -20
  7. data/doc/dataset_filtering.rdoc +8 -32
  8. data/doc/schema.rdoc +20 -0
  9. data/lib/sequel_core.rb +35 -1
  10. data/lib/sequel_core/adapters/ado.rb +1 -1
  11. data/lib/sequel_core/adapters/db2.rb +2 -2
  12. data/lib/sequel_core/adapters/dbi.rb +2 -11
  13. data/lib/sequel_core/adapters/do.rb +205 -0
  14. data/lib/sequel_core/adapters/do/mysql.rb +38 -0
  15. data/lib/sequel_core/adapters/do/postgres.rb +92 -0
  16. data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
  17. data/lib/sequel_core/adapters/firebird.rb +298 -0
  18. data/lib/sequel_core/adapters/informix.rb +10 -1
  19. data/lib/sequel_core/adapters/jdbc.rb +78 -19
  20. data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
  21. data/lib/sequel_core/adapters/jdbc/mysql.rb +10 -0
  22. data/lib/sequel_core/adapters/jdbc/postgresql.rb +7 -3
  23. data/lib/sequel_core/adapters/mysql.rb +53 -77
  24. data/lib/sequel_core/adapters/odbc.rb +1 -1
  25. data/lib/sequel_core/adapters/openbase.rb +1 -1
  26. data/lib/sequel_core/adapters/oracle.rb +2 -2
  27. data/lib/sequel_core/adapters/postgres.rb +16 -14
  28. data/lib/sequel_core/adapters/shared/mysql.rb +44 -9
  29. data/lib/sequel_core/adapters/shared/oracle.rb +4 -5
  30. data/lib/sequel_core/adapters/shared/postgres.rb +86 -82
  31. data/lib/sequel_core/adapters/shared/sqlite.rb +39 -24
  32. data/lib/sequel_core/adapters/sqlite.rb +11 -1
  33. data/lib/sequel_core/connection_pool.rb +10 -2
  34. data/lib/sequel_core/core_sql.rb +13 -3
  35. data/lib/sequel_core/database.rb +131 -30
  36. data/lib/sequel_core/database/schema.rb +5 -5
  37. data/lib/sequel_core/dataset.rb +31 -6
  38. data/lib/sequel_core/dataset/convenience.rb +11 -11
  39. data/lib/sequel_core/dataset/query.rb +2 -2
  40. data/lib/sequel_core/dataset/sql.rb +6 -6
  41. data/lib/sequel_core/exceptions.rb +4 -0
  42. data/lib/sequel_core/migration.rb +4 -4
  43. data/lib/sequel_core/schema/generator.rb +19 -3
  44. data/lib/sequel_core/schema/sql.rb +24 -20
  45. data/lib/sequel_core/sql.rb +13 -16
  46. data/lib/sequel_core/version.rb +11 -0
  47. data/lib/sequel_model.rb +2 -0
  48. data/lib/sequel_model/base.rb +2 -2
  49. data/lib/sequel_model/hooks.rb +46 -7
  50. data/lib/sequel_model/record.rb +11 -9
  51. data/lib/sequel_model/schema.rb +1 -1
  52. data/lib/sequel_model/validations.rb +72 -61
  53. data/spec/adapters/firebird_spec.rb +371 -0
  54. data/spec/adapters/mysql_spec.rb +118 -62
  55. data/spec/adapters/oracle_spec.rb +5 -5
  56. data/spec/adapters/postgres_spec.rb +33 -18
  57. data/spec/adapters/sqlite_spec.rb +2 -2
  58. data/spec/integration/dataset_test.rb +3 -3
  59. data/spec/integration/schema_test.rb +55 -5
  60. data/spec/integration/spec_helper.rb +11 -0
  61. data/spec/integration/type_test.rb +59 -16
  62. data/spec/sequel_core/connection_pool_spec.rb +14 -0
  63. data/spec/sequel_core/core_sql_spec.rb +24 -14
  64. data/spec/sequel_core/database_spec.rb +96 -11
  65. data/spec/sequel_core/dataset_spec.rb +97 -37
  66. data/spec/sequel_core/expression_filters_spec.rb +51 -40
  67. data/spec/sequel_core/object_graph_spec.rb +2 -2
  68. data/spec/sequel_core/schema_generator_spec.rb +31 -6
  69. data/spec/sequel_core/schema_spec.rb +25 -9
  70. data/spec/sequel_core/spec_helper.rb +4 -1
  71. data/spec/sequel_core/version_spec.rb +7 -0
  72. data/spec/sequel_model/associations_spec.rb +1 -1
  73. data/spec/sequel_model/hooks_spec.rb +68 -13
  74. data/spec/sequel_model/model_spec.rb +4 -4
  75. data/spec/sequel_model/record_spec.rb +22 -0
  76. data/spec/sequel_model/spec_helper.rb +2 -1
  77. data/spec/sequel_model/validations_spec.rb +107 -7
  78. metadata +15 -5
data/CHANGELOG CHANGED
@@ -1,3 +1,59 @@
1
+ === 2.10.0 (2009-02-03)
2
+
3
+ * Don't use a default schema any longer in the shared PostgreSQL adapter (jeremyevans)
4
+
5
+ * Make Dataset#quote_identifier return LiteralStrings as-is (jeremyevans)
6
+
7
+ * Support symbol keys and unnested hashes in the sequel command line tool's yaml config support (jeremyevans)
8
+
9
+ * Add schema parsing support to the JDBC adapter (jeremyevans)
10
+
11
+ * Add per-database type translation support for schema changes, translating ruby classes to database specific types (jeremyevans)
12
+
13
+ * Add Sequel::DatabaseConnectionError, for indicating that Sequel wasn't able to connect to the database (jeremyevans)
14
+
15
+ * Add validates_not_string validation, useful in conjunction with raise_on_typecast_failure = false (jeremyevans)
16
+
17
+ * Don't modify Model#new? and Model#changed_columns when saving a record until after the after hooks have been run (tamas, jeremyevans)
18
+
19
+ * Database#quote_identifiers= now affects future schema modification statements, even if it is not used before one of the schema modification statements (jeremyevans)
20
+
21
+ * Fix literalization of blobs when using the PostreSQL JDBC subadapter (jeremyevans)
22
+
23
+ * Fix literalization of date and time types when using the MySQL JDBC subadapter (jeremyevans)
24
+
25
+ * Convert some Java specific types to ruby types on output in the JDBC adapter (jeremyevans)
26
+
27
+ * Add Database#tables method to JDBC adapter (jeremyevans)
28
+
29
+ * Add H2 JDBC subadapter (logan_barnett, david_koontz, james_britt, jeremyevans)
30
+
31
+ * Add identifer_output_method, used for converting identifiers coming out of the database, replacing the lowercase support on some databases (jeremyevans)
32
+
33
+ * Add identifier_input_method, used for converting identifiers going into the database, replacing upcase_identifiers (jeremyevans)
34
+
35
+ * Add :allow_missing validation option, useful if the database provides a good default (jeremyevans)
36
+
37
+ * Fix literalization of SQL::Blobs in DataObjects and JDBC adapter's postgresql subadapters when ruby 1.9 is used (jeremyevans)
38
+
39
+ * When using standard strings in the postgres adapter with the postgres-pr driver, use custom string escaping to prevent errors (jeremyevans)
40
+
41
+ * Before hooks now run in reverse order of being added, so later ones are run first (tamas)
42
+
43
+ * Add Firebird adapter, requires Firebird ruby driver located at http://github.com/wishdev/fb (wishdev)
44
+
45
+ * Don't clobber the following Symbol instance methods when using ruby 1.9: [], <, <=, >, >= (jeremyevans)
46
+
47
+ * Quote the table name and the index for PostgreSQL index creation (jeremyevans)
48
+
49
+ * Add DataObjects adapter, supporting PostgreSQL, MySQL, and SQLite (jeremyevans)
50
+
51
+ * Add ability for Database#create_table to take options, support specifying MySQL engine, charset, and collate per table (pusewicz, jeremyevans)
52
+
53
+ * Add Model.add_hook_type class method, for adding your own hook types, mostly for use by plugin authors (pkondzior, jeremyevans)
54
+
55
+ * Add Sequel.version for getting the internal version of Sequel (pusewicz, jeremyevans)
56
+
1
57
  === 2.9.0 (2009-01-12)
2
58
 
3
59
  * Add -L option to sequel command line tool to load all .rb files in the given directory (pkondzior, jeremyevans)
@@ -6,12 +6,14 @@ Sequel is a lightweight database access toolkit for Ruby.
6
6
  for constructing database queries and table schemas.
7
7
  * Sequel also includes a lightweight but comprehensive ORM layer for
8
8
  mapping records to Ruby objects and handling associated records.
9
- * Sequel supports advanced database features such as prepared statements,
10
- bound variables, master/slave configurations, and database sharding.
9
+ * Sequel supports advanced database features such as prepared
10
+ statements, bound variables, stored procedures, master/slave
11
+ configurations, and database sharding.
11
12
  * Sequel makes it easy to deal with multiple records without having
12
13
  to break your teeth on SQL.
13
- * Sequel currently has adapters for ADO, DB2, DBI, Informix, JDBC,
14
- MySQL, ODBC, OpenBase, Oracle, PostgreSQL and SQLite3.
14
+ * Sequel currently has adapters for ADO, DataObjects, DB2, DBI,
15
+ Firebird, Informix, JDBC, MySQL, ODBC, OpenBase, Oracle, PostgreSQL
16
+ and SQLite3.
15
17
 
16
18
  == Resources
17
19
 
@@ -74,7 +76,7 @@ You get an IRB session with the database object stored in DB.
74
76
 
75
77
  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.
76
78
 
77
- 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.
79
+ 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 flexible.
78
80
 
79
81
  For example, the following one-liner returns the average GDP for the five biggest countries in the middle east region:
80
82
 
@@ -87,7 +89,7 @@ Which is equivalent to:
87
89
  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:
88
90
 
89
91
  middle_east = DB[:countries].filter(:region => 'Middle East')
90
- middle_east.order(:name).each {|r| puts r[:name]}
92
+ middle_east.order(:name).each{|r| puts r[:name]}
91
93
 
92
94
  Sequel also offers convenience methods for extracting data from Datasets, such as an extended map method:
93
95
 
@@ -121,8 +123,8 @@ You can specify a block to connect, which will disconnect from the database afte
121
123
 
122
124
  === Arbitrary SQL queries
123
125
 
124
- DB.execute("create table t (a text, b text)")
125
- DB.execute("insert into t values ('a', 'b')")
126
+ DB.execute_ddl("create table t (a text, b text)")
127
+ DB.execute_insert("insert into t values ('a', 'b')")
126
128
 
127
129
  Or more succinctly:
128
130
 
@@ -141,6 +143,12 @@ You can also fetch records with raw SQL through the dataset:
141
143
  p row
142
144
  end
143
145
 
146
+ You can use placeholders in your SQL string as well:
147
+
148
+ DB['select * from items where name = ?', name].each do |row|
149
+ p row
150
+ end
151
+
144
152
  === Getting Dataset Instances
145
153
 
146
154
  Dataset is the primary means through which records are retrieved and manipulated. You can create an blank dataset by using the dataset method:
@@ -196,13 +204,13 @@ You can also specify ranges:
196
204
 
197
205
  my_posts = posts.filter(:stamp => (Date.today - 14)..(Date.today - 7))
198
206
 
199
- Or lists of values:
207
+ Or arrays of values:
200
208
 
201
209
  my_posts = posts.filter(:category => ['ruby', 'postgres', 'linux'])
202
210
 
203
211
  Sequel also accepts expressions:
204
212
 
205
- my_posts = posts.filter(:stamp > Date.today << 1)
213
+ my_posts = posts.filter{|o| o.stamp > Date.today << 1}
206
214
 
207
215
  Some adapters (like postgresql) will also let you specify Regexps:
208
216
 
@@ -220,7 +228,7 @@ You can also specify a custom WHERE clause using a string:
220
228
  You can use parameters in your string, as well (ActiveRecord style):
221
229
 
222
230
  posts.filter('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
223
- posts.filter((:stamp < Date.today - 3) & ~(:author => author_name)) # same as above
231
+ posts.filter{|o| (o.stamp < Date.today + 3) & ~{:author => author_name}} # same as above
224
232
 
225
233
  Datasets can also be used as subqueries:
226
234
 
@@ -249,11 +257,34 @@ Ordering datasets is simple:
249
257
 
250
258
  posts.order(:stamp) # ORDER BY stamp
251
259
  posts.order(:stamp, :name) # ORDER BY stamp, name
260
+
261
+ Chaining order doesn't work the same as filter:
262
+
263
+ posts.order(:stamp).order(:name) # ORDER BY name
264
+
265
+ The order_more method chains this way, though:
266
+
267
+ posts.order(:stamp).order_more(:name) # ORDER BY stamp, name
252
268
 
253
269
  You can also specify descending order
254
270
 
255
271
  posts.order(:stamp.desc) # ORDER BY stamp DESC
256
272
 
273
+ === Selecting Columns
274
+
275
+ Selecting specific columns to be returned is also simple:
276
+
277
+ posts.select(:stamp) # SELECT stamp FROM posts
278
+ posts.select(:stamp, :name) # SELECT stamp, name FROM posts
279
+
280
+ Chaining select works like order, not filter:
281
+
282
+ posts.select(:stamp).select(:name) # SELECT name FROM posts
283
+
284
+ As you might expect, there is an order_more equivalent for select:
285
+
286
+ posts.select(:stamp).select_more(:name) # SELECT stamp, name FROM posts
287
+
257
288
  === Deleting Records
258
289
 
259
290
  Deleting records from the table is done with delete:
@@ -282,7 +313,7 @@ Joining is very useful in a variety of scenarios, for example many-to-many relat
282
313
 
283
314
  This is equivalent to the SQL:
284
315
 
285
- SELECT * FROM items LEFT OUTER JOIN order_items
316
+ SELECT * FROM items INNER JOIN order_items
286
317
  ON order_items.item_id = items.id
287
318
  WHERE order_items.order_id = 1234
288
319
 
@@ -292,13 +323,13 @@ You can then do anything you like with the dataset:
292
323
 
293
324
  Which is equivalent to the SQL:
294
325
 
295
- SELECT sum(price) FROM items LEFT OUTER JOIN order_items
326
+ SELECT sum(price) FROM items INNER JOIN order_items
296
327
  ON order_items.item_id = items.id
297
328
  WHERE order_items.order_id = 1234
298
329
 
299
330
  === Graphing Datasets
300
331
 
301
- When retrieving records from joined datasets, you get the results in a single hash, which is subject to clobbering:
332
+ When retrieving records from joined datasets, you get the results in a single hash, which is subject to clobbering if you have columns with the same name in multiple tables:
302
333
 
303
334
  DB[:items].join(:order_items, :item_id => :id).first
304
335
  => {:id=>(could be items.id or order_items.id), :item_id=>order_items.order_id}
@@ -308,6 +339,30 @@ Using graph, you can split the result hashes into subhashes, one per join:
308
339
  DB[:items].graph(:order_items, :item_id => :id).first
309
340
  => {:items=>{:id=>items.id}, :order_items=>{:id=>order_items.id, :item_id=>order_items.item_id}}
310
341
 
342
+ == An aside: column references in Sequel
343
+
344
+ Sequel expects column names to be specified using symbols. In addition, returned hashes always use symbols as their keys. This allows you to freely mix literal values and column references. For example, the two following lines produce equivalent SQL:
345
+
346
+ items.filter(:x => 1) #=> "SELECT * FROM items WHERE (x = 1)"
347
+ items.filter(1 => :x) #=> "SELECT * FROM items WHERE (1 = x)"
348
+
349
+ === Qualifying column names
350
+
351
+ Column references can be qualified by using the double underscore special notation :table__column:
352
+
353
+ items.literal(:items__price) #=> "items.price"
354
+
355
+ === Column aliases
356
+
357
+ You can also alias columns by using the triple undersecore special notation :column___alias or :table__column___alias:
358
+
359
+ items.literal(:price___p) #=> "price AS p"
360
+ items.literal(:items__price___p) #=> "items.price AS p"
361
+
362
+ Another way to alias columns is to use the #AS method:
363
+
364
+ items.literal(:price.as(:p)) #=> "price AS p"
365
+
311
366
  == Sequel Models
312
367
 
313
368
  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.
@@ -355,17 +410,17 @@ You can also define a model class that does not have a primary key, but then you
355
410
  A model instance can also be fetched by specifying a condition:
356
411
 
357
412
  post = Post[:title => 'hello world']
358
- post = Post.find(:num_comments < 10)
413
+ post = Post.find{|o| o.num_comments < 10}
359
414
 
360
415
  === Iterating over records
361
416
 
362
- A model class lets you iterate over specific records by acting as a proxy to the underlying dataset. This means that you can use the entire Dataset API to create customized queries that return model instances, e.g.:
417
+ A model class lets you iterate over subsets of records by proxying many methods to the underlying dataset. This means that you can use most of the Dataset API to create customized queries that return model instances, e.g.:
363
418
 
364
419
  Post.filter(:category => 'ruby').each{|post| p post}
365
420
 
366
421
  You can also manipulate the records in the dataset:
367
422
 
368
- Post.filter(:num_comments < 7).delete
423
+ Post.filter{|o| o.num_comments < 7}.delete
369
424
  Post.filter(:title.like(/ruby/)).update(:category => 'ruby')
370
425
 
371
426
  === Accessing record values
@@ -384,9 +439,9 @@ You can also change record values:
384
439
  post.title = 'hey there'
385
440
  post.save
386
441
 
387
- Another way to change values by using the #update_with_params method:
442
+ Another way to change values by using the #update method:
388
443
 
389
- post.update_with_params(:title => 'hey there')
444
+ post.update(:title => 'hey there')
390
445
 
391
446
  === Creating new records
392
447
 
@@ -402,7 +457,7 @@ Another way is to construct a new instance and save it:
402
457
 
403
458
  You can also supply a block to Model.new and Model.create:
404
459
 
405
- post = Post.create {|p| p.title = 'hello world'}
460
+ post = Post.create{|p| p.title = 'hello world'}
406
461
 
407
462
  post = Post.new do |p|
408
463
  p.title = 'hello world'
@@ -451,14 +506,6 @@ Associations are used in order to specify relationships between model classes th
451
506
  many_to_many :tags
452
507
  end
453
508
 
454
- You can also use the ActiveRecord names for these associations:
455
-
456
- class Post < Sequel::Model
457
- belongs_to :author
458
- has_many :comments
459
- has_and_belongs_to_many :tags
460
- end
461
-
462
509
  many_to_one creates a getter and setter for each model object:
463
510
 
464
511
  class Post < Sequel::Model
@@ -516,7 +563,7 @@ Associations can be eagerly loaded via .eager and the :eager association option.
516
563
  Post.eager(:person).all
517
564
 
518
565
  # eager is a dataset method, so it works with filters/orders/limits/etc.
519
- Post.filter(:topic > 'M').order(:date).limit(5).eager(:person).all
566
+ Post.filter{|o| o.topic > 'M'}.order(:date).limit(5).eager(:person).all
520
567
 
521
568
  person = Person.first
522
569
  # Eager loading via :eager (will eagerly load the tags for this person's posts)
@@ -560,7 +607,7 @@ The obvious way to add table-wide logic is to define class methods to the model
560
607
 
561
608
  class Post < Sequel::Model
562
609
  def self.posts_with_few_comments
563
- filter(:num_comments < 30)
610
+ filter{|o| o.num_comments < 30}
564
611
  end
565
612
 
566
613
  def self.clean_posts_with_few_comments
@@ -572,7 +619,7 @@ You can also implement table-wide logic by defining methods on the dataset:
572
619
 
573
620
  class Post < Sequel::Model
574
621
  def_dataset_method(:posts_with_few_comments) do
575
- filter(:num_comments < 30)
622
+ filter{|o| o.num_comments < 30}
576
623
  end
577
624
 
578
625
  def_dataset_method(:clean_posts_with_few_comments) do
@@ -582,48 +629,29 @@ You can also implement table-wide logic by defining methods on the dataset:
582
629
 
583
630
  This is the recommended way of implementing table-wide operations, and allows you to have access to your model API from filtered datasets as well:
584
631
 
585
- Post.filter(:category => 'ruby').clean_old_posts
632
+ Post.filter(:category => 'ruby').clean_posts_with_few_comments
586
633
 
587
634
  Sequel models also provide a short hand notation for filters:
588
635
 
589
636
  class Post < Sequel::Model
590
- subset(:posts_with_few_comments, :num_comments < 30)
591
- subset :invisible, :visible => false
592
- end
593
-
594
- === Defining the underlying schema
595
-
596
- Model classes can also be used as a place to define your table schema and control it. The schema DSL is exactly the same provided by Sequel::Schema::Generator:
597
-
598
- class Post < Sequel::Model
599
- set_schema do
600
- primary_key :id
601
- text :title
602
- text :category
603
- foreign_key :author_id, :table => :authors
604
- end
637
+ subset(:posts_with_few_comments){|o| o.num_comments < 30}
638
+ subset :invisible, ~:visible
605
639
  end
606
640
 
607
- You can then create the underlying table, drop it, or recreate it:
608
-
609
- Post.table_exists?
610
- Post.create_table
611
- Post.drop_table
612
- Post.create_table! # drops the table if it exists and then recreates it
613
-
614
641
  === Basic Model Validations
615
642
 
616
643
  To assign default validations to a sequel model:
617
644
 
618
645
  class MyModel < Sequel::Model
619
646
  validates do
620
- format_of...
621
- presence_of...
622
647
  acceptance_of...
623
648
  confirmation_of...
649
+ format_of...
650
+ format_of...
651
+ presence_of...
624
652
  length_of...
653
+ not_string ...
625
654
  numericality_of...
626
- format_of...
627
655
  each...
628
656
  end
629
657
  end
data/Rakefile CHANGED
@@ -8,14 +8,15 @@ rescue LoadError
8
8
  require "rake/rdoctask"
9
9
  end
10
10
  require "fileutils"
11
+ require "lib/sequel_core/version"
11
12
 
12
13
  include FileUtils
13
14
 
14
15
  NAME = 'sequel'
15
- VERS = '2.9.0'
16
+ VERS = Sequel.version
16
17
  CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage", "www/public/*.html"]
17
18
  RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
18
- 'Sequel: The Database Toolkit for Ruby', '--main', 'README']
19
+ 'Sequel: The Database Toolkit for Ruby', '--main', 'README.rdoc']
19
20
 
20
21
  # Gem Packaging and Release
21
22
 
@@ -27,7 +28,7 @@ spec = Gem::Specification.new do |s|
27
28
  s.version = VERS
28
29
  s.platform = Gem::Platform::RUBY
29
30
  s.has_rdoc = true
30
- s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"] + Dir["doc/*.rdoc"]
31
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "COPYING"] + Dir["doc/*.rdoc"]
31
32
  s.rdoc_options += RDOC_OPTS
32
33
  s.summary = "The Database Toolkit for Ruby"
33
34
  s.description = s.summary
@@ -35,7 +36,7 @@ spec = Gem::Specification.new do |s|
35
36
  s.email = "code@jeremyevans.net"
36
37
  s.homepage = "http://sequel.rubyforge.org"
37
38
  s.required_ruby_version = ">= 1.8.4"
38
- s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
39
+ s.files = %w(COPYING CHANGELOG README.rdoc Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
39
40
  s.require_path = "lib"
40
41
  s.bindir = 'bin'
41
42
  s.executables << 'sequel'
@@ -72,7 +73,7 @@ end
72
73
  Rake::RDocTask.new do |rdoc|
73
74
  rdoc.rdoc_dir = "rdoc"
74
75
  rdoc.options += RDOC_OPTS
75
- rdoc.rdoc_files.add %w"README CHANGELOG COPYING lib/**/*.rb doc/*.rdoc"
76
+ rdoc.rdoc_files.add %w"README.rdoc CHANGELOG COPYING lib/**/*.rb doc/*.rdoc"
76
77
  end
77
78
 
78
79
  ### Website
@@ -165,3 +166,7 @@ task :stats do
165
166
  CodeStatistics.new(*STATS_DIRECTORIES).to_s
166
167
  end
167
168
 
169
+ desc "Print Sequel version"
170
+ task :version do
171
+ puts VERS
172
+ end
data/bin/sequel CHANGED
@@ -55,13 +55,7 @@ opts = OptionParser.new do |opts|
55
55
  end
56
56
 
57
57
  opts.on_tail("-v", "--version", "Show version") do
58
- class << Gem; attr_accessor :loaded_specs; end
59
- begin
60
- specs = Gem.loaded_specs['sequel']
61
- puts "sequel #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
62
- rescue
63
- puts "No gem version found"
64
- end
58
+ puts "sequel #{Sequel.version}"
65
59
  exit
66
60
  end
67
61
  end
@@ -83,25 +77,22 @@ end
83
77
 
84
78
  if File.exist?(db)
85
79
  require 'yaml'
86
- db_config = YAML.load_file(db)[env || "development"]
87
- db_config.each {|(k,v)| db_config[k.to_sym] = db_config.delete(k)}
80
+ env ||= "development"
81
+ db_config = YAML.load_file(db)
82
+ db_config = db_config[env] || db_config[env.to_sym] || db_config
83
+ db_config.each{|(k,v)| db_config[k.to_sym] = db_config.delete(k)}
88
84
  db_config.merge!(db_opts)
89
85
  end
90
86
 
91
87
  begin
92
- if db_config
93
- opts = [db_config]
94
- else
95
- opts = [db, db_opts]
96
- end
97
- DB = Sequel.connect(*opts)
88
+ DB = Sequel.connect(*(db_config ? [db_config] : [db, db_opts]))
98
89
  DB.test_connection
99
90
  if migrate_dir
100
91
  Sequel::Migrator.apply(DB, migrate_dir, migrate_ver)
101
92
  exit
102
93
  end
103
94
  rescue => e
104
- puts e.message
95
+ puts "#{e.class}: #{e.message}"
105
96
  puts e.backtrace.first
106
97
  exit 1
107
98
  end