sequel_core 1.5.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGELOG +116 -0
  2. data/COPYING +19 -19
  3. data/README +83 -32
  4. data/Rakefile +9 -20
  5. data/bin/sequel +43 -112
  6. data/doc/cheat_sheet.rdoc +225 -0
  7. data/doc/dataset_filtering.rdoc +257 -0
  8. data/lib/sequel_core/adapters/adapter_skeleton.rb +4 -2
  9. data/lib/sequel_core/adapters/ado.rb +3 -1
  10. data/lib/sequel_core/adapters/db2.rb +4 -2
  11. data/lib/sequel_core/adapters/dbi.rb +127 -113
  12. data/lib/sequel_core/adapters/informix.rb +4 -2
  13. data/lib/sequel_core/adapters/jdbc.rb +5 -3
  14. data/lib/sequel_core/adapters/mysql.rb +112 -46
  15. data/lib/sequel_core/adapters/odbc.rb +5 -7
  16. data/lib/sequel_core/adapters/odbc_mssql.rb +12 -3
  17. data/lib/sequel_core/adapters/openbase.rb +3 -1
  18. data/lib/sequel_core/adapters/oracle.rb +11 -9
  19. data/lib/sequel_core/adapters/postgres.rb +261 -262
  20. data/lib/sequel_core/adapters/sqlite.rb +72 -22
  21. data/lib/sequel_core/connection_pool.rb +140 -73
  22. data/lib/sequel_core/core_ext.rb +201 -66
  23. data/lib/sequel_core/core_sql.rb +123 -153
  24. data/lib/sequel_core/database/schema.rb +156 -0
  25. data/lib/sequel_core/database.rb +321 -338
  26. data/lib/sequel_core/dataset/callback.rb +11 -12
  27. data/lib/sequel_core/dataset/convenience.rb +213 -240
  28. data/lib/sequel_core/dataset/pagination.rb +58 -43
  29. data/lib/sequel_core/dataset/parse_tree_sequelizer.rb +331 -0
  30. data/lib/sequel_core/dataset/query.rb +41 -0
  31. data/lib/sequel_core/dataset/schema.rb +15 -0
  32. data/lib/sequel_core/dataset/sequelizer.rb +41 -373
  33. data/lib/sequel_core/dataset/sql.rb +741 -632
  34. data/lib/sequel_core/dataset.rb +183 -168
  35. data/lib/sequel_core/deprecated.rb +1 -169
  36. data/lib/sequel_core/exceptions.rb +24 -19
  37. data/lib/sequel_core/migration.rb +44 -52
  38. data/lib/sequel_core/object_graph.rb +43 -42
  39. data/lib/sequel_core/pretty_table.rb +71 -76
  40. data/lib/sequel_core/schema/generator.rb +163 -105
  41. data/lib/sequel_core/schema/sql.rb +250 -93
  42. data/lib/sequel_core/schema.rb +2 -8
  43. data/lib/sequel_core/sql.rb +394 -0
  44. data/lib/sequel_core/worker.rb +37 -27
  45. data/lib/sequel_core.rb +99 -45
  46. data/spec/adapters/informix_spec.rb +0 -1
  47. data/spec/adapters/mysql_spec.rb +177 -124
  48. data/spec/adapters/oracle_spec.rb +0 -1
  49. data/spec/adapters/postgres_spec.rb +98 -58
  50. data/spec/adapters/sqlite_spec.rb +45 -4
  51. data/spec/blockless_filters_spec.rb +269 -0
  52. data/spec/connection_pool_spec.rb +21 -18
  53. data/spec/core_ext_spec.rb +169 -19
  54. data/spec/core_sql_spec.rb +56 -49
  55. data/spec/database_spec.rb +78 -17
  56. data/spec/dataset_spec.rb +300 -428
  57. data/spec/migration_spec.rb +1 -1
  58. data/spec/object_graph_spec.rb +5 -11
  59. data/spec/rcov.opts +1 -1
  60. data/spec/schema_generator_spec.rb +16 -4
  61. data/spec/schema_spec.rb +89 -10
  62. data/spec/sequelizer_spec.rb +56 -56
  63. data/spec/spec.opts +0 -5
  64. data/spec/spec_config.rb +7 -0
  65. data/spec/spec_config.rb.example +5 -5
  66. data/spec/spec_helper.rb +6 -0
  67. data/spec/worker_spec.rb +1 -1
  68. metadata +78 -63
data/CHANGELOG CHANGED
@@ -1,3 +1,119 @@
1
+ === 2.0.0 (2008-06-01)
2
+
3
+ * Refactor String inflection support, you must use String.inflections instead of Inflector.inflections now (jeremyevans)
4
+
5
+ * Allow connection to ODBC-MSSQL via a URL (petersumskas) (#230)
6
+
7
+ * Comprehensive update of all documentation, except for the block filters and adapters (jeremyevans)
8
+
9
+ * Handle Date and DateTime value literalization correctly in adapters (jeremyevans)
10
+
11
+ * Literalize DateTime values the same as Time values (jeremyevans)
12
+
13
+ * MySQL tinyints are now returned as boolean values instead of integers (jeremyevans)
14
+
15
+ * Set additional MySQL charset options required for creating tables and databases (tmm1)
16
+
17
+ * Remove methods deprecated in 1.5.0 (jeremyevans)
18
+
19
+ * Add Module#metaattr_accessor for creating attr_accessors for the metaclass (jeremyevans)
20
+
21
+ * Add SQL string concatenation support to blockless filters, via Array#sql_string_join (jeremyevans)
22
+
23
+ * Add Pagination#last_page? and Pagination#first_page? (apeiros)
24
+
25
+ * Add limited column reflection support, tested on PostgreSQL, MySQL, and SQLite (jeremyevans)
26
+
27
+ * Allow the use of :schema__table___table_alias syntax for tables, similar to the column support (jeremyevans)
28
+
29
+ * Merge metaid gem into core_ext.rb and clean it up, so sequel now has no external dependencies (jeremyevans)
30
+
31
+ * Add Dataset#as, so using a dataset as a column with an alias is not deprecated (jeremyevans)
32
+
33
+ * Add Dataset#invert, which returns a dataset with inverted HAVING and WHERE clauses (jeremyevans)
34
+
35
+ * Add blockless filter syntax support (jeremyevans)
36
+
37
+ * Passing an array to Dataset#order and Dataset#select no longer works, you need to pass multiple arguments (jeremyevans)
38
+
39
+ * You should use '?' instead of '(?)' when using interpolated strings with array arguments (jeremyevans)
40
+
41
+ * Dataset.literal now surrounds the literalization of arrays with parentheses (jeremyevans)
42
+
43
+ * Add echo option (back?) to sequel command line tool, via -E or --echo (jeremyevans)
44
+
45
+ * Allow databases to have multiple loggers (jeremyevans)
46
+
47
+ * The sequel command line tool now also accepts a path to a database config YAML file in addition to a URI (mtodd)
48
+
49
+ * Major update of the postgresql adapter (jdavis, jeremyevans) (#225)
50
+
51
+ * Make returning inside of a database transaction commit the transaction (ahoward, jeremyevans)
52
+
53
+ * Dataset#to_table_reference is now protected, and it has a different API (jeremyevans)
54
+
55
+ * Dataset#join_table and related functions now take an explicit optional table_alias argument, you can no longer include the table alias in the table argument (jeremyevans)
56
+
57
+ * Aliased and/or qualified columns with embedded spaces can now be specified as symbols (jeremyevans)
58
+
59
+ * When identifier quoting is enabled, the SQL standard double quote is used by default (jeremyevans)
60
+
61
+ * When identifier quoting is enabled, quote tables as well as columns (jeremyevans)
62
+
63
+ * Make identifier quoting optional, enabled by default (jeremyevans)
64
+
65
+ * Allow Sequel::Database.connect and related methods to take a block that disconnects the database when the block finishes (jeremyevans)
66
+
67
+ * Add Dataset#unfiltered, for removing filters from dataset (jeremyevans)
68
+
69
+ * Add add_foreign_key and add_primary_key methods to the AlterTableGenerator (jeremyevans)
70
+
71
+ * Allow migration files to have more than 3 digits (jeremyevans)
72
+
73
+ * Add methods directly to Dataset instead of including modules (jeremyevans)
74
+
75
+ * Make some Dataset instance methods private: invert_order, insert_default_values_sql (jeremyevans)
76
+
77
+ * Don't add methods that depend on ParseTree unless you can load ParseTree (jeremyevans)
78
+
79
+ * Don't wipeout the cached columns every time a dataset is cloned, but only on changes to :select, :sql, :from, or :join (jeremyevans)
80
+
81
+ * Fix Oracle Adapter (yasushi.abe)
82
+
83
+ * Fixed sqlite uri so that sqlite:// works just like file:// (2 slashes for a relative path, 3 for an absolute) (dlee)
84
+
85
+ * Raise a Sequel::Error if an invalid limit or offset is used (jeremyevans)
86
+
87
+ * Refactor and beef up Dataset#first and Dataset#last, with some change in functionality (jeremyevans)
88
+
89
+ * Add String#to_datetime, for consistency (jeremyevans)
90
+
91
+ * Fix Range#interval so that it returns 1 less for an exclusive range
92
+
93
+ * Change SQLite adapter so it doesn't swallow exceptions other than SQLite3::Exception (such as Interrupt) (jeremyevans)
94
+
95
+ * Change PostgreSQL and MySQL adapters to raise Sequel::Error instead of database specific errors if a database error occurs (jeremyevans)
96
+
97
+ * Using a memory database with SQLite now defaults to a single connection, so all queries it uses run against the same database (jeremyevans)
98
+
99
+ * Fix attempting to query MySQL using the same connection being used to concurrently execute another query (jeremyevans)
100
+
101
+ * Add options to the connection pool to configure reusing connections and converting exceptions (jeremyevans)
102
+
103
+ * Use the database driver provided string quoting methods for MySQL and SQLite (jeremyevans) (#223)
104
+
105
+ * Add ColumnAll#==, for checking the equality of two ColumnAlls (jeremyevans)
106
+
107
+ * Allow an array of arrays instead of a hash when specifying conditions (jeremyevans)
108
+
109
+ * Add Sequel::DBI::Database#lowercase, for lowercasing column names (jamesearl)
110
+
111
+ * Remove Dataset#extend_with_destroy, which may break code that uses Dataset#set_model directly and expects the destroy method to be added (jeremyevans)
112
+
113
+ * Fix some issues when running on Ruby 1.9 (Zverok, jeremyevans)
114
+
115
+ * Make the DBI adapter work (partially) with PostgreSQL (Seb)
116
+
1
117
  === 1.5.1 (2008-04-30)
2
118
 
3
119
  * Have Dataset#graph give a nil value instead of a hash with all nil values if no matching rows exist in the graphed table (jeremyevans)
data/COPYING CHANGED
@@ -1,19 +1,19 @@
1
- Copyright (c) 2007-2008 Sharon Rosner
2
- Copyright (c) 2008 Jeremy Evans
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to
6
- deal in the Software without restriction, including without limitation the
7
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
- sell copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in
12
- all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
- THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2007-2008 Sharon Rosner
2
+ Copyright (c) 2008 Jeremy Evans
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to
6
+ deal in the Software without restriction, including without limitation the
7
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
+ sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README CHANGED
@@ -6,7 +6,6 @@ Sequel makes it easy to deal with multiple records without having to break your
6
6
 
7
7
  == Resources
8
8
 
9
- * {Project page}[http://code.google.com/p/ruby-sequel/]
10
9
  * {Source code}[http://github.com/jeremyevans/sequel]
11
10
  * {Bug tracking}[http://code.google.com/p/ruby-sequel/issues/list]
12
11
  * {Google group}[http://groups.google.com/group/sequel-talk]
@@ -40,11 +39,39 @@ Sequel currently supports:
40
39
 
41
40
  There are also experimental adapters for DB2, OpenBase and JDBC (on JRuby).
42
41
 
42
+ == A Short Example
43
+
44
+ require 'rubygems'
45
+ require 'sequel'
46
+
47
+ DB = Sequel.sqlite # memory database
48
+
49
+ DB.create_table :items do # Create a new table
50
+ column :name, :text
51
+ column :price, :float
52
+ end
53
+
54
+ items = DB[:items] # Create a dataset
55
+
56
+ # Populate the table
57
+ items << {:name => 'abc', :price => rand * 100}
58
+ items << {:name => 'def', :price => rand * 100}
59
+ items << {:name => 'ghi', :price => rand * 100}
60
+
61
+ # Print out the number of records
62
+ puts "Item count: #{items.count}"
63
+
64
+ # Print out the records in descending order by price
65
+ items.reverse_order(:price).print
66
+
67
+ # Print out the average price
68
+ puts "The average price is: #{items.avg(:price)}"
69
+
43
70
  == The Sequel Console
44
71
 
45
72
  Sequel includes an IRB console for quick'n'dirty access to databases. You can use it like this:
46
73
 
47
- sequel sqlite:///test.db
74
+ sequel sqlite://test.db # test.db in current directory
48
75
 
49
76
  You get an IRB session with the database object stored in DB.
50
77
 
@@ -75,8 +102,6 @@ Or getting results as a transposed hash, with one column as key and another as v
75
102
 
76
103
  middle_east.to_hash(:name, :area) #=> {'Israel' => 20000, 'Greece' => 120000, ...}
77
104
 
78
- Much of Sequel is still undocumented (especially the part relating to model classes). The following section provides examples of common usage. Feel free to explore...
79
-
80
105
  == Getting Started
81
106
 
82
107
  === Connecting to a database
@@ -84,16 +109,20 @@ Much of Sequel is still undocumented (especially the part relating to model clas
84
109
  To connect to a database you simply provide Sequel with a URL:
85
110
 
86
111
  require 'sequel'
87
- DB = Sequel.open 'sqlite:///blog.db'
112
+ DB = Sequel.connect('sqlite://blog.db')
88
113
 
89
114
  The connection URL can also include such stuff as the user name and password:
90
115
 
91
- DB = Sequel.open 'postgres://cico:12345@localhost:5432/mydb'
116
+ DB = Sequel.connect('postgres://cico:12345@localhost:5432/mydb')
117
+
118
+ You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
92
119
 
93
- You can also specify optional parameters, such as the connection pool size, or a logger for logging SQL queries:
120
+ DB = Sequel.connect("postgres://postgres:postgres@localhost/my_db",
121
+ :max_connections => 10, :loggers => [Logger.new('log/db.log']))
94
122
 
95
- DB = Sequel.open("postgres://postgres:postgres@localhost/my_db",
96
- :max_connections => 10, :logger => Logger.new('log/db.log'))
123
+ You can specify a block to connect, which will disconnect from the database after it completes:
124
+
125
+ Sequel.connect('postgres://cico:12345@localhost:5432/mydb'){|db| db[:posts].delete}
97
126
 
98
127
  === Arbitrary SQL queries
99
128
 
@@ -105,6 +134,18 @@ Or more succinctly:
105
134
  DB << "create table t (a text, b text)"
106
135
  DB << "insert into t values ('a', 'b')"
107
136
 
137
+ You can also create datasets based on raw SQL:
138
+
139
+ dataset = DB['select * from items']
140
+ dataset.count # will return the number of records in the result set
141
+ dataset.map(:id) # will return an array containing all values of the id column in the result set
142
+
143
+ You can also fetch records with raw SQL through the dataset:
144
+
145
+ DB['select * from items'].each do |row|
146
+ p row
147
+ end
148
+
108
149
  === Getting Dataset Instances
109
150
 
110
151
  Dataset is the primary means through which records are retrieved and manipulated. You can create an blank dataset by using the dataset method:
@@ -115,11 +156,11 @@ Or by using the from methods:
115
156
 
116
157
  posts = DB.from(:posts)
117
158
 
118
- You can also use the equivalent shorthand:
159
+ The recommended way is the equivalent shorthand:
119
160
 
120
161
  posts = DB[:posts]
121
162
 
122
- Note: the dataset will only fetch records when you explicitly ask for them, as will be shown below. Datasets can be manipulated to filter through records, change record order and even join tables, as will also be shown below.
163
+ 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..
123
164
 
124
165
  === Retrieving Records
125
166
 
@@ -131,12 +172,12 @@ The all method returns an array of hashes, where each hash corresponds to a reco
131
172
 
132
173
  You can also iterate through records one at a time:
133
174
 
134
- posts.each {|row| p row}
175
+ posts.each{|row| p row}
135
176
 
136
177
  Or perform more advanced stuff:
137
178
 
138
179
  posts.map(:id)
139
- posts.inject({}) {|h, r| h[r[:id]] = r[:name]}
180
+ posts.inject({}){|h, r| h[r[:id]] = r[:name]}
140
181
 
141
182
  You can also retrieve the first record in a dataset:
142
183
 
@@ -164,13 +205,9 @@ Or lists of values:
164
205
 
165
206
  my_posts = posts.filter(:category => ['ruby', 'postgres', 'linux'])
166
207
 
167
- If ParseTree is installed, Sequel also accepts expressions as closures, AKA block filters:
168
-
169
- my_posts = posts.filter {:category == ['ruby', 'postgres', 'linux']}
208
+ Sequel also accepts expressions:
170
209
 
171
- Which also lets you do stuff like:
172
-
173
- my_posts = posts.filter {:stamp > Date.today << 1}
210
+ my_posts = posts.filter(:stamp > Date.today << 1)
174
211
 
175
212
  Some adapters (like postgresql) will also let you specify Regexps:
176
213
 
@@ -179,19 +216,27 @@ Some adapters (like postgresql) will also let you specify Regexps:
179
216
  You can also use an inverse filter:
180
217
 
181
218
  my_posts = posts.exclude(:category => /ruby/i)
219
+ my_posts = posts.filter(:category => /ruby/i).invert # same as above
182
220
 
183
- You can then retrieve the records by using any of the retrieval methods:
221
+ You can also specify a custom WHERE clause using a string:
184
222
 
185
- my_posts.each {|row| p row}
186
-
187
- You can also specify a custom WHERE clause:
223
+ posts.filter('stamp IS NOT NULL')
224
+
225
+ You can use parameters in your string, as well (ActiveRecord style):
188
226
 
189
- posts.filter('(stamp < ?) AND (author <> ?)', Date.today - 3, author_name)
227
+ posts.filter('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
228
+ posts.filter((:stamp < Date.today - 3) & ~(:author => author_name)) # same as above
190
229
 
191
230
  Datasets can also be used as subqueries:
192
231
 
193
232
  DB[:items].filter('price > ?', DB[:items].select('AVG(price) + 100'))
194
233
 
234
+ After filtering you can retrieve the matching records by using any of the retrieval methods:
235
+
236
+ my_posts.each{|row| p row}
237
+
238
+ See the doc/dataset_filtering.rdoc file for more details.
239
+
195
240
  === Summarizing Records
196
241
 
197
242
  Counting records is easy:
@@ -205,26 +250,32 @@ Or calculate a sum:
205
250
 
206
251
  === Ordering Records
207
252
 
208
- posts.order(:stamp)
253
+ Ordering datasets is simple:
254
+
255
+ posts.order(:stamp) # ORDER BY stamp
256
+ posts.order(:stamp, :name) # ORDER BY stamp, name
209
257
 
210
258
  You can also specify descending order
211
259
 
212
- posts.order(:stamp.desc)
260
+ posts.order(:stamp.desc) # ORDER BY stamp DESC
213
261
 
214
262
  === Deleting Records
215
263
 
264
+ Deleting records from the table is done with delete:
265
+
216
266
  posts.filter('stamp < ?', Date.today - 3).delete
217
267
 
218
268
  === Inserting Records
219
269
 
220
- posts.insert(:category => 'ruby', :author => 'david')
221
-
222
- Or alternatively:
270
+ Inserting records into the table is done with insert:
223
271
 
224
- posts << {:category => 'ruby', :author => 'david'}
272
+ posts.insert(:category => 'ruby', :author => 'david')
273
+ posts << {:category => 'ruby', :author => 'david'} # same as above
225
274
 
226
275
  === Updating Records
227
276
 
277
+ Updating records in the table is done with update:
278
+
228
279
  posts.filter('stamp < ?', Date.today - 7).update(:state => 'archived')
229
280
 
230
281
  === Joining Tables
@@ -257,7 +308,7 @@ When retrieving records from joined datasets, you get the results in a single ha
257
308
  DB[:items].join(:order_items, :item_id => :id).first
258
309
  => {:id=>(could be items.id or order_items.id), :item_id=>order_items.order_id}
259
310
 
260
- Using graph, you can split the resulting dataset into separate hashes:
311
+ Using graph, you can split the result hashes into subhashes, one per join:
261
312
 
262
313
  DB[:items].graph(:order_items, :item_id => :id).first
263
- => {:items->{:id=>items.id}, :order_items=>{:id=>order_items.id, :item_id=>order_items.item_id}}
314
+ => {:items=>{:id=>items.id}, :order_items=>{:id=>order_items.id, :item_id=>order_items.item_id}}
data/Rakefile CHANGED
@@ -9,19 +9,19 @@ include FileUtils
9
9
  # Configuration
10
10
  ##############################################################################
11
11
  NAME = "sequel_core"
12
- VERS = "1.5.1"
13
- CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
14
- RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source"]
12
+ VERS = "2.0.0"
13
+ CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
14
+ RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
15
+ 'Sequel: The Database Toolkit for Ruby: Core Library and Adapters', \
16
+ '--main', 'README']
15
17
 
16
18
  ##############################################################################
17
19
  # RDoc
18
20
  ##############################################################################
19
21
  Rake::RDocTask.new do |rdoc|
20
- rdoc.rdoc_dir = "doc/rdoc"
22
+ rdoc.rdoc_dir = "rdoc"
21
23
  rdoc.options += RDOC_OPTS
22
- rdoc.main = "README"
23
- rdoc.title = "Sequel: The Database Toolkit for Ruby: Core Library and Adapters"
24
- rdoc.rdoc_files.add ["README", "COPYING", "lib/**/*.rb"]
24
+ rdoc.rdoc_files.add ["README", "COPYING", "doc/*.rdoc", "lib/**/*.rb"]
25
25
  end
26
26
 
27
27
  ##############################################################################
@@ -36,7 +36,7 @@ spec = Gem::Specification.new do |s|
36
36
  s.version = VERS
37
37
  s.platform = Gem::Platform::RUBY
38
38
  s.has_rdoc = true
39
- s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"]
39
+ s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"] + Dir["doc/*.rdoc"]
40
40
  s.rdoc_options += RDOC_OPTS + ["--exclude", "^(examples|extras)\/"]
41
41
  s.summary = "The Database Toolkit for Ruby: Core Library and Adapters"
42
42
  s.description = s.summary
@@ -45,18 +45,7 @@ spec = Gem::Specification.new do |s|
45
45
  s.homepage = "http://sequel.rubyforge.org"
46
46
  s.executables = ["sequel"]
47
47
  s.required_ruby_version = ">= 1.8.4"
48
-
49
- s.add_dependency("metaid")
50
-
51
- case RUBY_PLATFORM
52
- when /java/
53
- s.platform = "jruby"
54
- else
55
- s.platform = Gem::Platform::RUBY
56
- end
57
-
58
48
  s.files = %w(COPYING README Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
59
-
60
49
  s.require_path = "lib"
61
50
  s.bindir = "bin"
62
51
  end
@@ -162,7 +151,7 @@ STATS_DIRECTORIES = [
162
151
 
163
152
  desc "Report code statistics (KLOCs, etc) from the application"
164
153
  task :stats do
165
- require "extra/stats"
154
+ require "../extra/stats"
166
155
  verbose = true
167
156
  CodeStatistics.new(*STATS_DIRECTORIES).to_s
168
157
  end
data/bin/sequel CHANGED
@@ -2,35 +2,43 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'optparse'
5
- require 'sequel' rescue nil
6
5
  require 'sequel_core'
7
- require 'sequel_model' rescue nil
8
- require 'logger'
9
6
 
10
- $uri = nil
11
- $logfile = nil
12
- $echo = nil
7
+ begin
8
+ require 'sequel'
9
+ sequel_loaded = true
10
+ rescue LoadError
11
+ end
12
+
13
+ db_opts = {}
14
+ echo = nil
15
+ env = nil
16
+ logfile = nil
13
17
 
14
18
  opts = OptionParser.new do |opts|
15
19
  opts.banner = "Sequel: The Database Toolkit for Ruby"
16
- opts.define_head "Usage: sequel <uri> [options]"
20
+ opts.define_head "Usage: sequel <uri|path> [options]"
17
21
  opts.separator ""
18
22
  opts.separator "Examples:"
19
23
  opts.separator " sequel sqlite:///blog.db"
20
24
  opts.separator " sequel postgres://localhost/my_blog"
21
-
25
+ opts.separator " sequel config/database.yml"
22
26
  opts.separator ""
23
- opts.separator "For more information see http://code.google.com/p/ruby-sequel"
27
+ opts.separator "For more information see http://sequel.rubyforge.org"
24
28
  opts.separator ""
25
29
  opts.separator "Options:"
26
30
 
27
31
  opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
28
- $logfile = v
32
+ logfile = v
33
+ end
34
+
35
+ opts.on("-E", "--echo", "echo SQL statements") do |v|
36
+ echo = v
29
37
  end
30
38
 
31
- # opts.on("-e", "--echo", "echo SQL statements") do |v|
32
- # $echo = v
33
- # end
39
+ opts.on("-e", "--env ENV", "use environment config for database") do |env|
40
+ env = env
41
+ end
34
42
 
35
43
  opts.on_tail("-?", "--help", "Show this message") do
36
44
  puts opts
@@ -39,14 +47,15 @@ opts = OptionParser.new do |opts|
39
47
 
40
48
  opts.on_tail("-v", "--version", "Show version") do
41
49
  class << Gem; attr_accessor :loaded_specs; end
42
- specs = Gem.loaded_specs['sequel']
43
- puts "sequel #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
50
+ begin
44
51
  specs = Gem.loaded_specs['sequel_core']
45
52
  puts "sequel_core #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
46
- begin
47
- specs = Gem.loaded_specs['sequel_model']
48
- puts "sequel_model #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
53
+ if sequel_loaded
54
+ specs = Gem.loaded_specs['sequel']
55
+ puts "sequel #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
56
+ end
49
57
  rescue
58
+ puts "No gem version found"
50
59
  end
51
60
  exit
52
61
  end
@@ -60,23 +69,27 @@ if db.blank?
60
69
  exit
61
70
  end
62
71
 
63
- db_opts = {}
64
- if $logfile
65
- db_opts[:logger] = Logger.new($logfile)
66
- end
67
- if $echo
68
- db_opts[:echo] = true
72
+ if logfile || echo
73
+ require 'logger'
74
+ db_opts[:loggers] = []
75
+ db_opts[:loggers] << Logger.new(logfile) if logfile
76
+ db_opts[:loggers] << Logger.new($stdout) if echo
69
77
  end
70
78
 
71
- begin
72
- puts "db_opts = #{db_opts.inspect}"
73
- DB = Sequel.connect db, db_opts
74
- rescue => e
75
- puts e.message
76
- exit
79
+ if File.exist?(db)
80
+ require 'yaml'
81
+ db_config = YAML.load_file(db)[env || "development"]
82
+ db_config.each {|(k,v)| db_config[k.to_sym] = db_config.delete(k)}
83
+ db_config.merge!(db_opts)
77
84
  end
78
85
 
79
86
  begin
87
+ if db_config
88
+ opts = [db_config]
89
+ else
90
+ opts = [db, db_opts]
91
+ end
92
+ DB = Sequel.connect(*opts)
80
93
  DB.test_connection
81
94
  rescue => e
82
95
  puts e.message
@@ -87,85 +100,3 @@ end
87
100
  require 'irb'
88
101
  puts "Your database is stored in DB..."
89
102
  IRB.start
90
-
91
- __END__
92
-
93
- #!/usr/bin/env ruby
94
-
95
- require 'rubygems'
96
- require 'optparse'
97
- require 'bulkmail'
98
-
99
- $helo = nil
100
- $from = nil
101
- $recipients = []
102
- $content = nil
103
- $delay = 60..300
104
-
105
- opts = OptionParser.new do |opts|
106
- opts.banner = "Usage: bulkmail <options>"
107
- opts.define_head "Simple bulk-mailer."
108
- opts.separator ""
109
- opts.separator "Options:"
110
-
111
- opts.on("-h", "--helo HOSTNAME", "HELO host name.") do |v|
112
- $helo = v
113
- end
114
-
115
- opts.on("-r", "--recipients filename", "Recipients file name") do |v|
116
- $recipients = IO.readlines(v).map {|l| l =~ /(.*)(\r\n|\n)$/ ? $1 : l}.compact
117
- end
118
-
119
- opts.on("-c", "--content filename", "Content file name") do |v|
120
- $content = IO.read(v)
121
- end
122
-
123
- opts.on("-f", "--from from", "From address") do |v|
124
- $from = v
125
- end
126
-
127
- opts.on('-n', "--nodelay", "No delay") do |v|
128
- $delay = 0
129
- end
130
-
131
- # No argument, shows at tail. This will print an options summary.
132
- # Try it and see!
133
- opts.on_tail("-?", "--help", "Show this message") do
134
- puts opts
135
- exit
136
- end
137
-
138
- # Another typical switch to print the version.
139
- opts.on_tail("-v", "--version", "Show version") do
140
- class << Gem; attr_accessor :loaded_specs; end
141
- specs = Gem.loaded_specs['bulkmail']
142
- puts "bulkmail #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
143
- exit
144
- end
145
- end
146
-
147
- begin
148
- opts.parse! ARGV
149
- rescue => e
150
- puts e.message
151
- puts e.backtrace.first
152
- exit
153
- end
154
-
155
- unless $content
156
- puts opts
157
- exit
158
- end
159
-
160
- trap('INT') {exit}
161
-
162
- puts "Please hold on..."
163
-
164
- sender = BulkMail::Sender.new({
165
- :list => $recipients,
166
- :from => $from,
167
- :message => $content,
168
- :helo => $helo,
169
- :delay => $delay
170
- })
171
- sender.start