sequel 0.2.0.1 → 0.2.0.2
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/core_ext.rb +1 -1
- data/lib/sequel/dataset/sequelizer.rb +6 -6
- data/lib/sequel/dataset/sql.rb +19 -13
- data/lib/sequel/migration.rb +2 -0
- data/lib/sequel/model.rb +3 -2
- data/lib/sequel/mysql.rb +5 -0
- data/lib/sequel/pretty_table.rb +9 -1
- data/spec/dataset_spec.rb +20 -8
- data/spec/migration_spec.rb +9 -1
- data/spec/model_spec.rb +11 -0
- data/spec/pretty_table_spec.rb +2 -2
- data/spec/sequelizer_spec.rb +11 -2
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
=== 0.2.0.2 (2007-09-07)
|
2
|
+
|
3
|
+
* Dataset#insert can now accept subqueries.
|
4
|
+
|
5
|
+
* Changed Migrator.apply to return the version.
|
6
|
+
|
7
|
+
* Changed Sequel::Model() to cache intermediate classes so descendant classes can be reopened (#39).
|
8
|
+
|
9
|
+
* Added :charset option to MySQL adapter (#40).
|
10
|
+
|
11
|
+
* Fixed Dataset#exclude to add parens around NOT expression (#38).
|
12
|
+
|
13
|
+
* Fixed use of sub-queries with all comparison operators in block filters (#38).
|
14
|
+
|
15
|
+
* Fixed arithmetic expressions in block filters to not be literalized.
|
16
|
+
|
17
|
+
* Changed Symbol#method_missing to return LiteralString.
|
18
|
+
|
19
|
+
* Changed PrettyTable to right-align numbers.
|
20
|
+
|
21
|
+
* Fixed Model.create_table (thanks Duane Johnson.)
|
22
|
+
|
1
23
|
=== 0.2.0.1 (2007-09-04)
|
2
24
|
|
3
25
|
* Improved support for invoking methods with inline procs inside block filters.
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
include FileUtils
|
7
7
|
|
8
8
|
NAME = "sequel"
|
9
|
-
VERS = "0.2.0.
|
9
|
+
VERS = "0.2.0.2"
|
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/core_ext.rb
CHANGED
@@ -134,7 +134,7 @@ class Symbol
|
|
134
134
|
# method name is made of all upper case letters.
|
135
135
|
def method_missing(sym)
|
136
136
|
((s = sym.to_s) =~ /^([A-Z]+)$/) ? \
|
137
|
-
"#{s.downcase}(#{to_field_name})" : super
|
137
|
+
"#{s.downcase}(#{to_field_name})".lit : super
|
138
138
|
end
|
139
139
|
|
140
140
|
# Formats an SQL function with optional parameters
|
@@ -106,9 +106,9 @@ class Sequel::Dataset
|
|
106
106
|
def call_expr(e, b)
|
107
107
|
case op = e[2]
|
108
108
|
when :>, :<, :>=, :<=
|
109
|
-
l =
|
110
|
-
r =
|
111
|
-
"(#{l} #{op} #{r})"
|
109
|
+
l = eval_expr(e[1], b)
|
110
|
+
r = eval_expr(e[3][1], b)
|
111
|
+
"(#{literal(l)} #{op} #{literal(r)})"
|
112
112
|
when :==
|
113
113
|
l = eval_expr(e[1], b)
|
114
114
|
r = eval_expr(e[3][1], b)
|
@@ -118,9 +118,9 @@ class Sequel::Dataset
|
|
118
118
|
r = eval_expr(e[3][1], b)
|
119
119
|
match_expr(l, r)
|
120
120
|
when :+, :-, :*, :/, :%
|
121
|
-
l =
|
122
|
-
r =
|
123
|
-
"(#{l} #{op} #{r})"
|
121
|
+
l = eval_expr(e[1], b)
|
122
|
+
r = eval_expr(e[3][1], b)
|
123
|
+
"(#{literal(l)} #{op} #{literal(r)})".lit
|
124
124
|
when :in, :in?
|
125
125
|
# in/in? operators are supported using two forms:
|
126
126
|
# :x.in([1, 2, 3])
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -249,9 +249,9 @@ module Sequel
|
|
249
249
|
if @opts[clause]
|
250
250
|
l = expression_list(@opts[clause])
|
251
251
|
r = expression_list(block || cond, parenthesize)
|
252
|
-
cond = "#{l} AND NOT #{r}"
|
252
|
+
cond = "#{l} AND (NOT #{r})"
|
253
253
|
else
|
254
|
-
cond = "NOT #{expression_list(block || cond, true)}"
|
254
|
+
cond = "(NOT #{expression_list(block || cond, true)})"
|
255
255
|
end
|
256
256
|
clone_merge(clause => cond)
|
257
257
|
end
|
@@ -420,18 +420,24 @@ module Sequel
|
|
420
420
|
def insert_sql(*values)
|
421
421
|
if values.empty?
|
422
422
|
"INSERT INTO #{@opts[:from]} DEFAULT VALUES;"
|
423
|
-
elsif (values.size == 1) && values[0].is_a?(Hash)
|
424
|
-
field_list = []
|
425
|
-
value_list = []
|
426
|
-
values[0].each do |k, v|
|
427
|
-
field_list << field_name(k)
|
428
|
-
value_list << literal(v)
|
429
|
-
end
|
430
|
-
fl = field_list.join(COMMA_SEPARATOR)
|
431
|
-
vl = value_list.join(COMMA_SEPARATOR)
|
432
|
-
"INSERT INTO #{@opts[:from]} (#{fl}) VALUES (#{vl});"
|
433
423
|
else
|
434
|
-
|
424
|
+
values = values[0] if values.size == 1
|
425
|
+
case values
|
426
|
+
when Hash
|
427
|
+
field_list = []
|
428
|
+
value_list = []
|
429
|
+
values.each do |k, v|
|
430
|
+
field_list << field_name(k)
|
431
|
+
value_list << literal(v)
|
432
|
+
end
|
433
|
+
fl = field_list.join(COMMA_SEPARATOR)
|
434
|
+
vl = value_list.join(COMMA_SEPARATOR)
|
435
|
+
"INSERT INTO #{@opts[:from]} (#{fl}) VALUES (#{vl});"
|
436
|
+
when Dataset
|
437
|
+
"INSERT INTO #{@opts[:from]} #{literal(values)}"
|
438
|
+
else
|
439
|
+
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)});"
|
440
|
+
end
|
435
441
|
end
|
436
442
|
end
|
437
443
|
|
data/lib/sequel/migration.rb
CHANGED
data/lib/sequel/model.rb
CHANGED
@@ -78,7 +78,7 @@ module Sequel
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def self.create_table
|
81
|
-
db.
|
81
|
+
db.create_table_sql_list(*schema.create_info).each {|s| db << s}
|
82
82
|
end
|
83
83
|
|
84
84
|
def self.drop_table
|
@@ -292,7 +292,8 @@ module Sequel
|
|
292
292
|
end
|
293
293
|
|
294
294
|
def self.Model(table)
|
295
|
-
|
295
|
+
@models ||= {}
|
296
|
+
@models[table] ||= Class.new(Sequel::Model) do
|
296
297
|
meta_def(:inherited) do |c|
|
297
298
|
if table.is_a?(Dataset)
|
298
299
|
c.set_dataset(table)
|
data/lib/sequel/mysql.rb
CHANGED
@@ -69,6 +69,11 @@ module Sequel
|
|
69
69
|
conn = Mysql.real_connect(@opts[:host], @opts[:user], @opts[:password],
|
70
70
|
@opts[:database], @opts[:port])
|
71
71
|
conn.query_with_result = false
|
72
|
+
if @opts[:charset]
|
73
|
+
conn.query("set character_set_connection = '#{@opts[:charset]}';")
|
74
|
+
conn.query("set character_set_client = '#{@opts[:charset]}';")
|
75
|
+
conn.query("set character_set_results = '#{@opts[:charset]}';")
|
76
|
+
end
|
72
77
|
conn.reconnect = true
|
73
78
|
conn
|
74
79
|
end
|
data/lib/sequel/pretty_table.rb
CHANGED
@@ -36,8 +36,16 @@ module Sequel
|
|
36
36
|
'+' + columns.map {|c| '-' * sizes[c]}.join('+') + '+'
|
37
37
|
end
|
38
38
|
|
39
|
+
def self.format_cell(size, v)
|
40
|
+
case v
|
41
|
+
when Bignum, Fixnum: "%#{size}d" % v
|
42
|
+
when Float: "%#{size}g" % v
|
43
|
+
else "%-#{size}s" % v.to_s
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
def self.data_line(columns, sizes, record)
|
40
|
-
'|' + columns.map {|c|
|
48
|
+
'|' + columns.map {|c| format_cell(sizes[c], record[c])}.join('|') + '|'
|
41
49
|
end
|
42
50
|
|
43
51
|
def self.header_line(columns, sizes)
|
data/spec/dataset_spec.rb
CHANGED
@@ -98,10 +98,22 @@ context "A simple dataset" do
|
|
98
98
|
@dataset.delete_sql.should == 'DELETE FROM test'
|
99
99
|
end
|
100
100
|
|
101
|
-
specify "should format an insert statement" do
|
101
|
+
specify "should format an insert statement with default values" do
|
102
102
|
@dataset.insert_sql.should == 'INSERT INTO test DEFAULT VALUES;'
|
103
|
+
end
|
104
|
+
|
105
|
+
specify "should format an insert statement with hash" do
|
103
106
|
@dataset.insert_sql(:name => 'wxyz', :price => 342).
|
104
107
|
should match(/INSERT INTO test \(name, price\) VALUES \('wxyz', 342\)|INSERT INTO test \(price, name\) VALUES \(342, 'wxyz'\)/)
|
108
|
+
end
|
109
|
+
|
110
|
+
specify "should format an insert statement with sub-query" do
|
111
|
+
@sub = Sequel::Dataset.new(nil).from(:something).filter(:x => 2)
|
112
|
+
@dataset.insert_sql(@sub).should == \
|
113
|
+
"INSERT INTO test (SELECT * FROM something WHERE (x = 2))"
|
114
|
+
end
|
115
|
+
|
116
|
+
specify "should format an insert statement with array" do
|
105
117
|
@dataset.insert_sql('a', 2, 6.5).should ==
|
106
118
|
"INSERT INTO test VALUES ('a', 2, 6.5);"
|
107
119
|
end
|
@@ -361,33 +373,33 @@ context "Dataset#exclude" do
|
|
361
373
|
|
362
374
|
specify "should correctly include the NOT operator when one condition is given" do
|
363
375
|
@dataset.exclude(:region=>'Asia').select_sql.should ==
|
364
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia')"
|
376
|
+
"SELECT * FROM test WHERE (NOT (region = 'Asia'))"
|
365
377
|
end
|
366
378
|
|
367
379
|
specify "should take multiple conditions as a hash and express the logic correctly in SQL" do
|
368
380
|
@dataset.exclude(:region => 'Asia', :name => 'Japan').select_sql.
|
369
|
-
should match(Regexp.union(/WHERE NOT \(\(region = 'Asia'\) AND \(name = 'Japan'\)\)/,
|
370
|
-
/WHERE NOT \(\(name = 'Japan'\) AND \(region = 'Asia'\)\)/))
|
381
|
+
should match(Regexp.union(/WHERE \(NOT \(\(region = 'Asia'\) AND \(name = 'Japan'\)\)\)/,
|
382
|
+
/WHERE \(NOT \(\(name = 'Japan'\) AND \(region = 'Asia'\)\)\)/))
|
371
383
|
end
|
372
384
|
|
373
385
|
specify "should parenthesize a single string condition correctly" do
|
374
386
|
@dataset.exclude("region = 'Asia' AND name = 'Japan'").select_sql.should ==
|
375
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
387
|
+
"SELECT * FROM test WHERE (NOT (region = 'Asia' AND name = 'Japan'))"
|
376
388
|
end
|
377
389
|
|
378
390
|
specify "should parenthesize an array condition correctly" do
|
379
391
|
@dataset.exclude('region = ? AND name = ?', 'Asia', 'Japan').select_sql.should ==
|
380
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
392
|
+
"SELECT * FROM test WHERE (NOT (region = 'Asia' AND name = 'Japan'))"
|
381
393
|
end
|
382
394
|
|
383
395
|
specify "should corrently parenthesize when it is used twice" do
|
384
396
|
@dataset.exclude(:region => 'Asia').exclude(:name => 'Japan').select_sql.should ==
|
385
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia') AND NOT (name = 'Japan')"
|
397
|
+
"SELECT * FROM test WHERE (NOT (region = 'Asia')) AND (NOT (name = 'Japan'))"
|
386
398
|
end
|
387
399
|
|
388
400
|
specify "should support proc expressions" do
|
389
401
|
@dataset.exclude {:id == (6...12)}.sql.should ==
|
390
|
-
'SELECT * FROM test WHERE NOT ((id >= 6 AND id < 12))'
|
402
|
+
'SELECT * FROM test WHERE (NOT ((id >= 6 AND id < 12)))'
|
391
403
|
end
|
392
404
|
end
|
393
405
|
|
data/spec/migration_spec.rb
CHANGED
@@ -229,7 +229,7 @@ context "Sequel::Migrator" do
|
|
229
229
|
|
230
230
|
Sequel::Migrator.get_current_migration_version(@db).should == 5
|
231
231
|
end
|
232
|
-
|
232
|
+
|
233
233
|
specify "should apply migrations correctly in the down direction" do
|
234
234
|
Sequel::Migrator.apply(@db, '.', 1, 5)
|
235
235
|
@db.drops.should == [5555, 3333, 2222]
|
@@ -250,4 +250,12 @@ context "Sequel::Migrator" do
|
|
250
250
|
|
251
251
|
Sequel::Migrator.get_current_migration_version(@db).should == 0
|
252
252
|
end
|
253
|
+
|
254
|
+
specify "should return the target version" do
|
255
|
+
Sequel::Migrator.apply(@db, '.', 3, 2).should == 3
|
256
|
+
|
257
|
+
Sequel::Migrator.apply(@db, '.', 0).should == 0
|
258
|
+
|
259
|
+
Sequel::Migrator.apply(@db, '.').should == 5
|
260
|
+
end
|
253
261
|
end
|
data/spec/model_spec.rb
CHANGED
@@ -44,4 +44,15 @@ describe Sequel::Model do
|
|
44
44
|
it "puts the lotion in the basket or it gets the hose again" do
|
45
45
|
# just kidding!
|
46
46
|
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class DummyModelBased < Sequel::Model(:blog)
|
50
|
+
end
|
51
|
+
|
52
|
+
context "Sequel::Model()" do
|
53
|
+
specify "should allow reopening of descendant classes" do
|
54
|
+
proc do
|
55
|
+
eval "class DummyModelBased < Sequel::Model(:blog); end"
|
56
|
+
end.should_not raise_error
|
57
|
+
end
|
47
58
|
end
|
data/spec/pretty_table_spec.rb
CHANGED
@@ -39,14 +39,14 @@ context "PrettyTable" do
|
|
39
39
|
Sequel::PrettyTable.print(@data2, [:a, :b])
|
40
40
|
@output.rewind
|
41
41
|
@output.read.should == \
|
42
|
-
"+--+----+\n|a |b |\n+--+----+\n|23|45
|
42
|
+
"+--+----+\n|a |b |\n+--+----+\n|23| 45|\n|45|2377|\n+--+----+\n"
|
43
43
|
end
|
44
44
|
|
45
45
|
specify "should also take header width into account" do
|
46
46
|
Sequel::PrettyTable.print(@data3, [:aaa, :bb, :c])
|
47
47
|
@output.rewind
|
48
48
|
@output.read.should == \
|
49
|
-
"+---+--+-+\n|aaa|bb|c|\n+---+--+-+\n|1
|
49
|
+
"+---+--+-+\n|aaa|bb|c|\n+---+--+-+\n| 1| | |\n| | 2| |\n| | |3|\n+---+--+-+\n"
|
50
50
|
end
|
51
51
|
|
52
52
|
specify "should print only the specified columns" do
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -175,6 +175,12 @@ context "Proc#to_sql" do
|
|
175
175
|
|
176
176
|
proc {:x == (a...b)}.to_sql.should == \
|
177
177
|
"(x >= 3 AND x < 5)"
|
178
|
+
|
179
|
+
t1 = Time.now - 4000
|
180
|
+
t2 = Time.now - 2000
|
181
|
+
|
182
|
+
proc {:stamp == (t1..t2)}.to_sql.should == \
|
183
|
+
"(stamp >= #{DS.literal(t1)} AND stamp <= #{DS.literal(t2)})"
|
178
184
|
end
|
179
185
|
|
180
186
|
specify "should support comparison to sub-queries" do
|
@@ -186,8 +192,11 @@ context "Proc#to_sql" do
|
|
186
192
|
# proc {:id == DB[:test].select(:node_id)}.to_sql.should == \
|
187
193
|
# "(id IN (SELECT node_id FROM test))"
|
188
194
|
|
189
|
-
proc {:id == DB[:test].select(:node_id).filter {:active == true}}.to_sql.should == \
|
190
|
-
"(id IN (SELECT node_id FROM test WHERE (active = 't')))"
|
195
|
+
# proc {:id == DB[:test].select(:node_id).filter {:active == true}}.to_sql.should == \
|
196
|
+
# "(id IN (SELECT node_id FROM test WHERE (active = 't')))"
|
197
|
+
|
198
|
+
proc {:price >= DB[:items].select(:price)}.to_sql.should == \
|
199
|
+
"(price >= (SELECT price FROM items))"
|
191
200
|
end
|
192
201
|
|
193
202
|
specify "should support comparison to arrays" do
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: sequel
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.0.
|
7
|
-
date: 2007-09-
|
6
|
+
version: 0.2.0.2
|
7
|
+
date: 2007-09-07 00:00:00 +03:00
|
8
8
|
summary: Lightweight ORM library for Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|