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 +22 -0
- data/Rakefile +1 -1
- data/lib/sequel/adapters/adapter_skeleton.rb +2 -2
- data/lib/sequel/adapters/ado.rb +2 -3
- data/lib/sequel/adapters/db2.rb +2 -2
- data/lib/sequel/adapters/dbi.rb +2 -3
- data/lib/sequel/adapters/informix.rb +2 -2
- data/lib/sequel/adapters/jdbc.rb +2 -2
- data/lib/sequel/adapters/mysql.rb +2 -2
- data/lib/sequel/adapters/odbc.rb +2 -2
- data/lib/sequel/adapters/openbase.rb +2 -2
- data/lib/sequel/adapters/oracle.rb +2 -2
- data/lib/sequel/adapters/postgres.rb +2 -2
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/core_sql.rb +22 -0
- data/lib/sequel/database.rb +14 -0
- data/lib/sequel/dataset.rb +4 -4
- data/lib/sequel/dataset/convenience.rb +2 -0
- data/lib/sequel/dataset/sequelizer.rb +32 -8
- data/lib/sequel/dataset/sql.rb +20 -9
- data/lib/sequel/model.rb +3 -0
- data/lib/sequel/schema/schema_generator.rb +10 -10
- data/spec/core_sql_spec.rb +7 -0
- data/spec/database_spec.rb +20 -0
- data/spec/dataset_spec.rb +52 -6
- data/spec/model_spec.rb +6 -0
- data/spec/schema_spec.rb +27 -1
- data/spec/sequelizer_spec.rb +20 -0
- metadata +55 -54
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.
|
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",
|
data/lib/sequel/adapters/ado.rb
CHANGED
data/lib/sequel/adapters/db2.rb
CHANGED
data/lib/sequel/adapters/dbi.rb
CHANGED
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -95,8 +95,8 @@ module Sequel
|
|
95
95
|
@db.execute_and_forget insert_sql(*values)
|
96
96
|
end
|
97
97
|
|
98
|
-
def update(
|
99
|
-
@db.execute_and_forget update_sql(
|
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(
|
218
|
-
@db.execute_affected(update_sql(
|
217
|
+
def update(*args, &block)
|
218
|
+
@db.execute_affected(update_sql(*args, &block))
|
219
219
|
end
|
220
220
|
|
221
221
|
def delete(opts = nil)
|
data/lib/sequel/adapters/odbc.rb
CHANGED
@@ -391,9 +391,9 @@ module Sequel
|
|
391
391
|
values.size == 1 ? values.first : values)
|
392
392
|
end
|
393
393
|
|
394
|
-
def update(
|
394
|
+
def update(*args, &block)
|
395
395
|
@db.synchronize do
|
396
|
-
result = @db.execute(update_sql(
|
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(
|
157
|
-
@db.execute update_sql(
|
156
|
+
def update(*args, &block)
|
157
|
+
@db.execute update_sql(*args, &block)
|
158
158
|
end
|
159
159
|
|
160
160
|
def delete(opts = nil)
|
data/lib/sequel/core_sql.rb
CHANGED
@@ -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
|
data/lib/sequel/database.rb
CHANGED
@@ -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)
|
data/lib/sequel/dataset.rb
CHANGED
@@ -51,9 +51,9 @@ module Sequel
|
|
51
51
|
# end
|
52
52
|
#
|
53
53
|
# # Update records.
|
54
|
-
# def update(
|
54
|
+
# def update(*args, &block)
|
55
55
|
# @db.synchronize do
|
56
|
-
# @db.execute(update_sql(
|
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
|
-
|
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 :
|
242
|
-
"(#{e[1..-1].map {|i| pt_expr(i, b)}.join(
|
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
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -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
|
-
|
477
|
-
|
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 =
|
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 =
|
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 =
|
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 =
|
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
|
data/spec/core_sql_spec.rb
CHANGED
@@ -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
|
|
data/spec/database_spec.rb
CHANGED
@@ -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__),
|
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 =
|
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
|
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
|
-
@
|
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
|
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
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|
-
-
|
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/
|
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/
|
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/
|
76
|
+
- spec/spec_helper.rb
|
75
77
|
- spec/worker_spec.rb
|
76
|
-
- spec/core_sql_spec.rb
|
77
78
|
- lib/sequel
|
78
|
-
- lib/sequel/
|
79
|
-
- lib/sequel/
|
80
|
-
- lib/sequel/
|
81
|
-
- lib/sequel/
|
82
|
-
- lib/sequel/
|
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/
|
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/
|
103
|
-
- lib/sequel/
|
104
|
-
- lib/sequel/
|
105
|
-
- lib/sequel/
|
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/
|
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
|