sequel_core 1.0.3 → 1.0.4
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 +18 -0
- data/Rakefile +6 -6
- data/lib/sequel_core/adapters/mysql.rb +93 -1
- data/lib/sequel_core/adapters/odbc.rb +49 -5
- data/lib/sequel_core/core_ext.rb +1 -0
- data/lib/sequel_core/database.rb +2 -1
- data/lib/sequel_core/dataset/convenience.rb +21 -2
- data/lib/sequel_core/dataset/sql.rb +5 -0
- data/lib/sequel_core/schema/schema_sql.rb +2 -2
- data/spec/adapters/mysql_spec.rb +23 -0
- data/spec/database_spec.rb +1 -3
- data/spec/dataset_spec.rb +83 -5
- metadata +2 -2
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
=== 1.0.4 (2008-01-24)
|
|
2
|
+
|
|
3
|
+
* Added Dataset#select_all method.
|
|
4
|
+
|
|
5
|
+
* Changed ODBC::Database to support connection using driver and database name, also added support for untitled columns in ODBC::Dataset (thanks Leonid Borisenko).
|
|
6
|
+
|
|
7
|
+
* Fixed MySQL adapter to correctly format foreign key definitions (#123).
|
|
8
|
+
|
|
9
|
+
* Changed MySQL::Dataset to allow HAVING clause on ungrouped datasets, and put HAVING clause before ORDER BY clause (#133).
|
|
10
|
+
|
|
11
|
+
* Changed Dataset#group_and_count to accept multiple columns (#134).
|
|
12
|
+
|
|
13
|
+
* Fixed database spec to open YAML file in binary mode (#131).
|
|
14
|
+
|
|
15
|
+
* Cleaned up gem spec (#132).
|
|
16
|
+
|
|
17
|
+
* Added Dataset#table_exists? convenience method.
|
|
18
|
+
|
|
1
19
|
=== 1.0.3 (2008-01-17)
|
|
2
20
|
|
|
3
21
|
* Added support for UNSIGNED constraint, used in MySQL? (#127).
|
data/Rakefile
CHANGED
|
@@ -9,7 +9,7 @@ include FileUtils
|
|
|
9
9
|
# Configuration
|
|
10
10
|
##############################################################################
|
|
11
11
|
NAME = "sequel_core"
|
|
12
|
-
VERS = "1.0.
|
|
12
|
+
VERS = "1.0.4"
|
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
|
14
14
|
RDOC_OPTS = [
|
|
15
15
|
"--quiet",
|
|
@@ -61,11 +61,6 @@ spec = Gem::Specification.new do |s|
|
|
|
61
61
|
s.add_dependency("assistance", ">= 0.1")
|
|
62
62
|
|
|
63
63
|
case RUBY_PLATFORM
|
|
64
|
-
when /mswin/
|
|
65
|
-
s.platform = Gem::Platform::CURRENT
|
|
66
|
-
s.add_dependency("RubyInline", ">= 3.6.6")
|
|
67
|
-
s.add_dependency("ParseTree", ">= 2.1.1")
|
|
68
|
-
s.add_dependency("ruby2ruby")
|
|
69
64
|
when /java/
|
|
70
65
|
s.platform = "jruby"
|
|
71
66
|
else
|
|
@@ -162,6 +157,11 @@ Spec::Rake::SpecTask.new("rcov") do |t|
|
|
|
162
157
|
t.rcov = true
|
|
163
158
|
end
|
|
164
159
|
|
|
160
|
+
desc "check documentation coverage"
|
|
161
|
+
task :dcov do
|
|
162
|
+
sh "find lib -name '*.rb' | xargs dcov"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
165
|
##############################################################################
|
|
166
166
|
# Statistics
|
|
167
167
|
##############################################################################
|
|
@@ -41,7 +41,7 @@ class Mysql::Result
|
|
|
41
41
|
@column_types = []
|
|
42
42
|
@columns = fetch_fields.map do |f|
|
|
43
43
|
@column_types << f.type
|
|
44
|
-
(with_table ?
|
|
44
|
+
(with_table ? "#{f.table}.#{f.name}" : f.name).to_sym
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
@columns
|
|
@@ -162,6 +162,28 @@ module Sequel
|
|
|
162
162
|
super(table, op)
|
|
163
163
|
end
|
|
164
164
|
end
|
|
165
|
+
|
|
166
|
+
def column_definition_sql(column)
|
|
167
|
+
if column[:type] == :check
|
|
168
|
+
return constraint_definition_sql(column)
|
|
169
|
+
end
|
|
170
|
+
sql = "#{literal(column[:name].to_sym)} #{TYPES[column[:type]]}"
|
|
171
|
+
column[:size] ||= 255 if column[:type] == :varchar
|
|
172
|
+
elements = column[:size] || column[:elements]
|
|
173
|
+
sql << "(#{literal(elements)})" if elements
|
|
174
|
+
sql << UNIQUE if column[:unique]
|
|
175
|
+
sql << NOT_NULL if column[:null] == false
|
|
176
|
+
sql << UNSIGNED if column[:unsigned]
|
|
177
|
+
sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
|
|
178
|
+
sql << PRIMARY_KEY if column[:primary_key]
|
|
179
|
+
sql << " #{auto_increment_sql}" if column[:auto_increment]
|
|
180
|
+
if column[:table]
|
|
181
|
+
sql << ", FOREIGN KEY (#{literal(column[:name].to_sym)}) REFERENCES #{column[:table]}"
|
|
182
|
+
sql << "(#{literal(column[:key])})" if column[:key]
|
|
183
|
+
sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
|
|
184
|
+
end
|
|
185
|
+
sql
|
|
186
|
+
end
|
|
165
187
|
|
|
166
188
|
def transaction
|
|
167
189
|
@pool.hold do |conn|
|
|
@@ -217,6 +239,76 @@ module Sequel
|
|
|
217
239
|
end
|
|
218
240
|
end
|
|
219
241
|
|
|
242
|
+
# MySQL expects the having clause before the order by clause.
|
|
243
|
+
def select_sql(opts = nil)
|
|
244
|
+
opts = opts ? @opts.merge(opts) : @opts
|
|
245
|
+
|
|
246
|
+
if sql = opts[:sql]
|
|
247
|
+
return sql
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
columns = opts[:select]
|
|
251
|
+
select_columns = columns ? column_list(columns) : WILDCARD
|
|
252
|
+
|
|
253
|
+
if distinct = opts[:distinct]
|
|
254
|
+
distinct_clause = distinct.empty? ? "DISTINCT" : "DISTINCT ON (#{column_list(distinct)})"
|
|
255
|
+
sql = "SELECT #{distinct_clause} #{select_columns}"
|
|
256
|
+
else
|
|
257
|
+
sql = "SELECT #{select_columns}"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if opts[:from]
|
|
261
|
+
sql << " FROM #{source_list(opts[:from])}"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
if join = opts[:join]
|
|
265
|
+
sql << join
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
if where = opts[:where]
|
|
269
|
+
sql << " WHERE #{where}"
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
if group = opts[:group]
|
|
273
|
+
sql << " GROUP BY #{column_list(group)}"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
if having = opts[:having]
|
|
277
|
+
sql << " HAVING #{having}"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
if order = opts[:order]
|
|
281
|
+
sql << " ORDER BY #{column_list(order)}"
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if limit = opts[:limit]
|
|
285
|
+
sql << " LIMIT #{limit}"
|
|
286
|
+
if offset = opts[:offset]
|
|
287
|
+
sql << " OFFSET #{offset}"
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
if union = opts[:union]
|
|
292
|
+
sql << (opts[:union_all] ? \
|
|
293
|
+
" UNION ALL #{union.sql}" : " UNION #{union.sql}")
|
|
294
|
+
elsif intersect = opts[:intersect]
|
|
295
|
+
sql << (opts[:intersect_all] ? \
|
|
296
|
+
" INTERSECT ALL #{intersect.sql}" : " INTERSECT #{intersect.sql}")
|
|
297
|
+
elsif except = opts[:except]
|
|
298
|
+
sql << (opts[:except_all] ? \
|
|
299
|
+
" EXCEPT ALL #{except.sql}" : " EXCEPT #{except.sql}")
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
sql
|
|
303
|
+
end
|
|
304
|
+
alias_method :sql, :select_sql
|
|
305
|
+
|
|
306
|
+
# MySQL allows HAVING clause on ungrouped datasets.
|
|
307
|
+
def having(*cond, &block)
|
|
308
|
+
@opts[:having] = {}
|
|
309
|
+
filter(*cond, &block)
|
|
310
|
+
end
|
|
311
|
+
|
|
220
312
|
# MySQL supports ORDER and LIMIT clauses in UPDATE statements.
|
|
221
313
|
def update_sql(values, opts = nil)
|
|
222
314
|
sql = super
|
|
@@ -5,12 +5,34 @@ module Sequel
|
|
|
5
5
|
class Database < Sequel::Database
|
|
6
6
|
set_adapter_scheme :odbc
|
|
7
7
|
|
|
8
|
+
# def connect
|
|
9
|
+
# conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
|
|
10
|
+
# conn.autocommit = true
|
|
11
|
+
# conn
|
|
12
|
+
# end
|
|
13
|
+
|
|
14
|
+
GUARDED_DRV_NAME = /^\{.+\}$/.freeze
|
|
15
|
+
DRV_NAME_GUARDS = '{%s}'.freeze
|
|
16
|
+
|
|
8
17
|
def connect
|
|
9
|
-
|
|
18
|
+
if @opts.include? :driver
|
|
19
|
+
drv = ::ODBC::Driver.new
|
|
20
|
+
drv.name = 'Sequel ODBC Driver130'
|
|
21
|
+
@opts.each do |param, value|
|
|
22
|
+
if :driver == param and not (value =~ GUARDED_DRV_NAME)
|
|
23
|
+
value = DRV_NAME_GUARDS % value
|
|
24
|
+
end
|
|
25
|
+
drv.attrs[param.to_s.capitalize] = value
|
|
26
|
+
end
|
|
27
|
+
db = ::ODBC::Database.new
|
|
28
|
+
conn = db.drvconnect(drv)
|
|
29
|
+
else
|
|
30
|
+
conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
|
|
31
|
+
end
|
|
10
32
|
conn.autocommit = true
|
|
11
33
|
conn
|
|
12
|
-
end
|
|
13
|
-
|
|
34
|
+
end
|
|
35
|
+
|
|
14
36
|
def disconnect
|
|
15
37
|
@pool.disconnect {|c| c.disconnect}
|
|
16
38
|
end
|
|
@@ -49,19 +71,41 @@ module Sequel
|
|
|
49
71
|
end
|
|
50
72
|
end
|
|
51
73
|
|
|
74
|
+
UNTITLED_COLUMN = 'untitled_%d'.freeze
|
|
75
|
+
|
|
52
76
|
def fetch_rows(sql, &block)
|
|
53
77
|
@db.synchronize do
|
|
54
78
|
s = @db.execute sql
|
|
55
79
|
begin
|
|
56
|
-
|
|
80
|
+
untitled_count = 0
|
|
81
|
+
@columns = s.columns(true).map do |c|
|
|
82
|
+
if (n = c.name).empty?
|
|
83
|
+
n = UNTITLED_COLUMN % (untitled_count += 1)
|
|
84
|
+
end
|
|
85
|
+
n.to_sym
|
|
86
|
+
end
|
|
57
87
|
rows = s.fetch_all
|
|
58
|
-
rows.each {|row| yield hash_row(row)}
|
|
88
|
+
rows.each {|row| yield hash_row(row)} if rows
|
|
59
89
|
ensure
|
|
60
90
|
s.drop unless s.nil? rescue nil
|
|
61
91
|
end
|
|
62
92
|
end
|
|
63
93
|
self
|
|
64
94
|
end
|
|
95
|
+
|
|
96
|
+
# def fetch_rows(sql, &block)
|
|
97
|
+
# @db.synchronize do
|
|
98
|
+
# s = @db.execute sql
|
|
99
|
+
# begin
|
|
100
|
+
# @columns = s.columns(true).map {|c| c.name.to_sym}
|
|
101
|
+
# rows = s.fetch_all
|
|
102
|
+
# rows.each {|row| yield hash_row(row)}
|
|
103
|
+
# ensure
|
|
104
|
+
# s.drop unless s.nil? rescue nil
|
|
105
|
+
# end
|
|
106
|
+
# end
|
|
107
|
+
# self
|
|
108
|
+
# end
|
|
65
109
|
|
|
66
110
|
def hash_row(row)
|
|
67
111
|
hash = {}
|
data/lib/sequel_core/core_ext.rb
CHANGED
data/lib/sequel_core/database.rb
CHANGED
|
@@ -176,9 +176,11 @@ module Sequel
|
|
|
176
176
|
single_value(:select => [column.AVG.AS(:v)])
|
|
177
177
|
end
|
|
178
178
|
|
|
179
|
+
COUNT_OF_ALL_AS_COUNT = :count['*'.lit].AS(:count)
|
|
180
|
+
|
|
179
181
|
# Returns a dataset grouped by the given column with count by group.
|
|
180
|
-
def group_and_count(
|
|
181
|
-
group(
|
|
182
|
+
def group_and_count(*columns)
|
|
183
|
+
group(*columns).select(columns + [COUNT_OF_ALL_AS_COUNT]).order(:count)
|
|
182
184
|
end
|
|
183
185
|
|
|
184
186
|
# Returns a Range object made from the minimum and maximum values for the
|
|
@@ -316,6 +318,23 @@ module Sequel
|
|
|
316
318
|
def create_or_replace_view(name)
|
|
317
319
|
@db.create_or_replace_view(name, self)
|
|
318
320
|
end
|
|
321
|
+
|
|
322
|
+
def table_exists?
|
|
323
|
+
if @opts[:sql]
|
|
324
|
+
raise Sequel::Error, "this dataset has fixed SQL"
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
if @opts[:from].size != 1
|
|
328
|
+
raise Sequel::Error, "this dataset selects from multiple sources"
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
t = @opts[:from].first
|
|
332
|
+
if t.is_a?(Dataset)
|
|
333
|
+
raise Sequel::Error, "this dataset selects from a sub query"
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
@db.table_exists?(t.to_sym)
|
|
337
|
+
end
|
|
319
338
|
end
|
|
320
339
|
end
|
|
321
340
|
end
|
|
@@ -156,6 +156,11 @@ module Sequel
|
|
|
156
156
|
def select(*columns)
|
|
157
157
|
clone_merge(:select => columns)
|
|
158
158
|
end
|
|
159
|
+
|
|
160
|
+
# Returns a copy of the dataset selecting the wildcard.
|
|
161
|
+
def select_all
|
|
162
|
+
clone_merge(:select => nil)
|
|
163
|
+
end
|
|
159
164
|
|
|
160
165
|
# Returns a copy of the dataset with the distinct option.
|
|
161
166
|
def uniq(*args)
|
|
@@ -62,12 +62,12 @@ module Sequel
|
|
|
62
62
|
sql << UNSIGNED if column[:unsigned]
|
|
63
63
|
sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
|
|
64
64
|
sql << PRIMARY_KEY if column[:primary_key]
|
|
65
|
+
sql << " #{auto_increment_sql}" if column[:auto_increment]
|
|
65
66
|
if column[:table]
|
|
66
67
|
sql << " REFERENCES #{column[:table]}"
|
|
67
68
|
sql << "(#{column[:key]})" if column[:key]
|
|
69
|
+
sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
|
|
68
70
|
end
|
|
69
|
-
sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
|
|
70
|
-
sql << " #{auto_increment_sql}" if column[:auto_increment]
|
|
71
71
|
sql
|
|
72
72
|
end
|
|
73
73
|
|
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -267,12 +267,25 @@ end
|
|
|
267
267
|
context "Joiמed MySQL dataset" do
|
|
268
268
|
setup do
|
|
269
269
|
@ds = MYSQL_DB[:nodes].join(:attributes, :node_id => :id)
|
|
270
|
+
@ds2 = MYSQL_DB[:nodes]
|
|
270
271
|
end
|
|
271
272
|
|
|
272
273
|
specify "should quote fields correctly" do
|
|
273
274
|
@ds.sql.should == \
|
|
274
275
|
"SELECT * FROM nodes INNER JOIN attributes ON (attributes.`node_id` = nodes.`id`)"
|
|
275
276
|
end
|
|
277
|
+
|
|
278
|
+
specify "should allow a having clause on ungrouped datasets" do
|
|
279
|
+
proc {@ds2.having('blah')}.should_not raise_error
|
|
280
|
+
|
|
281
|
+
@ds2.having('blah').sql.should == \
|
|
282
|
+
"SELECT * FROM nodes HAVING blah"
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
specify "should put a having clause before an order by clause" do
|
|
286
|
+
@ds2.order(:aaa).having(:bbb => :ccc).sql.should == \
|
|
287
|
+
"SELECT * FROM nodes HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
|
|
288
|
+
end
|
|
276
289
|
end
|
|
277
290
|
|
|
278
291
|
context "A MySQL database" do
|
|
@@ -339,6 +352,16 @@ context "A MySQL database" do
|
|
|
339
352
|
"CREATE TABLE items (`active1` boolean DEFAULT 1, `active2` boolean DEFAULT 0)"
|
|
340
353
|
]
|
|
341
354
|
end
|
|
355
|
+
|
|
356
|
+
specify "should correctly format CREATE TABLE statements with foreign keys" do
|
|
357
|
+
g = Sequel::Schema::Generator.new(@db) do
|
|
358
|
+
foreign_key :p_id, :table => :users, :key => :id,
|
|
359
|
+
:null => false, :on_delete => :cascade
|
|
360
|
+
end
|
|
361
|
+
@db.create_table_sql_list(:items, *g.create_info).should == [
|
|
362
|
+
"CREATE TABLE items (`p_id` integer NOT NULL, FOREIGN KEY (`p_id`) REFERENCES users(`id`) ON DELETE CASCADE)"
|
|
363
|
+
]
|
|
364
|
+
end
|
|
342
365
|
end
|
|
343
366
|
|
|
344
367
|
context "A MySQL database" do
|
data/spec/database_spec.rb
CHANGED
|
@@ -400,7 +400,6 @@ context "Database#table_exists?" do
|
|
|
400
400
|
@db = DummyDatabase.new
|
|
401
401
|
@db.stub!(:tables).and_return([:a, :b])
|
|
402
402
|
@db2 = DummyDatabase.new
|
|
403
|
-
Sequel::Dataset.stub!(:first).and_return(nil)
|
|
404
403
|
end
|
|
405
404
|
|
|
406
405
|
specify "should use Database#tables if available" do
|
|
@@ -415,7 +414,6 @@ context "Database#table_exists?" do
|
|
|
415
414
|
end
|
|
416
415
|
end
|
|
417
416
|
|
|
418
|
-
|
|
419
417
|
class Dummy3Database < Sequel::Database
|
|
420
418
|
attr_reader :sql, :transactions
|
|
421
419
|
def execute(sql); @sql ||= []; @sql << sql; end
|
|
@@ -820,7 +818,7 @@ context "Database.connect" do
|
|
|
820
818
|
end
|
|
821
819
|
|
|
822
820
|
@fn = File.join(File.dirname(__FILE__), 'eee.yaml')
|
|
823
|
-
File.open(@fn, '
|
|
821
|
+
File.open(@fn, 'wb') {|f| f << EEE_YAML}
|
|
824
822
|
end
|
|
825
823
|
|
|
826
824
|
teardown do
|
data/spec/dataset_spec.rb
CHANGED
|
@@ -364,6 +364,11 @@ context "Dataset#where" do
|
|
|
364
364
|
proc {@dataset.filter(:a == 1)}.should raise_error(Sequel::Error::InvalidFilter)
|
|
365
365
|
proc {@dataset.filter(:a != 1)}.should raise_error(Sequel::Error::InvalidFilter)
|
|
366
366
|
end
|
|
367
|
+
|
|
368
|
+
specify "should work for grouped datasets" do
|
|
369
|
+
@dataset.group(:a).filter(:b => 1).sql.should ==
|
|
370
|
+
'SELECT * FROM test WHERE (b = 1) GROUP BY a'
|
|
371
|
+
end
|
|
367
372
|
end
|
|
368
373
|
|
|
369
374
|
context "Dataset#or" do
|
|
@@ -684,8 +689,8 @@ context "Dataset#select" do
|
|
|
684
689
|
end
|
|
685
690
|
|
|
686
691
|
specify "should overrun the previous select option" do
|
|
687
|
-
@d.select(:a, :b, :c).select.sql.should == 'SELECT * FROM test'
|
|
688
|
-
@d.select(:price).select(:name).sql.should == 'SELECT name FROM test'
|
|
692
|
+
@d.select!(:a, :b, :c).select.sql.should == 'SELECT * FROM test'
|
|
693
|
+
@d.select!(:price).select(:name).sql.should == 'SELECT name FROM test'
|
|
689
694
|
end
|
|
690
695
|
|
|
691
696
|
specify "should accept arbitrary objects and literalize them correctly" do
|
|
@@ -697,6 +702,21 @@ context "Dataset#select" do
|
|
|
697
702
|
end
|
|
698
703
|
end
|
|
699
704
|
|
|
705
|
+
context "Dataset#select_all" do
|
|
706
|
+
setup do
|
|
707
|
+
@d = Sequel::Dataset.new(nil).from(:test)
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
specify "should select the wildcard" do
|
|
711
|
+
@d.select_all.sql.should == 'SELECT * FROM test'
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
specify "should overrun the previous select option" do
|
|
715
|
+
@d.select!(:a, :b, :c).select_all.sql.should == 'SELECT * FROM test'
|
|
716
|
+
end
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
|
|
700
720
|
context "Dataset#order" do
|
|
701
721
|
setup do
|
|
702
722
|
@dataset = Sequel::Dataset.new(nil).from(:test)
|
|
@@ -953,9 +973,14 @@ context "Dataset#group_and_count" do
|
|
|
953
973
|
end
|
|
954
974
|
|
|
955
975
|
specify "should format SQL properly" do
|
|
956
|
-
@ds.group_and_count(:name).sql.should == "SELECT name, count(
|
|
976
|
+
@ds.group_and_count(:name).sql.should == "SELECT name, count(*) AS count FROM test GROUP BY name ORDER BY count"
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
specify "should accept multiple columns for grouping" do
|
|
980
|
+
@ds.group_and_count(:a, :b).sql.should == "SELECT a, b, count(*) AS count FROM test GROUP BY a, b ORDER BY count"
|
|
957
981
|
end
|
|
958
982
|
end
|
|
983
|
+
|
|
959
984
|
context "Dataset#empty?" do
|
|
960
985
|
specify "should return true if #count == 0" do
|
|
961
986
|
@c = Class.new(Sequel::Dataset) do
|
|
@@ -2297,7 +2322,7 @@ context "Dataset magic methods" do
|
|
|
2297
2322
|
proc {@ds.count_by_name}.should_not raise_error
|
|
2298
2323
|
@ds.should respond_to(:count_by_name)
|
|
2299
2324
|
@ds.count_by_name.should be_a_kind_of(@c)
|
|
2300
|
-
@ds.count_by_name.sql.should == "SELECT name, count(
|
|
2325
|
+
@ds.count_by_name.sql.should == "SELECT name, count(*) AS count FROM items GROUP BY name ORDER BY count"
|
|
2301
2326
|
end
|
|
2302
2327
|
|
|
2303
2328
|
specify "should support filter_by_xxx" do
|
|
@@ -2399,5 +2424,58 @@ context "Dataset#update_sql" do
|
|
|
2399
2424
|
specify "should accept array subscript references" do
|
|
2400
2425
|
@ds.update_sql((:day|1) => 'd').should == "UPDATE items SET day[1] = 'd'"
|
|
2401
2426
|
end
|
|
2427
|
+
end
|
|
2428
|
+
|
|
2429
|
+
class DummyMummyDataset < Sequel::Dataset
|
|
2430
|
+
def first
|
|
2431
|
+
raise if @opts[:from] == [:a]
|
|
2432
|
+
true
|
|
2433
|
+
end
|
|
2434
|
+
end
|
|
2435
|
+
|
|
2436
|
+
class DummyMummyDatabase < Sequel::Database
|
|
2437
|
+
attr_reader :sqls
|
|
2438
|
+
|
|
2439
|
+
def execute(sql)
|
|
2440
|
+
@sqls ||= []
|
|
2441
|
+
@sqls << sql
|
|
2442
|
+
end
|
|
2443
|
+
|
|
2444
|
+
def transaction; yield; end
|
|
2445
|
+
|
|
2446
|
+
def dataset
|
|
2447
|
+
DummyMummyDataset.new(self)
|
|
2448
|
+
end
|
|
2449
|
+
end
|
|
2450
|
+
|
|
2451
|
+
context "Dataset#table_exists?" do
|
|
2452
|
+
setup do
|
|
2453
|
+
@db = DummyMummyDatabase.new
|
|
2454
|
+
@db.stub!(:tables).and_return([:a, :b])
|
|
2455
|
+
@db2 = DummyMummyDatabase.new
|
|
2456
|
+
end
|
|
2457
|
+
|
|
2458
|
+
specify "should use Database#tables if available" do
|
|
2459
|
+
@db[:a].table_exists?.should be_true
|
|
2460
|
+
@db[:b].table_exists?.should be_true
|
|
2461
|
+
@db[:c].table_exists?.should be_false
|
|
2462
|
+
end
|
|
2463
|
+
|
|
2464
|
+
specify "should otherwise try to select the first record from the table's dataset" do
|
|
2465
|
+
@db2[:a].table_exists?.should be_false
|
|
2466
|
+
@db2[:b].table_exists?.should be_true
|
|
2467
|
+
end
|
|
2468
|
+
|
|
2469
|
+
specify "should raise Sequel::Error if dataset references more than one table" do
|
|
2470
|
+
proc {@db.from(:a, :b).table_exists?}.should raise_error(Sequel::Error)
|
|
2471
|
+
end
|
|
2472
|
+
|
|
2473
|
+
specify "should raise Sequel::Error if dataset is from a subquery" do
|
|
2474
|
+
proc {@db.from(@db[:a]).table_exists?}.should raise_error(Sequel::Error)
|
|
2475
|
+
end
|
|
2476
|
+
|
|
2477
|
+
specify "should raise Sequel::Error if dataset has fixed sql" do
|
|
2478
|
+
proc {@db['select * from blah'].table_exists?}.should raise_error(Sequel::Error)
|
|
2479
|
+
end
|
|
2480
|
+
end
|
|
2402
2481
|
|
|
2403
|
-
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sequel_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.4
|
|
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: 2008-01-
|
|
12
|
+
date: 2008-01-24 00:00:00 +02:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|