sequel 0.4.2.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,25 @@
1
+ === 0.4.3 (2007-12-15)
2
+
3
+ * Fixed Dataset#update to accept strings (#98).
4
+
5
+ * Fixed Model.[] to raise for boolean argument (#97).
6
+
7
+ * Added Database#add_index method (thanks coda.hale).
8
+
9
+ * Added error reporting for filtering on comparison not in a block (thanks Jim Morris).
10
+
11
+ * Added support for inline index definition (thanks Dado).
12
+
13
+ * Added Database#create_table! method for forcibly creating a table (thanks Dado).
14
+
15
+ * Added support for using Dataset#update with block.
16
+
17
+ * Changed subscript access to use | operator.
18
+
19
+ * Fixed subscript access in sequelizer.
20
+
21
+ * Added support for subscript access using Symbol#/ operator.
22
+
1
23
  === 0.4.2.2 (2007-12-10)
2
24
 
3
25
  * Improved code coverage.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  include FileUtils
7
7
 
8
8
  NAME = "sequel"
9
- VERS = "0.4.2.2"
9
+ VERS = "0.4.3"
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",
@@ -55,8 +55,8 @@ module Sequel
55
55
  @db.do insert_sql(*values)
56
56
  end
57
57
 
58
- def update(values, opts = nil)
59
- @db.do update_sql(values, opts)
58
+ def update(*args, &block)
59
+ @db.do update_sql(*args, &block)
60
60
  end
61
61
 
62
62
  def delete(opts = nil)
@@ -87,9 +87,8 @@ module Sequel
87
87
  @db.do insert_sql(*values)
88
88
  end
89
89
 
90
- def update(values, opts = nil)
91
- @db.do update_sql(values, opts)
92
- self
90
+ def update(*args, &block)
91
+ @db.do update_sql(*args, &block)
93
92
  end
94
93
 
95
94
  def delete(opts = nil)
@@ -144,8 +144,8 @@ module Sequel
144
144
  @db.do insert_sql(*values)
145
145
  end
146
146
 
147
- def update(values, opts = nil)
148
- @db.do update_sql(values, opts)
147
+ def update(*args, &block)
148
+ @db.do update_sql(*args, &block)
149
149
  end
150
150
 
151
151
  def delete(opts = nil)
@@ -113,9 +113,8 @@ module Sequel
113
113
  @db.do insert_sql(*values)
114
114
  end
115
115
 
116
- def update(values, opts = nil)
117
- @db.do update_sql(values, opts)
118
- self
116
+ def update(*args, &block)
117
+ @db.do update_sql(*args, &block)
119
118
  end
120
119
 
121
120
  def delete(opts = nil)
@@ -74,8 +74,8 @@ module Sequel
74
74
  @db.do insert_sql(*values)
75
75
  end
76
76
 
77
- def update(values, opts = nil)
78
- @db.do update_sql(values, opts)
77
+ def update(*args, &block)
78
+ @db.do update_sql(*args, &block)
79
79
  end
80
80
 
81
81
  def delete(opts = nil)
@@ -95,8 +95,8 @@ module Sequel
95
95
  @db.execute_and_forget insert_sql(*values)
96
96
  end
97
97
 
98
- def update(values, opts = nil)
99
- @db.execute_and_forget update_sql(values, opts)
98
+ def update(*args, &block)
99
+ @db.execute_and_forget update_sql(*args, &block)
100
100
  end
101
101
 
102
102
  def delete(opts = nil)
@@ -214,8 +214,8 @@ module Sequel
214
214
  @db.execute_insert(insert_sql(*values))
215
215
  end
216
216
 
217
- def update(values, opts = nil)
218
- @db.execute_affected(update_sql(values, opts))
217
+ def update(*args, &block)
218
+ @db.execute_affected(update_sql(*args, &block))
219
219
  end
220
220
 
221
221
  def delete(opts = nil)
@@ -127,8 +127,8 @@ module Sequel
127
127
  @db.do insert_sql(*values)
128
128
  end
129
129
 
130
- def update(values, opts = nil)
131
- @db.do update_sql(values, opts)
130
+ def update(*args, &block)
131
+ @db.do update_sql(*args, &block)
132
132
  self
133
133
  end
134
134
 
@@ -77,8 +77,8 @@ module Sequel
77
77
  @db.do insert_sql(*values)
78
78
  end
79
79
 
80
- def update(values, opts = nil)
81
- @db.do update_sql(values, opts)
80
+ def update(*args, &block)
81
+ @db.do update_sql(*args, &block)
82
82
  end
83
83
 
84
84
  def delete(opts = nil)
@@ -86,8 +86,8 @@ module Sequel
86
86
  @db.do insert_sql(*values)
87
87
  end
88
88
 
89
- def update(values, opts = nil)
90
- @db.do update_sql(values, opts)
89
+ def update(*args, &block)
90
+ @db.do update_sql(*args, &block)
91
91
  end
92
92
 
93
93
  def delete(opts = nil)
@@ -391,9 +391,9 @@ module Sequel
391
391
  values.size == 1 ? values.first : values)
392
392
  end
393
393
 
394
- def update(values, opts = nil)
394
+ def update(*args, &block)
395
395
  @db.synchronize do
396
- result = @db.execute(update_sql(values))
396
+ result = @db.execute(update_sql(*args, &block))
397
397
  begin
398
398
  affected = result.cmdtuples
399
399
  ensure
@@ -153,8 +153,8 @@ module Sequel
153
153
  @db.execute_insert insert_sql(*values)
154
154
  end
155
155
 
156
- def update(values, opts = nil)
157
- @db.execute update_sql(values, opts)
156
+ def update(*args, &block)
157
+ @db.execute update_sql(*args, &block)
158
158
  end
159
159
 
160
160
  def delete(opts = nil)
@@ -86,6 +86,22 @@ module Sequel
86
86
  end
87
87
  end
88
88
 
89
+ class Subscript < Expression
90
+ def initialize(f, sub); @f, @sub = f, sub; end
91
+ def |(sub)
92
+ unless Array === sub
93
+ sub = [sub]
94
+ end
95
+ Subscript.new(@f, @sub << sub)
96
+ end
97
+
98
+ COMMA_SEPARATOR = ", ".freeze
99
+
100
+ def to_s(ds)
101
+ "#{@f}[#{@sub.join(COMMA_SEPARATOR)}]"
102
+ end
103
+ end
104
+
89
105
  class ColumnAll < Expression
90
106
  def initialize(t); @t = t; end
91
107
  def to_s(ds); "#{@t}.*"; end
@@ -124,6 +140,12 @@ end
124
140
 
125
141
  class Symbol
126
142
  def [](*args); Sequel::SQL::Function.new(self, *args); end
143
+ def |(sub)
144
+ unless Array === sub
145
+ sub = [sub]
146
+ end
147
+ Sequel::SQL::Subscript.new(self, sub)
148
+ end
127
149
 
128
150
  COLUMN_REF_RE1 = /^(\w+)__(\w+)___(\w+)/.freeze
129
151
  COLUMN_REF_RE2 = /^(\w+)___(\w+)$/.freeze
@@ -177,11 +177,25 @@ module Sequel
177
177
  create_table_sql_list(*g.create_info).each {|sta| execute(sta)}
178
178
  end
179
179
 
180
+ # Forcibly creates a table. If the table already exists it is dropped.
181
+ def create_table!(name, &block)
182
+ drop_table(name) rescue nil
183
+ create_table(name, &block)
184
+ end
185
+
180
186
  # Drops one or more tables corresponding to the given table names.
181
187
  def drop_table(*names)
182
188
  names.each {|n| execute(drop_table_sql(n))}
183
189
  end
184
190
 
191
+ # Adds an index to a table for the given columns:
192
+ #
193
+ # DB.add_index(:posts, :title)
194
+ # DB.add_index(:posts, [:author, :title], :unique => true)
195
+ def add_index(table, columns, options = {})
196
+ execute(index_definition_sql(table, options.update(:columns => [columns])))
197
+ end
198
+
185
199
  # Returns true if the given table exists.
186
200
  def table_exists?(name)
187
201
  if respond_to?(:tables)
@@ -51,9 +51,9 @@ module Sequel
51
51
  # end
52
52
  #
53
53
  # # Update records.
54
- # def update(values, opts = nil)
54
+ # def update(*args, &block)
55
55
  # @db.synchronize do
56
- # @db.execute(update_sql(values, opts)).affected_rows
56
+ # @db.execute(update_sql(*args, &block)).affected_rows
57
57
  # end
58
58
  # end
59
59
  #
@@ -154,8 +154,8 @@ module Sequel
154
154
  end
155
155
 
156
156
  # Updates the dataset with the given values.
157
- def set(*args)
158
- update(*args)
157
+ def set(*args, &block)
158
+ update(*args, &block)
159
159
  end
160
160
 
161
161
  # Iterates over the records in the dataset
@@ -22,10 +22,12 @@ module Sequel
22
22
  NAKED_HASH = {:naked => true}.freeze
23
23
 
24
24
  # Returns the first value of the first reecord in the dataset.
25
+ # Returns nill if dataset is empty.
25
26
  def single_value(opts = nil)
26
27
  opts = opts ? NAKED_HASH.merge(opts) : NAKED_HASH
27
28
  # reset the columns cache so it won't fuck subsequent calls to columns
28
29
  each(opts) {|r| @columns = nil; return r.values.first}
30
+ nil
29
31
  end
30
32
 
31
33
  # Returns the first record in the dataset. If the num argument is specified,
@@ -122,7 +122,7 @@ class Sequel::Dataset
122
122
  l = eval_expr(e[1], b)
123
123
  r = eval_expr(e[3][1], b)
124
124
  match_expr(l, r)
125
- when :+, :-, :*, :/, :%
125
+ when :+, :-, :*, :%, :/
126
126
  l = eval_expr(e[1], b)
127
127
  r = eval_expr(e[3][1], b)
128
128
  if l.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression) || \
@@ -131,6 +131,21 @@ class Sequel::Dataset
131
131
  else
132
132
  ext_expr(e, b)
133
133
  end
134
+ when :<<
135
+ l = eval_expr(e[1], b)
136
+ r = eval_expr(e[3][1], b)
137
+ "#{literal(l)} = #{literal(r)}".lit
138
+ when :|
139
+ l = eval_expr(e[1], b)
140
+ r = eval_expr(e[3][1], b)
141
+ if l.is_one_of?(Symbol, Sequel::SQL::Subscript)
142
+ l|r
143
+ elsif l.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression) || \
144
+ r.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression)
145
+ "(#{literal(l)} #{op} #{literal(r)})".lit
146
+ else
147
+ ext_expr(e, b)
148
+ end
134
149
  when :in, :in?
135
150
  # in/in? operators are supported using two forms:
136
151
  # :x.in([1, 2, 3])
@@ -229,21 +244,30 @@ class Sequel::Dataset
229
244
  end
230
245
  end
231
246
 
232
- def pt_expr(e, b) #:nodoc:
247
+ JOIN_AND = " AND ".freeze
248
+ JOIN_COMMA = ", ".freeze
249
+
250
+ def pt_expr(e, b, comma_separated = false) #:nodoc:
233
251
  case e[0]
234
252
  when :not # negation: !x, (x != y), (x !~ y)
235
253
  if (e[1][0] == :lit) && (Symbol === e[1][1])
236
254
  # translate (!:x) into (x = 'f')
237
255
  compare_expr(e[1][1], false)
238
256
  else
239
- "(NOT #{pt_expr(e[1], b)})"
257
+ "(NOT #{pt_expr(e[1], b, comma_separated)})"
240
258
  end
241
- when :block, :and # block of statements, x && y
242
- "(#{e[1..-1].map {|i| pt_expr(i, b)}.join(" AND ")})"
259
+ when :and # x && y
260
+ "(#{e[1..-1].map {|i| pt_expr(i, b, comma_separated)}.join(JOIN_AND)})"
243
261
  when :or # x || y
244
- "(#{pt_expr(e[1], b)} OR #{pt_expr(e[2], b)})"
262
+ "(#{pt_expr(e[1], b, comma_separated)} OR #{pt_expr(e[2], b, comma_separated)})"
245
263
  when :call, :vcall, :iter, :match3 # method calls, blocks
246
264
  eval_expr(e, b)
265
+ when :block # block of statements
266
+ if comma_separated
267
+ "#{e[1..-1].map {|i| pt_expr(i, b, comma_separated)}.join(JOIN_COMMA)}"
268
+ else
269
+ "(#{e[1..-1].map {|i| pt_expr(i, b, comma_separated)}.join(JOIN_AND)})"
270
+ end
247
271
  else # literals
248
272
  if e == [:lvar, :block]
249
273
  eval_expr(e, b)
@@ -254,9 +278,9 @@ class Sequel::Dataset
254
278
  end
255
279
 
256
280
  # Translates a Ruby block into an SQL expression.
257
- def proc_to_sql(proc)
281
+ def proc_to_sql(proc, comma_separated = false)
258
282
  c = Class.new {define_method(:m, &proc)}
259
- pt_expr(ParseTree.translate(c, :m)[2][2], proc.binding)
283
+ pt_expr(ParseTree.translate(c, :m)[2][2], proc.binding, comma_separated)
260
284
  end
261
285
  end
262
286
  end
@@ -203,6 +203,9 @@ module Sequel
203
203
  def filter(*cond, &block)
204
204
  clause = (@opts[:group] ? :having : :where)
205
205
  cond = cond.first if cond.size == 1
206
+ if cond === true || cond === false
207
+ raise SequelError, "Invalid filter specified. Did you mean to supply a block?"
208
+ end
206
209
  parenthesize = !(cond.is_a?(Hash) || cond.is_a?(Array))
207
210
  filter = cond.is_a?(Hash) && cond
208
211
  if @opts[clause]
@@ -464,7 +467,7 @@ module Sequel
464
467
  #
465
468
  # dataset.update_sql(:price => 100, :category => 'software') #=>
466
469
  # "UPDATE items SET price = 100, category = 'software'"
467
- def update_sql(values, opts = nil)
470
+ def update_sql(values = {}, opts = nil, &block)
468
471
  opts = opts ? @opts.merge(opts) : @opts
469
472
 
470
473
  if opts[:group]
@@ -472,15 +475,23 @@ module Sequel
472
475
  elsif (opts[:from].size > 1) or opts[:join]
473
476
  raise SequelError, "Can't update a joined dataset"
474
477
  end
475
-
476
- if values.is_a?(Array) && values.keys
477
- values = values.to_hash
478
+
479
+ sql = "UPDATE #{@opts[:from]} SET "
480
+ if block
481
+ sql << proc_to_sql(block, true)
482
+ else
483
+ # check if array with keys
484
+ values = values.to_hash if values.is_a?(Array) && values.keys
485
+ if values.is_a?(Hash)
486
+ # get values from hash
487
+ values = transform_save(values) if @transform
488
+ set = values.map {|k, v| "#{literal(k)} = #{literal(v)}"}.join(COMMA_SEPARATOR)
489
+ else
490
+ # copy values verbatim
491
+ set = values
492
+ end
493
+ sql << set
478
494
  end
479
- values = transform_save(values) if @transform
480
- set_list = values.map {|k, v| "#{literal(k)} = #{literal(v)}"}.
481
- join(COMMA_SEPARATOR)
482
- sql = "UPDATE #{@opts[:from]} SET #{set_list}"
483
-
484
495
  if where = opts[:where]
485
496
  sql << " WHERE #{where}"
486
497
  end
data/lib/sequel/model.rb CHANGED
@@ -255,6 +255,9 @@ module Sequel
255
255
 
256
256
  def self.[](*args)
257
257
  args = args.first if (args.size == 1)
258
+ if args === true || args === false
259
+ raise SequelError, "Invalid filter specified. Did you mean to supply a hash?"
260
+ end
258
261
  dataset[(Hash === args) ? args : primary_key_hash(args)]
259
262
  end
260
263
 
@@ -10,7 +10,7 @@ module Sequel
10
10
  instance_eval(&block)
11
11
  end
12
12
 
13
- def method_missing(type, name = nil, opts = nil)
13
+ def method_missing(type, name = nil, opts = {})
14
14
  name ? column(name, type, opts) : super
15
15
  end
16
16
 
@@ -19,9 +19,7 @@ module Sequel
19
19
  end
20
20
 
21
21
  def primary_key(name, *args)
22
- @primary_key = @db.serial_primary_key_options.merge({
23
- :name => name
24
- })
22
+ @primary_key = @db.serial_primary_key_options.merge({:name => name})
25
23
 
26
24
  if opts = args.pop
27
25
  opts = {:type => opts} unless opts.is_a?(Hash)
@@ -33,12 +31,14 @@ module Sequel
33
31
  @primary_key
34
32
  end
35
33
 
36
- def column(name, type, opts = nil)
37
- @columns << {:name => name, :type => type}.merge(opts || {})
34
+ def column(name, type, opts = {})
35
+ @columns << {:name => name, :type => type}.merge(opts)
36
+ index(name) if opts[:index]
38
37
  end
39
38
 
40
- def foreign_key(name, opts = nil)
41
- @columns << {:name => name, :type => :integer}.merge(opts || {})
39
+ def foreign_key(name, opts = {})
40
+ @columns << {:name => name, :type => :integer}.merge(opts)
41
+ index(name) if opts[:index]
42
42
  end
43
43
 
44
44
  def has_column?(name)
@@ -46,9 +46,9 @@ module Sequel
46
46
  false
47
47
  end
48
48
 
49
- def index(columns, opts = nil)
49
+ def index(columns, opts = {})
50
50
  columns = [columns] unless columns.is_a?(Array)
51
- @indexes << {:columns => columns}.merge(opts || {})
51
+ @indexes << {:columns => columns}.merge(opts)
52
52
  end
53
53
 
54
54
  def create_info
@@ -279,5 +279,12 @@ context "Symbol" do
279
279
  specify "should raise NoMethodError for non-uppercase invalid methods" do
280
280
  proc {:abc.dfaxs}.should raise_error(NoMethodError)
281
281
  end
282
+
283
+ specify "should support subscript access using | operator" do
284
+ (:abc|1).to_s(@ds).should == 'abc[1]'
285
+ (:abc|[1]).to_s(@ds).should == 'abc[1]'
286
+ (:abc|[1, 2]).to_s(@ds).should == 'abc[1, 2]'
287
+ (:abc|1|2).to_s(@ds).should == 'abc[1, 2]'
288
+ end
282
289
  end
283
290
 
@@ -229,6 +229,26 @@ context "Database#create_table" do
229
229
  end
230
230
  end
231
231
 
232
+ context "Database#add_index" do
233
+ setup do
234
+ @db = DummyDatabase.new
235
+ end
236
+
237
+ specify "should construct proper SQL" do
238
+ @db.add_index :test, :name, :unique => true
239
+ @db.sqls.should == [
240
+ 'CREATE UNIQUE INDEX test_name_index ON test (name)'
241
+ ]
242
+ end
243
+
244
+ specify "should accept multiple columns" do
245
+ @db.add_index :test, [:one, :two]
246
+ @db.sqls.should == [
247
+ 'CREATE INDEX test_one_two_index ON test (one, two)'
248
+ ]
249
+ end
250
+ end
251
+
232
252
  class Dummy2Database < Sequel::Database
233
253
  attr_reader :sql
234
254
  def execute(sql); @sql = sql; end
data/spec/dataset_spec.rb CHANGED
@@ -1,4 +1,12 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ SQLITE_DB = Sequel("sqlite:/")
4
+ SQLITE_DB.create_table :items do
5
+ integer :id, :primary_key => true, :auto_increment => true
6
+ text :name
7
+ float :value
8
+ end
9
+ SQLITE_DB.create_table(:time) {timestamp :t}
2
10
 
3
11
  context "Dataset" do
4
12
  setup do
@@ -6,7 +14,7 @@ context "Dataset" do
6
14
  end
7
15
 
8
16
  specify "should accept database and opts in initialize" do
9
- db = 'db'
17
+ db = "db"
10
18
  opts = {:from => :test}
11
19
  d = Sequel::Dataset.new(db, opts)
12
20
  d.db.should be(db)
@@ -158,6 +166,9 @@ context "A simple dataset" do
158
166
  specify "should format an update statement" do
159
167
  @dataset.update_sql(:name => 'abc').should ==
160
168
  "UPDATE test SET name = 'abc'"
169
+
170
+ @dataset.update_sql {:x << :y}.should ==
171
+ "UPDATE test SET x = y"
161
172
  end
162
173
 
163
174
  specify "should format an update statement with array with keys" do
@@ -352,6 +363,14 @@ context "Dataset#where" do
352
363
  @dataset.filter {:c.like? 'ABC%'}.sql.should ==
353
364
  "SELECT * FROM test WHERE (c LIKE 'ABC%')"
354
365
  end
366
+
367
+ specify "should raise if receiving a single boolean value" do
368
+ # the result of erroneous use of comparison not in a block
369
+ # so instead of filter{:x == y} someone writes filter(:x == y)
370
+
371
+ proc {@dataset.filter(:a == 1)}.should raise_error(SequelError)
372
+ proc {@dataset.filter(:a != 1)}.should raise_error(SequelError)
373
+ end
355
374
  end
356
375
 
357
376
  context "Dataset#or" do
@@ -1073,17 +1092,23 @@ context "Dataset#set" do
1073
1092
  @@last_sql
1074
1093
  end
1075
1094
 
1076
- def update(*args)
1077
- @@last_sql = update_sql(*args)
1095
+ def update(*args, &block)
1096
+ @@last_sql = update_sql(*args, &block)
1078
1097
  end
1079
1098
  end
1080
1099
 
1081
1100
  @d = c.new(nil).from(:items)
1082
1101
  end
1083
1102
 
1084
- specify "should act as alis to #update" do
1103
+ specify "should act as alias to #update" do
1085
1104
  @d.set({:x => 3})
1086
1105
  @d.last_sql.should == 'UPDATE items SET x = 3'
1106
+
1107
+ @d.set {:x << :x + 1}
1108
+ @d.last_sql.should == 'UPDATE items SET x = (x + 1)'
1109
+
1110
+ @d.set {(:x|1) << (:x|2) + 1}
1111
+ @d.last_sql.should == 'UPDATE items SET x[1] = (x[2] + 1)'
1087
1112
  end
1088
1113
  end
1089
1114
 
@@ -1398,8 +1423,13 @@ context "Dataset#single_record" do
1398
1423
  @cc = Class.new(@c) do
1399
1424
  def fetch_rows(sql); end
1400
1425
  end
1426
+
1401
1427
  @d = @c.new(nil).from(:test)
1402
1428
  @e = @cc.new(nil).from(:test)
1429
+
1430
+ @d_empty = SQLITE_DB[:items]
1431
+ @d_empty.delete # remove all records
1432
+
1403
1433
  end
1404
1434
 
1405
1435
  specify "should call each and return the first record" do
@@ -1411,7 +1441,7 @@ context "Dataset#single_record" do
1411
1441
  end
1412
1442
 
1413
1443
  specify "should return nil if no record is present" do
1414
- @e.single_record.should be_nil
1444
+ @d_empty.single_record.should be_nil
1415
1445
  end
1416
1446
  end
1417
1447
 
@@ -1423,6 +1453,8 @@ context "Dataset#single_value" do
1423
1453
  end
1424
1454
  end
1425
1455
  @d = @c.new(nil).from(:test)
1456
+ @d_empty = SQLITE_DB[:items]
1457
+ @d_empty.delete # remove all records
1426
1458
  end
1427
1459
 
1428
1460
  specify "should call each and return the first value of the first record" do
@@ -1432,6 +1464,11 @@ context "Dataset#single_value" do
1432
1464
  specify "should pass opts to each" do
1433
1465
  @d.single_value(:limit => 3).should == 'SELECT * FROM test LIMIT 3'
1434
1466
  end
1467
+
1468
+ specify "should return nil" do
1469
+ @d_empty.single_value.should be_nil
1470
+ end
1471
+
1435
1472
  end
1436
1473
 
1437
1474
  context "Dataset#set_row_proc" do
@@ -2330,3 +2367,12 @@ context "Dataset#create_or_replace_view" do
2330
2367
  end
2331
2368
  end
2332
2369
 
2370
+ context "Dataset#update_sql" do
2371
+ setup do
2372
+ @ds = Sequel::Dataset.new(nil).from(:items)
2373
+ end
2374
+
2375
+ specify "should accept strings" do
2376
+ @ds.update_sql("a = b").should == "UPDATE items SET a = b"
2377
+ end
2378
+ end
data/spec/model_spec.rb CHANGED
@@ -702,6 +702,12 @@ context "Model.[]" do
702
702
  $sqls.last.should == "SELECT * FROM items WHERE (id = 9999) LIMIT 1"
703
703
  end
704
704
 
705
+ specify "should raise for boolean argument (mistaken comparison)" do
706
+ # This in order to prevent stuff like Model[:a == 'b']
707
+ proc {@c[:a == 1]}.should raise_error(SequelError)
708
+ proc {@c[:a != 1]}.should raise_error(SequelError)
709
+ end
710
+
705
711
  specify "should work correctly for custom primary key" do
706
712
  @c.set_primary_key :name
707
713
  @c['sharon'].should be_a_kind_of(@c)
data/spec/schema_spec.rb CHANGED
@@ -151,6 +151,21 @@ context "DB#create_table" do
151
151
  @db.sqls.clear
152
152
  end
153
153
 
154
+ specify "should accept inline index definition" do
155
+ @db.create_table(:cats) do
156
+ integer :id, :index => true
157
+ end
158
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
159
+ end
160
+
161
+ specify "should accept inline index definition for foreign keys" do
162
+ @db.create_table(:cats) do
163
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade, :index => true
164
+ end
165
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)",
166
+ "CREATE INDEX cats_project_id_index ON cats (project_id)"]
167
+ end
168
+
154
169
  specify "should accept index definitions" do
155
170
  @db.create_table(:cats) do
156
171
  integer :id
@@ -184,7 +199,7 @@ context "DB#create_table" do
184
199
  @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_index ON cats (id)"]
185
200
  end
186
201
 
187
- specify "should accept compound index definitions" do
202
+ specify "should accept composite index definitions" do
188
203
  @db.create_table(:cats) do
189
204
  integer :id
190
205
  index [:id, :name], :unique => true
@@ -193,6 +208,17 @@ context "DB#create_table" do
193
208
  end
194
209
  end
195
210
 
211
+ context "DB#create_table!" do
212
+ setup do
213
+ @db = SchemaDummyDatabase.new
214
+ end
215
+
216
+ specify "should drop the table and then create it" do
217
+ @db.create_table!(:cats) {}
218
+ @db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
219
+ end
220
+ end
221
+
196
222
  context "DB#drop_table" do
197
223
  setup do
198
224
  @db = SchemaDummyDatabase.new
@@ -8,6 +8,10 @@ context "Proc#to_sql" do
8
8
  def to_sql
9
9
  DS.proc_to_sql(self)
10
10
  end
11
+
12
+ def to_sql_comma_separated
13
+ DS.proc_to_sql(self, true)
14
+ end
11
15
  end
12
16
 
13
17
  def DS.match_expr(l, r)
@@ -64,6 +68,12 @@ context "Proc#to_sql" do
64
68
  proc {:x == y2}.to_sql.should == "(x = 111)"
65
69
  end
66
70
 
71
+ specify "sould support subscript access on symbols" do
72
+ proc {:x|1 > 0}.to_sql.should == "(x[1] > 0)"
73
+ proc {:x|2|3 > 0}.to_sql.should == "(x[2, 3] > 0)"
74
+ proc {:x|[4, 5] > 0}.to_sql.should == "(x[4, 5] > 0)"
75
+ end
76
+
67
77
  specify "should support constants" do
68
78
  ZZZ = 444
69
79
  proc {:x == ZZZ}.to_sql.should == "(x = 444)"
@@ -117,12 +127,22 @@ context "Proc#to_sql" do
117
127
  proc {:x && :y && :z}.to_sql.should == "(x AND (y AND z))"
118
128
  end
119
129
 
130
+ specify "should support << operator for assignment" do
131
+ proc {:x << 1}.to_sql.should == "x = 1"
132
+ end
133
+
120
134
  specify "should concatenate separate statements using AND" do
121
135
  proc {:x == 20; :y == 30}.to_sql.should == "((x = 20) AND (y = 30))"
122
136
  proc {:x != 1; :y != 2; :z != 3}.to_sql.should == \
123
137
  "((NOT (x = 1)) AND (NOT (y = 2)) AND (NOT (z = 3)))"
124
138
  end
125
139
 
140
+ specify "should concatenate separate statements using custom join argument" do
141
+ proc {:x << 20; :y << 30}.to_sql_comma_separated.should == "x = 20, y = 30"
142
+ z = 333
143
+ proc {:x << :x + 1; :y << z}.to_sql_comma_separated.should == "x = (x + 1), y = 333"
144
+ end
145
+
126
146
  specify "should support || operator" do
127
147
  proc {1 || 2}.to_sql.should == "(1 OR 2)"
128
148
  proc {:x > 100 || :y < 100}.to_sql.should == "((x > 100) OR (y < 100))"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-11 00:00:00 +02:00
12
+ date: 2007-12-15 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -54,77 +54,78 @@ files:
54
54
  - README
55
55
  - Rakefile
56
56
  - bin/sequel
57
- - spec/dataset_spec.rb
58
- - spec/connection_pool_spec.rb
59
- - spec/database_spec.rb
60
- - spec/core_ext_spec.rb
57
+ - doc/rdoc
61
58
  - spec/adapters
62
- - spec/adapters/sqlite_spec.rb
59
+ - spec/adapters/informix_spec.rb
63
60
  - spec/adapters/mysql_spec.rb
64
- - spec/adapters/postgres_spec.rb
65
61
  - spec/adapters/oracle_spec.rb
66
- - spec/adapters/informix_spec.rb
62
+ - spec/adapters/postgres_spec.rb
63
+ - spec/adapters/sqlite_spec.rb
64
+ - spec/array_keys_spec.rb
65
+ - spec/connection_pool_spec.rb
66
+ - spec/core_ext_spec.rb
67
+ - spec/core_sql_spec.rb
68
+ - spec/database_spec.rb
69
+ - spec/dataset_spec.rb
67
70
  - spec/migration_spec.rb
68
- - spec/schema_spec.rb
69
- - spec/schema_generator_spec.rb
70
- - spec/pretty_table_spec.rb
71
- - spec/spec_helper.rb
72
71
  - spec/model_spec.rb
72
+ - spec/pretty_table_spec.rb
73
+ - spec/schema_generator_spec.rb
74
+ - spec/schema_spec.rb
73
75
  - spec/sequelizer_spec.rb
74
- - spec/array_keys_spec.rb
76
+ - spec/spec_helper.rb
75
77
  - spec/worker_spec.rb
76
- - spec/core_sql_spec.rb
77
78
  - lib/sequel
78
- - lib/sequel/pretty_table.rb
79
- - lib/sequel/model.rb
80
- - lib/sequel/schema.rb
81
- - lib/sequel/database.rb
82
- - lib/sequel/dataset.rb
79
+ - lib/sequel/adapters
80
+ - lib/sequel/adapters/adapter_skeleton.rb
81
+ - lib/sequel/adapters/ado.rb
82
+ - lib/sequel/adapters/db2.rb
83
+ - lib/sequel/adapters/dbi.rb
84
+ - lib/sequel/adapters/informix.rb
85
+ - lib/sequel/adapters/jdbc.rb
86
+ - lib/sequel/adapters/mysql.rb
87
+ - lib/sequel/adapters/odbc.rb
88
+ - lib/sequel/adapters/odbc_mssql.rb
89
+ - lib/sequel/adapters/openbase.rb
90
+ - lib/sequel/adapters/oracle.rb
91
+ - lib/sequel/adapters/postgres.rb
92
+ - lib/sequel/adapters/sqlite.rb
93
+ - lib/sequel/ado.rb
94
+ - lib/sequel/array_keys.rb
83
95
  - lib/sequel/connection_pool.rb
84
96
  - lib/sequel/core_ext.rb
85
- - lib/sequel/error.rb
97
+ - lib/sequel/core_sql.rb
98
+ - lib/sequel/database.rb
86
99
  - lib/sequel/dataset
87
- - lib/sequel/dataset/sql.rb
88
- - lib/sequel/dataset/sequelizer.rb
89
100
  - lib/sequel/dataset/convenience.rb
101
+ - lib/sequel/dataset/sequelizer.rb
102
+ - lib/sequel/dataset/sql.rb
103
+ - lib/sequel/dataset.rb
104
+ - lib/sequel/db2.rb
105
+ - lib/sequel/dbi.rb
106
+ - lib/sequel/error.rb
107
+ - lib/sequel/informix.rb
90
108
  - lib/sequel/migration.rb
91
- - lib/sequel/schema
92
- - lib/sequel/schema/schema_sql.rb
93
- - lib/sequel/schema/schema_generator.rb
94
109
  - lib/sequel/model
95
- - lib/sequel/model/record.rb
96
- - lib/sequel/model/relations.rb
97
- - lib/sequel/model/schema.rb
98
- - lib/sequel/model/hooks.rb
99
110
  - lib/sequel/model/base.rb
100
111
  - lib/sequel/model/caching.rb
112
+ - lib/sequel/model/hooks.rb
101
113
  - lib/sequel/model/plugins.rb
102
- - lib/sequel/array_keys.rb
103
- - lib/sequel/worker.rb
104
- - lib/sequel/core_sql.rb
105
- - lib/sequel/informix.rb
106
- - lib/sequel/adapters
107
- - lib/sequel/adapters/dbi.rb
108
- - lib/sequel/adapters/sqlite.rb
109
- - lib/sequel/adapters/ado.rb
110
- - lib/sequel/adapters/mysql.rb
111
- - lib/sequel/adapters/oracle.rb
112
- - lib/sequel/adapters/postgres.rb
113
- - lib/sequel/adapters/db2.rb
114
- - lib/sequel/adapters/odbc.rb
115
- - lib/sequel/adapters/informix.rb
116
- - lib/sequel/adapters/odbc_mssql.rb
117
- - lib/sequel/adapters/openbase.rb
118
- - lib/sequel/adapters/jdbc.rb
119
- - lib/sequel/adapters/adapter_skeleton.rb
120
- - lib/sequel/dbi.rb
121
- - lib/sequel/sqlite.rb
122
- - lib/sequel/ado.rb
123
- - lib/sequel/oracle.rb
114
+ - lib/sequel/model/record.rb
115
+ - lib/sequel/model/relations.rb
116
+ - lib/sequel/model/schema.rb
117
+ - lib/sequel/model.rb
124
118
  - lib/sequel/mysql.rb
125
- - lib/sequel/postgres.rb
126
119
  - lib/sequel/odbc.rb
127
- - lib/sequel/db2.rb
120
+ - lib/sequel/oracle.rb
121
+ - lib/sequel/postgres.rb
122
+ - lib/sequel/pretty_table.rb
123
+ - lib/sequel/schema
124
+ - lib/sequel/schema/schema_generator.rb
125
+ - lib/sequel/schema/schema_sql.rb
126
+ - lib/sequel/schema.rb
127
+ - lib/sequel/sqlite.rb
128
+ - lib/sequel/worker.rb
128
129
  - lib/sequel.rb
129
130
  - CHANGELOG
130
131
  has_rdoc: true