sequel 0.4.2.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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