sequel 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ *0.0.19*
2
+
3
+ * More specs for Dataset.
4
+
5
+ * Fixed Dataset#invert_order to work correctly with strings.
6
+
7
+ * Fixed Model#== to check equality of values.
8
+
9
+ * Added Model#exclude and Model#order.
10
+
11
+ * Fixed Dataset#order and Dataset#group to behave correctly when supplied with qualified field name symbols.
12
+
13
+ * Removed Database#literal. Shouldn't have been there.
14
+
15
+ * Added SQLite::Dataset#explain. Returns an array of opcode hashes.
16
+
17
+ * Specs for ConnectionPool.
18
+
1
19
  *0.0.18*
2
20
 
3
21
  * Implemented SequelError and SequelConnectionError classes. ConnectionPool#hold now catches any connection errors and reraises them SequelConnectionError.
data/README CHANGED
@@ -9,6 +9,7 @@ Sequel makes it easy to deal with multiple records without having to break your
9
9
  * {Project page}[http://code.google.com/p/ruby-sequel/]
10
10
  * {Source code}[http://ruby-sequel.googlecode.com/svn/]
11
11
  * {Bug tracking}[http://code.google.com/p/ruby-sequel/issues/list]
12
+ * {Google group}[http://groups.google.com/group/sequel-talk]
12
13
  * {RubyForge page}[http://rubyforge.org/projects/sequel/]
13
14
 
14
15
  To check out the source code:
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  include FileUtils
7
7
 
8
8
  NAME = "sequel"
9
- VERS = "0.0.18"
9
+ VERS = "0.0.19"
10
10
  CLEAN.include ['**/.*.sw?', 'pkg/*', '.config', 'doc/*', 'coverage/*']
11
11
  RDOC_OPTS = ['--quiet', '--title', "Sequel: Concise ORM for Ruby",
12
12
  "--opname", "index.html",
@@ -43,7 +43,9 @@ module Sequel
43
43
 
44
44
  def acquire(thread)
45
45
  @mutex.synchronize do
46
- @allocated[thread] = available
46
+ if conn = available
47
+ @allocated[thread] = conn
48
+ end
47
49
  end
48
50
  end
49
51
 
@@ -34,13 +34,15 @@ module Sequel
34
34
  alias_method :[], :from
35
35
 
36
36
  def execute(sql)
37
- raise RuntimeError
37
+ raise NotImplementedError
38
38
  end
39
39
 
40
+ # Acquires a database connection, yielding it to the passed block.
40
41
  def synchronize(&block)
41
42
  @pool.hold(&block)
42
43
  end
43
-
44
+
45
+ # Returns true if there is a database connection
44
46
  def test_connection
45
47
  @pool.hold {|conn|} if @pool
46
48
  true
@@ -55,15 +57,6 @@ module Sequel
55
57
  execute(sql)
56
58
  end
57
59
 
58
- # Returns a literal SQL representation of a value. This method is usually
59
- # overriden in database adapters.
60
- def literal(v)
61
- case v
62
- when String: "'%s'" % v
63
- else v.to_s
64
- end
65
- end
66
-
67
60
  # Creates a table. The easiest way to use this method is to provide a
68
61
  # block:
69
62
  # DB.create_table :posts do
@@ -104,23 +97,24 @@ module Sequel
104
97
  SQL_BEGIN = 'BEGIN'.freeze
105
98
  SQL_COMMIT = 'COMMIT'.freeze
106
99
  SQL_ROLLBACK = 'ROLLBACK'.freeze
107
-
100
+
101
+ # A simple implementation of SQL transactions. Nested transactions are not
102
+ # supported - calling #transaction within a transaction will reuse the
103
+ # current transaction. May be overridden for databases that support nested
104
+ # transactions.
108
105
  def transaction
109
106
  @pool.hold do |conn|
110
107
  @transactions ||= []
111
108
  if @transactions.include? Thread.current
112
109
  return yield(conn)
113
110
  end
114
- # ServerSide.info('BEGIN')
115
111
  conn.execute(SQL_BEGIN)
116
112
  begin
117
113
  @transactions << Thread.current
118
114
  result = yield(conn)
119
- # ServerSide.info('COMMIT')
120
115
  conn.execute(SQL_COMMIT)
121
116
  result
122
117
  rescue => e
123
- # ServerSide.info('ROLLBACK')
124
118
  conn.execute(SQL_ROLLBACK)
125
119
  raise e
126
120
  ensure
@@ -132,11 +126,14 @@ module Sequel
132
126
  @@adapters = Hash.new
133
127
 
134
128
  # Sets the adapter scheme for the database class. Call this method in
135
- # descendnants of Database to allow connection using a URL. For example:
129
+ # descendnants of Database to allow connection using a URL. For example the
130
+ # following:
136
131
  # class DB2::Database < Sequel::Database
137
132
  # set_adapter_scheme :db2
138
133
  # ...
139
134
  # end
135
+ # would allow connection using:
136
+ # Sequel.open('db2://user:password@dbserver/mydb')
140
137
  def self.set_adapter_scheme(scheme)
141
138
  @@adapters[scheme.to_sym] = self
142
139
  end
@@ -51,7 +51,7 @@ module Sequel
51
51
  # objects). If no record class is defined for the dataset, self is
52
52
  # returned.
53
53
  def naked
54
- @record_class ? self.class.new(@db, @opts) : self
54
+ @record_class ? self.class.new(@db, @opts.dup) : self
55
55
  end
56
56
 
57
57
  AS_REGEXP = /(.*)___(.*)/.freeze
@@ -90,7 +90,7 @@ module Sequel
90
90
 
91
91
  # Converts an array of sources into a comma separated list.
92
92
  def source_list(source)
93
- raise 'No source specified for query' unless source
93
+ raise SequelError, 'No source specified for query' unless source
94
94
  source.map {|i| i.is_a?(Dataset) ? i.to_table_reference : i}.
95
95
  join(COMMA_SEPARATOR)
96
96
  end
@@ -109,7 +109,7 @@ module Sequel
109
109
  when Array: v.empty? ? NULL : v.map {|i| literal(i)}.join(COMMA_SEPARATOR)
110
110
  when Dataset: SUBQUERY % v.sql
111
111
  else
112
- raise "can't express #{v.inspect}:#{v.class} as a SQL literal"
112
+ raise SequelError, "can't express #{v.inspect}:#{v.class} as a SQL literal"
113
113
  end
114
114
  end
115
115
 
@@ -195,9 +195,14 @@ module Sequel
195
195
  DESC_ORDER_REGEXP = /(.*)\sDESC/.freeze
196
196
 
197
197
  def invert_order(order)
198
- order.map do |f|
199
- f.to_s =~ DESC_ORDER_REGEXP ? $1 : f.DESC
198
+ new_order = []
199
+ order.each do |f|
200
+ f.to_s.split(',').map do |p|
201
+ p.strip!
202
+ new_order << (p =~ DESC_ORDER_REGEXP ? $1 : p.to_sym.DESC)
203
+ end
200
204
  end
205
+ new_order
201
206
  end
202
207
 
203
208
  # Returns a copy of the dataset with the results grouped by the value of
@@ -240,7 +245,7 @@ module Sequel
240
245
  # if the dataset has been grouped. See also #filter
241
246
  def where(*cond)
242
247
  if @opts[:group]
243
- raise "Can't specify a WHERE clause once the dataset has been grouped"
248
+ raise SequelError, "Can't specify a WHERE clause once the dataset has been grouped"
244
249
  else
245
250
  filter(*cond)
246
251
  end
@@ -250,7 +255,7 @@ module Sequel
250
255
  # if the dataset has not been grouped. See also #filter
251
256
  def having(*cond)
252
257
  unless @opts[:group]
253
- raise "Can only specify a HAVING clause on a grouped dataset"
258
+ raise SequelError, "Can only specify a HAVING clause on a grouped dataset"
254
259
  else
255
260
  filter(*cond)
256
261
  end
@@ -331,11 +336,11 @@ module Sequel
331
336
  end
332
337
 
333
338
  if group = opts[:group]
334
- sql << (GROUP % group.join(COMMA_SEPARATOR))
339
+ sql << (GROUP % field_list(group))
335
340
  end
336
341
 
337
342
  if order = opts[:order]
338
- sql << (ORDER % order.join(COMMA_SEPARATOR))
343
+ sql << (ORDER % field_list(order))
339
344
  end
340
345
 
341
346
  if having = opts[:having]
@@ -384,9 +389,9 @@ module Sequel
384
389
  opts = opts ? @opts.merge(opts) : @opts
385
390
 
386
391
  if opts[:group]
387
- raise "Can't update a grouped dataset"
392
+ raise SequelError, "Can't update a grouped dataset"
388
393
  elsif (opts[:from].size > 1) or opts[:join_type]
389
- raise "Can't update a joined dataset"
394
+ raise SequelError, "Can't update a joined dataset"
390
395
  end
391
396
 
392
397
  set_list = values.map {|kv| SET_FORMAT % [kv[0], literal(kv[1])]}.
@@ -406,9 +411,9 @@ module Sequel
406
411
  opts = opts ? @opts.merge(opts) : @opts
407
412
 
408
413
  if opts[:group]
409
- raise "Can't delete from a grouped dataset"
414
+ raise SequelError, "Can't delete from a grouped dataset"
410
415
  elsif opts[:from].is_a?(Array) && opts[:from].size > 1
411
- raise "Can't delete from a joined dataset"
416
+ raise SequelError, "Can't delete from a joined dataset"
412
417
  end
413
418
 
414
419
  sql = DELETE % opts[:from]
@@ -495,7 +500,8 @@ module Sequel
495
500
  end
496
501
 
497
502
  def last(num = 1)
498
- raise 'No order specified' unless @opts[:order] || (opts && opts[:order])
503
+ raise SequelError, 'No order specified' unless
504
+ @opts[:order] || (opts && opts[:order])
499
505
 
500
506
  l = {:limit => num}
501
507
  opts = {:order => invert_order(@opts[:order])}.
@@ -511,7 +517,7 @@ module Sequel
511
517
  # Deletes all records in the dataset one at a time by invoking the destroy
512
518
  # method of the associated model class.
513
519
  def destroy
514
- raise 'Dataset not associated with model' unless @record_class
520
+ raise SequelError, 'Dataset not associated with model' unless @record_class
515
521
 
516
522
  count = 0
517
523
  @db.transaction {each {|r| count += 1; r.destroy}}
@@ -531,7 +537,7 @@ class Symbol
531
537
  end
532
538
 
533
539
  def AS(target)
534
- "#{field_name} AS #{target}"
540
+ "#{to_field_name} AS #{target}"
535
541
  end
536
542
 
537
543
  def MIN; "min(#{to_field_name})"; end
@@ -556,4 +562,3 @@ class Symbol
556
562
  "#{to_s}.*"
557
563
  end
558
564
  end
559
-
data/lib/sequel/model.rb CHANGED
@@ -170,7 +170,9 @@ module Sequel
170
170
  def self.each(&block); dataset.each(&block); end
171
171
  def self.all; dataset.all; end
172
172
  def self.filter(*arg); dataset.filter(*arg); end
173
- def self.first; dataset.first; end
173
+ def self.exclude(*arg); dataset.exclude(*arg); end
174
+ def self.order(*arg); dataset.order(*arg); end
175
+ def self.first(*arg); dataset.first(*arg); end
174
176
  def self.count; dataset.count; end
175
177
  def self.map(column); dataset.map(column); end
176
178
  def self.hash_column(column); dataset.hash_column(primary_key, column); end
@@ -254,7 +256,7 @@ module Sequel
254
256
  end
255
257
 
256
258
  def ==(obj)
257
- (obj.class == model) && (obj.pkey == @pkey)
259
+ (obj.class == model) && (obj.values == @values)
258
260
  end
259
261
 
260
262
  def set(values)
@@ -172,7 +172,7 @@ module Sequel
172
172
  Postgres::Dataset.new(self, opts)
173
173
  end
174
174
 
175
- RELATION_QUERY = {:from => :pg_class, :select => :relname}.freeze
175
+ RELATION_QUERY = {:from => [:pg_class], :select => [:relname]}.freeze
176
176
  RELATION_FILTER = "(relkind = 'r') AND (relname !~ '^pg|sql')".freeze
177
177
  SYSTEM_TABLE_REGEXP = /^pg|sql/.freeze
178
178
 
data/lib/sequel/sqlite.rb CHANGED
@@ -101,6 +101,14 @@ module Sequel
101
101
  end
102
102
  self
103
103
  end
104
+
105
+ EXPLAIN = 'EXPLAIN %s'.freeze
106
+
107
+ def explain
108
+ res = []
109
+ @db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
110
+ res
111
+ end
104
112
  end
105
113
  end
106
114
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: sequel
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.18
7
- date: 2007-04-13 00:00:00 +03:00
6
+ version: 0.0.19
7
+ date: 2007-04-16 00:00:00 +03:00
8
8
  summary: Concise ORM for Ruby.
9
9
  require_paths:
10
10
  - lib
@@ -35,18 +35,18 @@ files:
35
35
  - bin/sequel
36
36
  - doc/rdoc
37
37
  - lib/sequel
38
- - lib/sequel.rb
39
- - lib/sequel/connection_pool.rb
40
- - lib/sequel/core_ext.rb
38
+ - lib/sequel/pretty_table.rb
39
+ - lib/sequel/model.rb
40
+ - lib/sequel/schema.rb
41
+ - lib/sequel/sqlite.rb
41
42
  - lib/sequel/database.rb
42
43
  - lib/sequel/dataset.rb
43
- - lib/sequel/error.rb
44
- - lib/sequel/model.rb
45
44
  - lib/sequel/mysql.rb
46
45
  - lib/sequel/postgres.rb
47
- - lib/sequel/pretty_table.rb
48
- - lib/sequel/schema.rb
49
- - lib/sequel/sqlite.rb
46
+ - lib/sequel/connection_pool.rb
47
+ - lib/sequel/core_ext.rb
48
+ - lib/sequel/error.rb
49
+ - lib/sequel.rb
50
50
  - CHANGELOG
51
51
  test_files: []
52
52