sequel 0.4.2 → 0.4.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/Rakefile +1 -1
- data/lib/sequel/adapters/odbc_mssql.rb +0 -1
- data/lib/sequel/core_sql.rb +1 -0
- data/lib/sequel/database.rb +14 -0
- data/lib/sequel/dataset/convenience.rb +8 -0
- data/lib/sequel/dataset/sequelizer.rb +2 -2
- data/lib/sequel/dataset/sql.rb +9 -16
- data/lib/sequel/model.rb +4 -0
- data/lib/sequel/model/record.rb +2 -5
- data/spec/adapters/mysql_spec.rb +17 -3
- data/spec/database_spec.rb +46 -1
- data/spec/dataset_spec.rb +45 -2
- data/spec/model_spec.rb +11 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 0.4.2.1 (2007-12-09)
|
2
|
+
|
3
|
+
* Refactored and fixed Dataset#reverse_order to work with field quoting (thanks Christian).
|
4
|
+
|
5
|
+
* Fixed problem with field quoting in insert statements.
|
6
|
+
|
7
|
+
* Changed sequelizer code to silently fail on any error when requiring parsetree and ruby2ruby.
|
8
|
+
|
9
|
+
* Added Database#create_view, #create_or_replace_view and #drop_view methods. Also implemented Dataset#create_view and #create_or_replace_view convenience methods.
|
10
|
+
|
11
|
+
* Keep DRY by re-using Model#[]= from method_missing.
|
12
|
+
|
13
|
+
* Added Model.fetch alias for DB.fetch.set_model(Model)
|
14
|
+
|
1
15
|
=== 0.4.2 (2007-12-07)
|
2
16
|
|
3
17
|
* Implemented Model#save_changes.
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
include FileUtils
|
7
7
|
|
8
8
|
NAME = "sequel"
|
9
|
-
VERS = "0.4.2"
|
9
|
+
VERS = "0.4.2.1"
|
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_sql.rb
CHANGED
data/lib/sequel/database.rb
CHANGED
@@ -194,6 +194,20 @@ module Sequel
|
|
194
194
|
false
|
195
195
|
end
|
196
196
|
|
197
|
+
def create_view(name, source)
|
198
|
+
source = source.sql if source.is_a?(Dataset)
|
199
|
+
execute("CREATE VIEW #{name} AS #{source}")
|
200
|
+
end
|
201
|
+
|
202
|
+
def create_or_replace_view(name, source)
|
203
|
+
source = source.sql if source.is_a?(Dataset)
|
204
|
+
execute("CREATE OR REPLACE VIEW #{name} AS #{source}")
|
205
|
+
end
|
206
|
+
|
207
|
+
def drop_view(name)
|
208
|
+
execute("DROP VIEW #{name}")
|
209
|
+
end
|
210
|
+
|
197
211
|
SQL_BEGIN = 'BEGIN'.freeze
|
198
212
|
SQL_COMMIT = 'COMMIT'.freeze
|
199
213
|
SQL_ROLLBACK = 'ROLLBACK'.freeze
|
@@ -263,7 +263,7 @@ end
|
|
263
263
|
|
264
264
|
begin
|
265
265
|
require 'parse_tree'
|
266
|
-
rescue
|
266
|
+
rescue Exception
|
267
267
|
module Sequel::Dataset::Sequelizer
|
268
268
|
def proc_to_sql(proc)
|
269
269
|
raise SequelError, "You must have the ParseTree gem installed in order to use block filters."
|
@@ -273,7 +273,7 @@ end
|
|
273
273
|
|
274
274
|
begin
|
275
275
|
require 'ruby2ruby'
|
276
|
-
rescue
|
276
|
+
rescue Exception
|
277
277
|
module Sequel::Dataset::Sequelizer
|
278
278
|
def ext_expr(e)
|
279
279
|
raise SequelError, "You must have the Ruby2Ruby gem installed in order to use this block filter."
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -152,28 +152,21 @@ module Sequel
|
|
152
152
|
order(*invert_order(order.empty? ? @opts[:order] : order))
|
153
153
|
end
|
154
154
|
|
155
|
-
DESC_ORDER_REGEXP = /^(.*)\sDESC$/i.freeze
|
156
|
-
|
157
155
|
# Inverts the given order by breaking it into a list of column references
|
158
156
|
# and inverting them.
|
159
157
|
#
|
160
|
-
# dataset.invert_order([
|
161
|
-
# dataset.invert_order(
|
162
|
-
# [
|
158
|
+
# dataset.invert_order([:id.desc]]) #=> [:id]
|
159
|
+
# dataset.invert_order(:category, :price.desc]) #=>
|
160
|
+
# [:category.desc, :price]
|
163
161
|
def invert_order(order)
|
164
162
|
new_order = []
|
165
|
-
order.
|
166
|
-
if f.is_a?(
|
167
|
-
f.
|
168
|
-
r.strip!
|
169
|
-
new_order << ((r =~ DESC_ORDER_REGEXP ? $1 : r.to_sym.desc).lit)
|
170
|
-
end
|
163
|
+
order.map do |f|
|
164
|
+
if f.is_a?(Sequel::SQL::ColumnExpr) && (f.op == Sequel::SQL::ColumnMethods::DESC)
|
165
|
+
f.l
|
171
166
|
else
|
172
|
-
|
173
|
-
new_order << ((r =~ DESC_ORDER_REGEXP ? $1 : r.to_sym.desc).lit)
|
167
|
+
f.desc
|
174
168
|
end
|
175
169
|
end
|
176
|
-
new_order
|
177
170
|
end
|
178
171
|
|
179
172
|
# Returns a copy of the dataset with the results grouped by the value of
|
@@ -442,7 +435,7 @@ module Sequel
|
|
442
435
|
if values.empty?
|
443
436
|
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
444
437
|
elsif values.keys
|
445
|
-
fl = values.keys
|
438
|
+
fl = values.keys.map {|f| literal(f.to_sym)}
|
446
439
|
vl = transform_save(values.values).map {|v| literal(v)}
|
447
440
|
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
448
441
|
else
|
@@ -454,7 +447,7 @@ module Sequel
|
|
454
447
|
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
455
448
|
else
|
456
449
|
fl, vl = [], []
|
457
|
-
values.each {|k, v| fl << k.
|
450
|
+
values.each {|k, v| fl << literal(k.to_sym); vl << literal(v)}
|
458
451
|
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
459
452
|
end
|
460
453
|
when Dataset
|
data/lib/sequel/model.rb
CHANGED
@@ -259,6 +259,10 @@ module Sequel
|
|
259
259
|
dataset[(Hash === args) ? args : primary_key_hash(args)]
|
260
260
|
end
|
261
261
|
|
262
|
+
def self.fetch(*args)
|
263
|
+
db.fetch(*args).set_model(self)
|
264
|
+
end
|
265
|
+
|
262
266
|
# Like find but invokes create with given conditions when record does not
|
263
267
|
# exists.
|
264
268
|
def self.find_or_create(cond)
|
data/lib/sequel/model/record.rb
CHANGED
@@ -284,12 +284,9 @@ module Sequel
|
|
284
284
|
# define the column accessor
|
285
285
|
Thread.exclusive do
|
286
286
|
if write
|
287
|
-
model.class_def(m)
|
288
|
-
@values[att] = v
|
289
|
-
@changed_columns << att unless @changed_columns.include?(att)
|
290
|
-
end
|
287
|
+
model.class_def(m) {|v| self[att] = v}
|
291
288
|
else
|
292
|
-
model.class_def(m) {
|
289
|
+
model.class_def(m) {self[att]}
|
293
290
|
end
|
294
291
|
end
|
295
292
|
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -96,7 +96,7 @@ context "A MySQL dataset" do
|
|
96
96
|
|
97
97
|
@d.order(:name.DESC).sql.should == \
|
98
98
|
'SELECT * FROM items ORDER BY `name` DESC'
|
99
|
-
|
99
|
+
|
100
100
|
@d.select('items.name AS item_name'.lit).sql.should == \
|
101
101
|
'SELECT items.name AS item_name FROM items'
|
102
102
|
|
@@ -118,8 +118,22 @@ context "A MySQL dataset" do
|
|
118
118
|
@d.insert_sql(:value => 333).should == \
|
119
119
|
'INSERT INTO items (`value`) VALUES (333)'
|
120
120
|
|
121
|
-
|
122
|
-
|
121
|
+
@d.insert_sql(:x => :y).should == \
|
122
|
+
'INSERT INTO items (`x`) VALUES (`y`)'
|
123
|
+
end
|
124
|
+
|
125
|
+
specify "should quote fields correctly when reversing the order" do
|
126
|
+
@d.reverse_order(:name).sql.should == \
|
127
|
+
'SELECT * FROM items ORDER BY `name` DESC'
|
128
|
+
|
129
|
+
@d.reverse_order(:name.DESC).sql.should == \
|
130
|
+
'SELECT * FROM items ORDER BY `name`'
|
131
|
+
|
132
|
+
@d.reverse_order(:name, :test.DESC).sql.should == \
|
133
|
+
'SELECT * FROM items ORDER BY `name` DESC, `test`'
|
134
|
+
|
135
|
+
@d.reverse_order(:name.DESC, :test).sql.should == \
|
136
|
+
'SELECT * FROM items ORDER BY `name`, `test` DESC'
|
123
137
|
end
|
124
138
|
|
125
139
|
specify "should support ORDER clause in UPDATE statements" do
|
data/spec/database_spec.rb
CHANGED
@@ -600,4 +600,49 @@ context "Database#[]" do
|
|
600
600
|
@db['select * from xyz where x = ? and y = ?', 15, 'abc'].each {|r| sql = r[:sql]}
|
601
601
|
sql.should == "select * from xyz where x = 15 and y = 'abc'"
|
602
602
|
end
|
603
|
-
end
|
603
|
+
end
|
604
|
+
|
605
|
+
context "Database#create_view" do
|
606
|
+
setup do
|
607
|
+
@db = DummyDatabase.new
|
608
|
+
end
|
609
|
+
|
610
|
+
specify "should construct proper SQL with raw SQL" do
|
611
|
+
@db.create_view :test, "SELECT * FROM xyz"
|
612
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
|
613
|
+
end
|
614
|
+
|
615
|
+
specify "should construct proper SQL with dataset" do
|
616
|
+
@db.create_view :test, @db[:items].select(:a, :b).order(:c)
|
617
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
context "Database#create_or_replace_view" do
|
622
|
+
setup do
|
623
|
+
@db = DummyDatabase.new
|
624
|
+
end
|
625
|
+
|
626
|
+
specify "should construct proper SQL with raw SQL" do
|
627
|
+
@db.create_or_replace_view :test, "SELECT * FROM xyz"
|
628
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT * FROM xyz']
|
629
|
+
end
|
630
|
+
|
631
|
+
specify "should construct proper SQL with dataset" do
|
632
|
+
@db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
|
633
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
context "Database#drop_view" do
|
638
|
+
setup do
|
639
|
+
@db = DummyDatabase.new
|
640
|
+
end
|
641
|
+
|
642
|
+
specify "should construct proper SQL" do
|
643
|
+
@db.drop_view :test
|
644
|
+
@db.sqls.should == ['DROP VIEW test']
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
|
data/spec/dataset_spec.rb
CHANGED
@@ -752,7 +752,7 @@ context "Dataset#reverse_order" do
|
|
752
752
|
specify "should reverse a previous ordering if no arguments are given" do
|
753
753
|
@dataset.order(:name).reverse_order.sql.should ==
|
754
754
|
'SELECT * FROM test ORDER BY name DESC'
|
755
|
-
@dataset.order(
|
755
|
+
@dataset.order(:clumsy.DESC, :fool).reverse_order.sql.should ==
|
756
756
|
'SELECT * FROM test ORDER BY clumsy, fool DESC'
|
757
757
|
end
|
758
758
|
end
|
@@ -2278,4 +2278,47 @@ context "Dataset magic methods" do
|
|
2278
2278
|
@ds.last_by_name('sharon').should == {:a => 1, :b => 2}
|
2279
2279
|
@c.sqls.should == ["SELECT * FROM items ORDER BY name DESC LIMIT 1"] * 2
|
2280
2280
|
end
|
2281
|
-
end
|
2281
|
+
end
|
2282
|
+
|
2283
|
+
context "Dataset#create_view" do
|
2284
|
+
setup do
|
2285
|
+
@dbc = Class.new(Sequel::Database) do
|
2286
|
+
attr_reader :sqls
|
2287
|
+
|
2288
|
+
def execute(sql)
|
2289
|
+
@sqls ||= []
|
2290
|
+
@sqls << sql
|
2291
|
+
end
|
2292
|
+
end
|
2293
|
+
@db = @dbc.new
|
2294
|
+
|
2295
|
+
@ds = @db[:items].order(:abc).filter(:category => 'ruby')
|
2296
|
+
end
|
2297
|
+
|
2298
|
+
specify "should create a view with the dataset's sql" do
|
2299
|
+
@ds.create_view(:xyz)
|
2300
|
+
@db.sqls.should == ["CREATE VIEW xyz AS #{@ds.sql}"]
|
2301
|
+
end
|
2302
|
+
end
|
2303
|
+
|
2304
|
+
context "Dataset#create_or_replace_view" do
|
2305
|
+
setup do
|
2306
|
+
@dbc = Class.new(Sequel::Database) do
|
2307
|
+
attr_reader :sqls
|
2308
|
+
|
2309
|
+
def execute(sql)
|
2310
|
+
@sqls ||= []
|
2311
|
+
@sqls << sql
|
2312
|
+
end
|
2313
|
+
end
|
2314
|
+
@db = @dbc.new
|
2315
|
+
|
2316
|
+
@ds = @db[:items].order(:abc).filter(:category => 'ruby')
|
2317
|
+
end
|
2318
|
+
|
2319
|
+
specify "should create a view with the dataset's sql" do
|
2320
|
+
@ds.create_or_replace_view(:xyz)
|
2321
|
+
@db.sqls.should == ["CREATE OR REPLACE VIEW xyz AS #{@ds.sql}"]
|
2322
|
+
end
|
2323
|
+
end
|
2324
|
+
|
data/spec/model_spec.rb
CHANGED
@@ -724,6 +724,17 @@ context "Model.[]" do
|
|
724
724
|
end
|
725
725
|
end
|
726
726
|
|
727
|
+
context "Model.fetch" do
|
728
|
+
setup do
|
729
|
+
MODEL_DB.reset
|
730
|
+
@c = Class.new(Sequel::Model(:items))
|
731
|
+
end
|
732
|
+
|
733
|
+
specify "should return instances of Model" do
|
734
|
+
@c.fetch("SELECT * FROM items").first.should be_a_kind_of(@c)
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
727
738
|
context "A cached model" do
|
728
739
|
setup do
|
729
740
|
MODEL_DB.reset
|
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
|
4
|
+
version: 0.4.2.1
|
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-09 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|