sequel 0.3.2 → 0.3.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 +16 -0
- data/Rakefile +1 -1
- data/lib/sequel.rb +1 -1
- data/lib/sequel/array_keys.rb +2 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core_ext.rb +53 -12
- data/lib/sequel/database.rb +1 -1
- data/lib/sequel/dataset/sql.rb +11 -11
- data/lib/sequel/mysql.rb +9 -9
- data/lib/sequel/postgres.rb +2 -2
- data/lib/sequel/schema/schema_sql.rb +4 -4
- data/lib/sequel/sqlite.rb +3 -3
- data/lib/sequel/worker.rb +44 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +130 -0
- data/spec/array_keys_spec.rb +6 -6
- data/spec/connection_pool_spec.rb +1 -1
- data/spec/core_ext_spec.rb +59 -1
- data/spec/database_spec.rb +17 -13
- data/spec/dataset_spec.rb +32 -32
- data/spec/model_spec.rb +14 -14
- data/spec/schema_spec.rb +26 -26
- data/spec/worker_spec.rb +63 -0
- metadata +5 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
=== 0.3.3 (2007-11-04)
|
2
|
+
|
3
|
+
* Revised code to generate SQL statements without trailing semicolons.
|
4
|
+
|
5
|
+
* Added Sequel::Worker implementation of a simple worker thread for asynchronous execution.
|
6
|
+
|
7
|
+
* Added spec for Oracle adapter.
|
8
|
+
|
9
|
+
* Fixed Oracle adapter to format INSERT statements without semicolons (thanks Liming Lian).
|
10
|
+
|
11
|
+
* Renamed alias to Array#keys as Array#columns instead of Array#fields.
|
12
|
+
|
13
|
+
* Renamed FieldCompositionMethods as ColumnCompositionMethods.
|
14
|
+
|
15
|
+
* Implemented Sequel::NumericExtensions to provide stuff like 30.days.ago.
|
16
|
+
|
1
17
|
=== 0.3.2 (2007-11-01)
|
2
18
|
|
3
19
|
* Added #to_column_name as alias to #to_field_name, #column_title as alias to #field_title.
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
include FileUtils
|
7
7
|
|
8
8
|
NAME = "sequel"
|
9
|
-
VERS = "0.3.
|
9
|
+
VERS = "0.3.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.rb
CHANGED
@@ -2,7 +2,7 @@ require 'metaid'
|
|
2
2
|
|
3
3
|
files = %w[
|
4
4
|
core_ext array_keys error connection_pool pretty_table
|
5
|
-
dataset migration model schema database
|
5
|
+
dataset migration model schema database worker
|
6
6
|
]
|
7
7
|
dir = File.join(File.dirname(__FILE__), 'sequel')
|
8
8
|
files.each {|f| require(File.join(dir, f))}
|
data/lib/sequel/array_keys.rb
CHANGED
@@ -183,8 +183,8 @@ module ArrayKeys
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
-
alias_method :
|
187
|
-
alias_method :
|
186
|
+
alias_method :columns, :keys
|
187
|
+
alias_method :columns=, :keys=
|
188
188
|
end
|
189
189
|
|
190
190
|
# The DatasetExtensions module provides extensions that modify
|
@@ -43,7 +43,7 @@ module Sequel
|
|
43
43
|
# Assigns a connection to the current thread, yielding the connection
|
44
44
|
# to the supplied block.
|
45
45
|
#
|
46
|
-
# pool.hold {|conn| conn.execute('DROP TABLE posts
|
46
|
+
# pool.hold {|conn| conn.execute('DROP TABLE posts')}
|
47
47
|
#
|
48
48
|
# Pool#hold is re-entrant, meaning it can be called recursively in
|
49
49
|
# the same thread without blocking.
|
data/lib/sequel/core_ext.rb
CHANGED
@@ -17,6 +17,14 @@ class Array
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
# Range extensions
|
21
|
+
class Range
|
22
|
+
# Returns the interval between the beginning and end of the range.
|
23
|
+
def interval
|
24
|
+
last - first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
20
28
|
module Sequel
|
21
29
|
# LiteralString is used to represent literal SQL expressions. An
|
22
30
|
# LiteralString is copied verbatim into an SQL statement. Instances of
|
@@ -68,7 +76,7 @@ end
|
|
68
76
|
|
69
77
|
# Methods to format column names and associated constructs. This module is
|
70
78
|
# included in String and Symbol.
|
71
|
-
module
|
79
|
+
module ColumnCompositionMethods
|
72
80
|
# Constructs a DESC clause for use in an ORDER BY clause.
|
73
81
|
def DESC
|
74
82
|
"#{to_column_name} DESC".lit
|
@@ -84,14 +92,14 @@ module FieldCompositionMethods
|
|
84
92
|
"#{to_s}.*".lit
|
85
93
|
end
|
86
94
|
|
87
|
-
|
88
|
-
|
95
|
+
COLUMN_TITLE_RE1 = /^(.*)\sAS\s(.+)$/i.freeze
|
96
|
+
COLUMN_TITLE_RE2 = /^([^\.]+)\.([^\.]+)$/.freeze
|
89
97
|
|
90
98
|
# Returns the column name. If the column name is aliased, the alias is
|
91
99
|
# returned.
|
92
100
|
def field_title
|
93
101
|
case s = to_column_name
|
94
|
-
when
|
102
|
+
when COLUMN_TITLE_RE1, COLUMN_TITLE_RE2: $2
|
95
103
|
else
|
96
104
|
s
|
97
105
|
end
|
@@ -101,17 +109,17 @@ end
|
|
101
109
|
|
102
110
|
# String extensions
|
103
111
|
class String
|
104
|
-
include
|
112
|
+
include ColumnCompositionMethods
|
105
113
|
end
|
106
114
|
|
107
115
|
# Symbol extensions
|
108
116
|
class Symbol
|
109
|
-
include
|
117
|
+
include ColumnCompositionMethods
|
110
118
|
|
111
119
|
|
112
|
-
|
113
|
-
|
114
|
-
|
120
|
+
COLUMN_REF_RE1 = /^(\w+)__(\w+)___(\w+)/.freeze
|
121
|
+
COLUMN_REF_RE2 = /^(\w+)___(\w+)$/.freeze
|
122
|
+
COLUMN_REF_RE3 = /^(\w+)__(\w+)$/.freeze
|
115
123
|
|
116
124
|
# Converts a symbol into a column name. This method supports underscore
|
117
125
|
# notation in order to express qualified (two underscores) and aliased
|
@@ -125,9 +133,9 @@ class Symbol
|
|
125
133
|
def to_field_name
|
126
134
|
s = to_s
|
127
135
|
case s
|
128
|
-
when
|
129
|
-
when
|
130
|
-
when
|
136
|
+
when COLUMN_REF_RE1: "#{$1}.#{$2} AS #{$3}"
|
137
|
+
when COLUMN_REF_RE2: "#{$1} AS #{$2}"
|
138
|
+
when COLUMN_REF_RE3: "#{$1}.#{$2}"
|
131
139
|
else
|
132
140
|
s
|
133
141
|
end
|
@@ -147,4 +155,37 @@ class Symbol
|
|
147
155
|
end
|
148
156
|
end
|
149
157
|
|
158
|
+
module Sequel
|
159
|
+
# Facilitates time calculations by providing methods to convert from larger
|
160
|
+
# time units to seconds, and to convert relative time intervals to absolute
|
161
|
+
# ones. This module duplicates some of the functionality provided by Rails'
|
162
|
+
# ActiveSupport::CoreExtensions::Numeric::Time module.
|
163
|
+
module NumericExtensions
|
164
|
+
MINUTE = 60
|
165
|
+
HOUR = 3600
|
166
|
+
DAY = 86400
|
167
|
+
WEEK = DAY * 7
|
168
|
+
|
169
|
+
# Converts self from minutes to seconds
|
170
|
+
def minutes; self * MINUTE; end; alias_method :minute, :minutes
|
171
|
+
# Converts self from hours to seconds
|
172
|
+
def hours; self * HOUR; end; alias_method :hour, :hours
|
173
|
+
# Converts self from days to seconds
|
174
|
+
def days; self * DAY; end; alias_method :day, :days
|
175
|
+
# Converts self from weeks to seconds
|
176
|
+
def weeks; self * WEEK; end; alias_method :week, :weeks
|
177
|
+
|
178
|
+
# Returns the time at now - self.
|
179
|
+
def ago(t = Time.now); t - self; end
|
180
|
+
alias_method :before, :ago
|
150
181
|
|
182
|
+
# Returns the time at now + self.
|
183
|
+
def from_now(t = Time.now); t + self; end
|
184
|
+
alias_method :since, :from_now
|
185
|
+
|
186
|
+
# Extends the Numeric class with numeric extensions.
|
187
|
+
def self.enable
|
188
|
+
Numeric.send(:include, self)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
data/lib/sequel/database.rb
CHANGED
@@ -180,7 +180,7 @@ module Sequel
|
|
180
180
|
|
181
181
|
# Drops one or more tables corresponding to the given table names.
|
182
182
|
def drop_table(*names)
|
183
|
-
|
183
|
+
names.each {|n| execute(drop_table_sql(n))}
|
184
184
|
end
|
185
185
|
|
186
186
|
# Returns true if the given table exists.
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -438,7 +438,7 @@ module Sequel
|
|
438
438
|
# 'INSERT INTO items (a, b) VALUES (1, 2)'
|
439
439
|
def insert_sql(*values)
|
440
440
|
if values.empty?
|
441
|
-
"INSERT INTO #{@opts[:from]} DEFAULT VALUES
|
441
|
+
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
442
442
|
else
|
443
443
|
values = values[0] if values.size == 1
|
444
444
|
case values
|
@@ -446,27 +446,27 @@ module Sequel
|
|
446
446
|
insert_sql(values.values)
|
447
447
|
when Array
|
448
448
|
if values.empty?
|
449
|
-
"INSERT INTO #{@opts[:from]} DEFAULT VALUES
|
450
|
-
elsif values.
|
451
|
-
fl = values.
|
449
|
+
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
450
|
+
elsif values.keys
|
451
|
+
fl = values.keys
|
452
452
|
vl = transform_save(values.values).map {|v| literal(v)}
|
453
|
-
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})
|
453
|
+
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
454
454
|
else
|
455
|
-
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)})
|
455
|
+
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)})"
|
456
456
|
end
|
457
457
|
when Hash
|
458
458
|
values = transform_save(values) if @transform
|
459
459
|
if values.empty?
|
460
|
-
"INSERT INTO #{@opts[:from]} DEFAULT VALUES
|
460
|
+
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
461
461
|
else
|
462
462
|
fl, vl = [], []
|
463
463
|
values.each {|k, v| fl << column_name(k); vl << literal(v)}
|
464
|
-
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})
|
464
|
+
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
465
465
|
end
|
466
466
|
when Dataset
|
467
|
-
"INSERT INTO #{@opts[:from]} #{literal(values)}
|
467
|
+
"INSERT INTO #{@opts[:from]} #{literal(values)}"
|
468
468
|
else
|
469
|
-
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)})
|
469
|
+
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)})"
|
470
470
|
end
|
471
471
|
end
|
472
472
|
end
|
@@ -484,7 +484,7 @@ module Sequel
|
|
484
484
|
raise SequelError, "Can't update a joined dataset"
|
485
485
|
end
|
486
486
|
|
487
|
-
if values.is_a?(Array) && values.
|
487
|
+
if values.is_a?(Array) && values.keys
|
488
488
|
values = values.to_hash
|
489
489
|
end
|
490
490
|
values = transform_save(values) if @transform
|
data/lib/sequel/mysql.rb
CHANGED
@@ -96,9 +96,9 @@ module Sequel
|
|
96
96
|
@opts[:database], @opts[:port])
|
97
97
|
conn.query_with_result = false
|
98
98
|
if encoding = @opts[:encoding] || @opts[:charset]
|
99
|
-
conn.query("set character_set_connection = '#{encoding}'
|
100
|
-
conn.query("set character_set_client = '#{encoding}'
|
101
|
-
conn.query("set character_set_results = '#{encoding}'
|
99
|
+
conn.query("set character_set_connection = '#{encoding}'")
|
100
|
+
conn.query("set character_set_client = '#{encoding}'")
|
101
|
+
conn.query("set character_set_results = '#{encoding}'")
|
102
102
|
end
|
103
103
|
conn.reconnect = true
|
104
104
|
conn
|
@@ -172,20 +172,20 @@ module Sequel
|
|
172
172
|
end
|
173
173
|
|
174
174
|
class Dataset < Sequel::Dataset
|
175
|
-
|
175
|
+
UNQUOTABLE_COLUMN_RE = /^(`(.+)`)|\*$/.freeze
|
176
176
|
def quote_column(f)
|
177
|
-
(f.nil? || f.empty? || f =~
|
177
|
+
(f.nil? || f.empty? || f =~ UNQUOTABLE_COLUMN_RE) ? f : "`#{f}`"
|
178
178
|
end
|
179
179
|
|
180
|
-
|
181
|
-
|
180
|
+
COLUMN_EXPR_RE = /^([^\(]+\()?([^\.]+\.)?([^\s\)]+)?(\))?(\sAS\s(.+))?$/i.freeze
|
181
|
+
COLUMN_ORDER_RE = /^(.*) (DESC|ASC)$/i.freeze
|
182
182
|
def quoted_column_name(name)
|
183
183
|
case name
|
184
|
-
when
|
184
|
+
when COLUMN_EXPR_RE:
|
185
185
|
$6 ? \
|
186
186
|
"#{$1}#{$2}#{quote_column($3)}#{$4} AS #{quote_column($6)}" : \
|
187
187
|
"#{$1}#{$2}#{quote_column($3)}#{$4}"
|
188
|
-
when
|
188
|
+
when COLUMN_ORDER_RE: "#{quote_column($1)} #{$2}"
|
189
189
|
else
|
190
190
|
quote_column(name)
|
191
191
|
end
|
data/lib/sequel/postgres.rb
CHANGED
@@ -284,7 +284,7 @@ module Sequel
|
|
284
284
|
end
|
285
285
|
|
286
286
|
def drop_table_sql(name)
|
287
|
-
"DROP TABLE #{name} CASCADE
|
287
|
+
"DROP TABLE #{name} CASCADE"
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
@@ -350,7 +350,7 @@ module Sequel
|
|
350
350
|
analysis.join("\r\n")
|
351
351
|
end
|
352
352
|
|
353
|
-
LOCK = 'LOCK TABLE %s IN %s MODE
|
353
|
+
LOCK = 'LOCK TABLE %s IN %s MODE'.freeze
|
354
354
|
|
355
355
|
ACCESS_SHARE = 'ACCESS SHARE'.freeze
|
356
356
|
ROW_SHARE = 'ROW SHARE'.freeze
|
@@ -63,9 +63,9 @@ module Sequel
|
|
63
63
|
columns = index[:columns].join(COMMA_SEPARATOR)
|
64
64
|
index_name = index[:name] || default_index_name(table_name, index[:columns])
|
65
65
|
if index[:unique]
|
66
|
-
"CREATE UNIQUE INDEX #{index_name} ON #{table_name} (#{columns})
|
66
|
+
"CREATE UNIQUE INDEX #{index_name} ON #{table_name} (#{columns})"
|
67
67
|
else
|
68
|
-
"CREATE INDEX #{index_name} ON #{table_name} (#{columns})
|
68
|
+
"CREATE INDEX #{index_name} ON #{table_name} (#{columns})"
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -74,7 +74,7 @@ module Sequel
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def create_table_sql_list(name, columns, indexes = nil)
|
77
|
-
sql = ["CREATE TABLE #{name} (#{column_list_sql(columns)})
|
77
|
+
sql = ["CREATE TABLE #{name} (#{column_list_sql(columns)})"]
|
78
78
|
if indexes && !indexes.empty?
|
79
79
|
sql.concat(index_list_sql_list(name, indexes))
|
80
80
|
end
|
@@ -82,7 +82,7 @@ module Sequel
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def drop_table_sql(name)
|
85
|
-
"DROP TABLE #{name}
|
85
|
+
"DROP TABLE #{name}"
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
data/lib/sequel/sqlite.rb
CHANGED
@@ -61,11 +61,11 @@ module Sequel
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def pragma_get(name)
|
64
|
-
single_value("PRAGMA #{name}
|
64
|
+
single_value("PRAGMA #{name}")
|
65
65
|
end
|
66
66
|
|
67
67
|
def pragma_set(name, value)
|
68
|
-
execute("PRAGMA #{name} = #{value}
|
68
|
+
execute("PRAGMA #{name} = #{value}")
|
69
69
|
end
|
70
70
|
|
71
71
|
AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
|
@@ -149,7 +149,7 @@ module Sequel
|
|
149
149
|
def array_tuples_fetch_rows(sql, &block)
|
150
150
|
@db.execute_select(sql) do |result|
|
151
151
|
@columns = result.columns.map {|c| c.to_sym}
|
152
|
-
result.each
|
152
|
+
result.each {|r| r.keys = @columns; block[r]}
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
class Worker < Thread
|
5
|
+
class WorkerStopError < RuntimeError; end
|
6
|
+
|
7
|
+
attr_reader :queue
|
8
|
+
|
9
|
+
def initialize(db = nil)
|
10
|
+
@queue = Queue.new
|
11
|
+
t = self
|
12
|
+
if db
|
13
|
+
super {db.transaction {t.work}}
|
14
|
+
else
|
15
|
+
super {t.work}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def work
|
20
|
+
begin
|
21
|
+
loop {@cur = @queue.pop; @cur.call; @cur = nil}
|
22
|
+
rescue WorkerStopError # do nothing
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def busy?
|
27
|
+
@cur || !@queue.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def async(proc = nil, &block)
|
31
|
+
@queue << (proc || block)
|
32
|
+
end
|
33
|
+
alias_method :add, :async
|
34
|
+
alias_method :<<, :async
|
35
|
+
|
36
|
+
def join
|
37
|
+
while busy?
|
38
|
+
sleep 0.1
|
39
|
+
end
|
40
|
+
self.raise WorkerStopError
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -107,7 +107,7 @@ context "A MySQL dataset" do
|
|
107
107
|
'SELECT max(items.`name`) AS `max_name` FROM items'
|
108
108
|
|
109
109
|
@d.insert_sql(:value => 333).should == \
|
110
|
-
'INSERT INTO items (`value`) VALUES (333)
|
110
|
+
'INSERT INTO items (`value`) VALUES (333)'
|
111
111
|
end
|
112
112
|
|
113
113
|
specify "should support ORDER clause in UPDATE statements" do
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../lib/sequel/oracle')
|
2
|
+
|
3
|
+
ORACLE_DB = Sequel('oracle://hr:hr@loalhost/XE')
|
4
|
+
if ORACLE_DB.table_exists?(:test)
|
5
|
+
ORACLE_DB.drop_table :test
|
6
|
+
end
|
7
|
+
ORACLE_DB.create_table :test do
|
8
|
+
text :name
|
9
|
+
integer :value
|
10
|
+
|
11
|
+
index :value
|
12
|
+
end
|
13
|
+
|
14
|
+
context "A Oracle database" do
|
15
|
+
specify "should provide disconnect functionality" do
|
16
|
+
ORACLE_DB.execute("select user from dual")
|
17
|
+
ORACLE_DB.pool.size.should == 1
|
18
|
+
ORACLE_DB.disconnect
|
19
|
+
ORACLE_DB.pool.size.should == 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "A Oracle dataset" do
|
24
|
+
setup do
|
25
|
+
@d = ORACLE_DB[:test]
|
26
|
+
@d.delete # remove all records
|
27
|
+
end
|
28
|
+
|
29
|
+
specify "should return the correct record count" do
|
30
|
+
@d.count.should == 0
|
31
|
+
@d << {:name => 'abc', :value => 123}
|
32
|
+
@d << {:name => 'abc', :value => 456}
|
33
|
+
@d << {:name => 'def', :value => 789}
|
34
|
+
@d.count.should == 3
|
35
|
+
end
|
36
|
+
|
37
|
+
specify "should return the correct records" do
|
38
|
+
@d.to_a.should == []
|
39
|
+
@d << {:name => 'abc', :value => 123}
|
40
|
+
@d << {:name => 'abc', :value => 456}
|
41
|
+
@d << {:name => 'def', :value => 789}
|
42
|
+
|
43
|
+
@d.order(:value).to_a.should == [
|
44
|
+
{:name => 'abc', :value => 123},
|
45
|
+
{:name => 'abc', :value => 456},
|
46
|
+
{:name => 'def', :value => 789}
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should update records correctly" do
|
51
|
+
@d << {:name => 'abc', :value => 123}
|
52
|
+
@d << {:name => 'abc', :value => 456}
|
53
|
+
@d << {:name => 'def', :value => 789}
|
54
|
+
@d.filter(:name => 'abc').update(:value => 530)
|
55
|
+
|
56
|
+
# the third record should stay the same
|
57
|
+
# floating-point precision bullshit
|
58
|
+
@d[:name => 'def'][:value].should == 789
|
59
|
+
@d.filter(:value => 530).count.should == 2
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "should delete records correctly" do
|
63
|
+
@d << {:name => 'abc', :value => 123}
|
64
|
+
@d << {:name => 'abc', :value => 456}
|
65
|
+
@d << {:name => 'def', :value => 789}
|
66
|
+
@d.filter(:name => 'abc').delete
|
67
|
+
|
68
|
+
@d.count.should == 1
|
69
|
+
@d.first[:name].should == 'def'
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should be able to literalize booleans" do
|
73
|
+
proc {@d.literal(true)}.should_not raise_error
|
74
|
+
proc {@d.literal(false)}.should_not raise_error
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "should support transactions" do
|
78
|
+
ORACLE_DB.transaction do
|
79
|
+
@d << {:name => 'abc', :value => 1}
|
80
|
+
end
|
81
|
+
|
82
|
+
@d.count.should == 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "A Oracle dataset in array tuples mode" do
|
87
|
+
setup do
|
88
|
+
@d = ORACLE_DB[:test]
|
89
|
+
@d.delete # remove all records
|
90
|
+
Sequel.use_array_tuples
|
91
|
+
end
|
92
|
+
|
93
|
+
teardown do
|
94
|
+
Sequel.use_hash_tuples
|
95
|
+
end
|
96
|
+
|
97
|
+
specify "should return the correct records" do
|
98
|
+
@d.to_a.should == []
|
99
|
+
@d << {:name => 'abc', :value => 123}
|
100
|
+
@d << {:name => 'abc', :value => 456}
|
101
|
+
@d << {:name => 'def', :value => 789}
|
102
|
+
|
103
|
+
@d.order(:value).select(:name, :value).to_a.should == [
|
104
|
+
['abc', 123],
|
105
|
+
['abc', 456],
|
106
|
+
['def', 789]
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
specify "should work correctly with transforms" do
|
111
|
+
@d.transform(:value => [proc {|v| v.to_s}, proc {|v| v.to_i}])
|
112
|
+
|
113
|
+
@d.to_a.should == []
|
114
|
+
@d << {:name => 'abc', :value => 123}
|
115
|
+
@d << {:name => 'abc', :value => 456}
|
116
|
+
@d << {:name => 'def', :value => 789}
|
117
|
+
|
118
|
+
@d.order(:value).select(:name, :value).to_a.should == [
|
119
|
+
['abc', '123'],
|
120
|
+
['abc', '456'],
|
121
|
+
['def', '789']
|
122
|
+
]
|
123
|
+
|
124
|
+
a = @d.order(:value).first
|
125
|
+
a.values.should == ['abc', '123']
|
126
|
+
a.keys.should == [:name, :value]
|
127
|
+
a[:name].should == 'abc'
|
128
|
+
a[:value].should == '123'
|
129
|
+
end
|
130
|
+
end
|