sequel 0.1.8 → 0.1.9
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 +24 -0
- data/README +1 -1
- data/Rakefile +1 -1
- data/lib/sequel/core_ext.rb +5 -0
- data/lib/sequel/database.rb +44 -2
- data/lib/sequel/dataset/dataset_convenience.rb +2 -1
- data/lib/sequel/dataset/dataset_sql.rb +4 -4
- data/lib/sequel/mysql.rb +127 -14
- data/lib/sequel/postgres.rb +7 -11
- data/spec/adapters/mysql_spec.rb +105 -0
- data/spec/core_ext_spec.rb +7 -0
- data/spec/database_spec.rb +79 -0
- metadata +4 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
=== 0.1.9 (2007-07-21)
|
2
|
+
|
3
|
+
* Fixed #update_sql and #insert_sql to support field quoting by calling #field_name.
|
4
|
+
|
5
|
+
* Implemented automatic data type conversion in mysql adapter.
|
6
|
+
|
7
|
+
* Added support for boolean literals in mysql adapter.
|
8
|
+
|
9
|
+
* Added support for ORDER and LIMIT clauses in UPDATE statements in mysql adapter.
|
10
|
+
|
11
|
+
* Implemented correct field quoting (using back-ticks) in mysql adapter.
|
12
|
+
|
13
|
+
* Wrote basic MySQL spec.
|
14
|
+
|
15
|
+
* Fixd MySQL::Dataset to return correct data types with symbols as hash keys.
|
16
|
+
|
17
|
+
* Removed discunctional MySQL::Database#transaction.
|
18
|
+
|
19
|
+
* Added support for single threaded operation.
|
20
|
+
|
21
|
+
* Fixed bug in Dataset#format_eq_expression where Range objects would not be literalized correctly.
|
22
|
+
|
23
|
+
* Added parens around postgres LIKE expressions using regexps.
|
24
|
+
|
1
25
|
=== 0.1.8 (2007-07-10)
|
2
26
|
|
3
27
|
* Implemented Dataset#columns for retrieving the columns in the result set.
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
include FileUtils
|
7
7
|
|
8
8
|
NAME = "sequel"
|
9
|
-
VERS = "0.1.
|
9
|
+
VERS = "0.1.9"
|
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
data/lib/sequel/database.rb
CHANGED
@@ -5,6 +5,25 @@ require File.join(File.dirname(__FILE__), 'dataset')
|
|
5
5
|
require File.join(File.dirname(__FILE__), 'model')
|
6
6
|
|
7
7
|
module Sequel
|
8
|
+
# A SingleThreadedPool acts as a replacement for a ConnectionPool for use
|
9
|
+
# in single-threaded applications. ConnectionPool imposes a substantial
|
10
|
+
# performance penalty, so SingleThreadedPool is used to gain some speed.
|
11
|
+
class SingleThreadedPool
|
12
|
+
attr_writer :connection_proc
|
13
|
+
|
14
|
+
def initialize(&block)
|
15
|
+
@connection_proc = block
|
16
|
+
end
|
17
|
+
|
18
|
+
def hold
|
19
|
+
@conn ||= @connection_proc.call
|
20
|
+
yield @conn
|
21
|
+
rescue Exception => e
|
22
|
+
# if the error is not a StandardError it is converted into RuntimeError.
|
23
|
+
raise e.is_a?(StandardError) ? e : e.message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
8
27
|
# A Database object represents a virtual connection to a database.
|
9
28
|
# The Database class is meant to be subclassed by database adapters in order
|
10
29
|
# to provide the functionality needed for executing queries.
|
@@ -18,15 +37,32 @@ module Sequel
|
|
18
37
|
def initialize(opts = {}, &block)
|
19
38
|
Model.database_opened(self)
|
20
39
|
@opts = opts
|
21
|
-
|
22
|
-
|
40
|
+
|
41
|
+
# Determine if the DB is single threaded or multi threaded
|
42
|
+
@single_threaded = opts[:single_threaded] || @@single_threaded
|
43
|
+
# Construct pool
|
44
|
+
if @single_threaded
|
45
|
+
@pool = SingleThreadedPool.new(&block)
|
46
|
+
else
|
47
|
+
@pool = ConnectionPool.new(opts[:max_connections] || 4, &block)
|
48
|
+
end
|
23
49
|
@pool.connection_proc = block || proc {connect}
|
50
|
+
|
51
|
+
@logger = opts[:logger]
|
24
52
|
end
|
25
53
|
|
26
54
|
def connect
|
27
55
|
raise NotImplementedError, "#connect should be overriden by adapters"
|
28
56
|
end
|
29
57
|
|
58
|
+
def multi_threaded?
|
59
|
+
!@single_threaded
|
60
|
+
end
|
61
|
+
|
62
|
+
def single_threaded?
|
63
|
+
@single_threaded
|
64
|
+
end
|
65
|
+
|
30
66
|
def uri
|
31
67
|
uri = URI::Generic.new(
|
32
68
|
self.class.adapter_scheme.to_s,
|
@@ -188,6 +224,12 @@ module Sequel
|
|
188
224
|
raise SequelError, "Invalid database scheme" unless c
|
189
225
|
c.new(c.uri_to_options(uri).merge(more_opts || {}))
|
190
226
|
end
|
227
|
+
|
228
|
+
@@single_threaded = false
|
229
|
+
|
230
|
+
def self.single_threaded=(value)
|
231
|
+
@@single_threaded = value
|
232
|
+
end
|
191
233
|
end
|
192
234
|
end
|
193
235
|
|
@@ -12,7 +12,8 @@ module Sequel
|
|
12
12
|
# Returns the first value of the first reecord in the dataset.
|
13
13
|
def single_value(opts = nil)
|
14
14
|
opts = opts ? NAKED_HASH.merge(opts) : NAKED_HASH
|
15
|
-
|
15
|
+
# reset the columns cache so it won't fuck subsequent calls to columns
|
16
|
+
each(opts) {|r| @columns = nil; return r.values.first}
|
16
17
|
end
|
17
18
|
|
18
19
|
# Returns the first record in the dataset. If the num argument is specified,
|
@@ -96,8 +96,8 @@ module Sequel
|
|
96
96
|
case right
|
97
97
|
when Range:
|
98
98
|
right.exclude_end? ? \
|
99
|
-
"(#{left} >= #{right.begin} AND #{left} < #{right.end})" : \
|
100
|
-
"(#{left} >= #{right.begin} AND #{left} <= #{right.end})"
|
99
|
+
"(#{left} >= #{literal(right.begin)} AND #{left} < #{literal(right.end)})" : \
|
100
|
+
"(#{left} >= #{literal(right.begin)} AND #{left} <= #{literal(right.end)})"
|
101
101
|
when Array:
|
102
102
|
"(#{left} IN (#{literal(right)}))"
|
103
103
|
when Dataset:
|
@@ -464,7 +464,7 @@ module Sequel
|
|
464
464
|
field_list = []
|
465
465
|
value_list = []
|
466
466
|
values[0].each do |k, v|
|
467
|
-
field_list << k
|
467
|
+
field_list << field_name(k)
|
468
468
|
value_list << literal(v)
|
469
469
|
end
|
470
470
|
fl = field_list.join(COMMA_SEPARATOR)
|
@@ -488,7 +488,7 @@ module Sequel
|
|
488
488
|
raise SequelError, "Can't update a joined dataset"
|
489
489
|
end
|
490
490
|
|
491
|
-
set_list = values.map {|k, v| "#{k} = #{literal(v)}"}.
|
491
|
+
set_list = values.map {|k, v| "#{field_name(k)} = #{literal(v)}"}.
|
492
492
|
join(COMMA_SEPARATOR)
|
493
493
|
sql = "UPDATE #{@opts[:from]} SET #{set_list}"
|
494
494
|
|
data/lib/sequel/mysql.rb
CHANGED
@@ -4,21 +4,74 @@ end
|
|
4
4
|
|
5
5
|
require 'mysql'
|
6
6
|
|
7
|
+
# Monkey patch Mysql::Result to yield hashes with symbol keys
|
8
|
+
class Mysql::Result
|
9
|
+
MYSQL_TYPES = {
|
10
|
+
0 => :to_i,
|
11
|
+
1 => :to_i,
|
12
|
+
2 => :to_i,
|
13
|
+
3 => :to_i,
|
14
|
+
4 => :to_f,
|
15
|
+
5 => :to_f,
|
16
|
+
7 => :to_time,
|
17
|
+
8 => :to_i,
|
18
|
+
9 => :to_i,
|
19
|
+
10 => :to_time,
|
20
|
+
11 => :to_time,
|
21
|
+
12 => :to_time,
|
22
|
+
13 => :to_i,
|
23
|
+
14 => :to_time,
|
24
|
+
247 => :to_i,
|
25
|
+
248 => :to_i
|
26
|
+
}
|
27
|
+
|
28
|
+
def convert_type(v, type)
|
29
|
+
v ? ((t = MYSQL_TYPES[type]) ? v.send(t) : v) : nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def columns(with_table = nil)
|
33
|
+
unless @columns
|
34
|
+
@column_types = []
|
35
|
+
@columns = fetch_fields.map do |f|
|
36
|
+
@column_types << f.type
|
37
|
+
(with_table ? (f.table + "." + f.name) : f.name).to_sym
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@columns
|
41
|
+
end
|
42
|
+
|
43
|
+
def each_hash(with_table=nil)
|
44
|
+
c = columns
|
45
|
+
while row = fetch_row
|
46
|
+
h = {}
|
47
|
+
c.each_with_index {|f, i| h[f] = convert_type(row[i], @column_types[i])}
|
48
|
+
yield h
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
7
53
|
module Sequel
|
8
54
|
module MySQL
|
9
|
-
|
10
55
|
class Database < Sequel::Database
|
11
56
|
set_adapter_scheme :mysql
|
12
57
|
|
13
58
|
def connect
|
14
|
-
Mysql.real_connect(@opts[:host], @opts[:user], @opts[:password],
|
59
|
+
conn = Mysql.real_connect(@opts[:host], @opts[:user], @opts[:password],
|
15
60
|
@opts[:database], @opts[:port])
|
61
|
+
conn.query_with_result = false
|
62
|
+
conn
|
63
|
+
end
|
64
|
+
|
65
|
+
def tables
|
66
|
+
@pool.hold do |conn|
|
67
|
+
conn.list_tables.map {|t| t.to_sym}
|
68
|
+
end
|
16
69
|
end
|
17
70
|
|
18
71
|
def dataset(opts = nil)
|
19
72
|
MySQL::Dataset.new(self, opts)
|
20
73
|
end
|
21
|
-
|
74
|
+
|
22
75
|
def execute(sql)
|
23
76
|
@logger.info(sql) if @logger
|
24
77
|
@pool.hold do |conn|
|
@@ -26,6 +79,14 @@ module Sequel
|
|
26
79
|
end
|
27
80
|
end
|
28
81
|
|
82
|
+
def query(sql)
|
83
|
+
@logger.info(sql) if @logger
|
84
|
+
@pool.hold do |conn|
|
85
|
+
conn.query(sql)
|
86
|
+
conn.use_result
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
29
90
|
def execute_insert(sql)
|
30
91
|
@logger.info(sql) if @logger
|
31
92
|
@pool.hold do |conn|
|
@@ -41,13 +102,69 @@ module Sequel
|
|
41
102
|
conn.affected_rows
|
42
103
|
end
|
43
104
|
end
|
44
|
-
|
45
|
-
def transaction
|
46
|
-
@pool.hold
|
105
|
+
|
106
|
+
def transaction
|
107
|
+
@pool.hold do |conn|
|
108
|
+
@transactions ||= []
|
109
|
+
if @transactions.include? Thread.current
|
110
|
+
return yield(conn)
|
111
|
+
end
|
112
|
+
conn.query(SQL_BEGIN)
|
113
|
+
begin
|
114
|
+
@transactions << Thread.current
|
115
|
+
result = yield(conn)
|
116
|
+
conn.query(SQL_COMMIT)
|
117
|
+
result
|
118
|
+
rescue => e
|
119
|
+
conn.query(SQL_ROLLBACK)
|
120
|
+
raise e
|
121
|
+
ensure
|
122
|
+
@transactions.delete(Thread.current)
|
123
|
+
end
|
124
|
+
end
|
47
125
|
end
|
48
126
|
end
|
49
127
|
|
50
128
|
class Dataset < Sequel::Dataset
|
129
|
+
def field_name(field)
|
130
|
+
f = field.is_a?(Symbol) ? field.to_field_name : field
|
131
|
+
if f =~ /^(([^\(]*)\(\*\))|\*$/
|
132
|
+
f
|
133
|
+
elsif f =~ /^([^\(]*)\(([^\*\)]*)\)$/
|
134
|
+
"#{$1}(`#{$2}`)"
|
135
|
+
elsif f =~ /^(.*) (DESC|ASC)$/
|
136
|
+
"`#{$1}` #{$2}"
|
137
|
+
else
|
138
|
+
"`#{f}`"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def literal(v)
|
143
|
+
case v
|
144
|
+
when true: '1'
|
145
|
+
when false: '0'
|
146
|
+
else
|
147
|
+
super
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# MySQL supports ORDER and LIMIT clauses in UPDATE statements.
|
152
|
+
def update_sql(values, opts = nil)
|
153
|
+
sql = super
|
154
|
+
|
155
|
+
opts = opts ? @opts.merge(opts) : @opts
|
156
|
+
|
157
|
+
if order = opts[:order]
|
158
|
+
sql << " ORDER BY #{field_list(order)}"
|
159
|
+
end
|
160
|
+
|
161
|
+
if limit = opts[:limit]
|
162
|
+
sql << " LIMIT #{limit}"
|
163
|
+
end
|
164
|
+
|
165
|
+
sql
|
166
|
+
end
|
167
|
+
|
51
168
|
def insert(*values)
|
52
169
|
@db.execute_insert(insert_sql(*values))
|
53
170
|
end
|
@@ -62,20 +179,16 @@ module Sequel
|
|
62
179
|
|
63
180
|
def fetch_rows(sql)
|
64
181
|
@db.synchronize do
|
65
|
-
|
182
|
+
r = @db.query(sql)
|
66
183
|
begin
|
67
|
-
|
68
|
-
|
184
|
+
@columns = r.columns
|
185
|
+
r.each_hash {|row| yield row}
|
69
186
|
ensure
|
70
|
-
|
187
|
+
r.free
|
71
188
|
end
|
72
189
|
end
|
73
190
|
self
|
74
191
|
end
|
75
|
-
|
76
|
-
def fetch_columns(result)
|
77
|
-
@columns = result.fetch_fields.map {|c| c.name.to_sym}
|
78
|
-
end
|
79
192
|
end
|
80
193
|
end
|
81
194
|
end
|
data/lib/sequel/postgres.rb
CHANGED
@@ -122,10 +122,6 @@ class String
|
|
122
122
|
nil
|
123
123
|
end
|
124
124
|
end
|
125
|
-
|
126
|
-
def postgres_to_time
|
127
|
-
Time.parse(self)
|
128
|
-
end
|
129
125
|
end
|
130
126
|
|
131
127
|
module Sequel
|
@@ -138,7 +134,7 @@ module Sequel
|
|
138
134
|
23 => :to_i,
|
139
135
|
700 => :to_f,
|
140
136
|
701 => :to_f,
|
141
|
-
1114 => :
|
137
|
+
1114 => :to_time
|
142
138
|
}
|
143
139
|
|
144
140
|
class Database < Sequel::Database
|
@@ -272,9 +268,6 @@ module Sequel
|
|
272
268
|
end
|
273
269
|
|
274
270
|
class Dataset < Sequel::Dataset
|
275
|
-
TRUE = "'t'".freeze
|
276
|
-
FALSE = "'f'".freeze
|
277
|
-
|
278
271
|
def literal(v)
|
279
272
|
case v
|
280
273
|
when String, Fixnum, Float, TrueClass, FalseClass: PGconn.quote(v)
|
@@ -283,14 +276,17 @@ module Sequel
|
|
283
276
|
end
|
284
277
|
end
|
285
278
|
|
286
|
-
LIKE = '%s ~ %s'.freeze
|
279
|
+
LIKE = '(%s ~ %s)'.freeze
|
287
280
|
LIKE_CI = '%s ~* %s'.freeze
|
288
281
|
|
289
282
|
def format_eq_expression(left, right)
|
290
283
|
case right
|
291
284
|
when Regexp:
|
292
|
-
|
293
|
-
|
285
|
+
l = field_name(left)
|
286
|
+
r = PGconn.quote(right.source)
|
287
|
+
right.casefold? ? \
|
288
|
+
"(#{l} ~* #{r})" : \
|
289
|
+
"(#{l} ~ #{r})"
|
294
290
|
else
|
295
291
|
super
|
296
292
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../lib/sequel/mysql')
|
2
|
+
|
3
|
+
MYSQL_DB = Sequel('mysql://root@localhost/sandbox')
|
4
|
+
if MYSQL_DB.table_exists?(:items)
|
5
|
+
MYSQL_DB.drop_table :items
|
6
|
+
end
|
7
|
+
MYSQL_DB.create_table :items do
|
8
|
+
text :name
|
9
|
+
integer :value
|
10
|
+
end
|
11
|
+
|
12
|
+
context "A MySQL dataset" do
|
13
|
+
setup do
|
14
|
+
@d = MYSQL_DB[:items]
|
15
|
+
@d.delete # remove all records
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should return the correct record count" do
|
19
|
+
@d.count.should == 0
|
20
|
+
@d << {:name => 'abc', :value => 123}
|
21
|
+
@d << {:name => 'abc', :value => 456}
|
22
|
+
@d << {:name => 'def', :value => 789}
|
23
|
+
@d.count.should == 3
|
24
|
+
end
|
25
|
+
|
26
|
+
# specify "should return the last inserted id when inserting records" do
|
27
|
+
# id = @d << {:name => 'abc', :value => 1.23}
|
28
|
+
# id.should == @d.first[:id]
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
|
32
|
+
specify "should return all records" do
|
33
|
+
@d << {:name => 'abc', :value => 123}
|
34
|
+
@d << {:name => 'abc', :value => 456}
|
35
|
+
@d << {:name => 'def', :value => 789}
|
36
|
+
|
37
|
+
@d.order(:value).all.should == [
|
38
|
+
{:name => 'abc', :value => 123},
|
39
|
+
{:name => 'abc', :value => 456},
|
40
|
+
{:name => 'def', :value => 789}
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
specify "should update records correctly" do
|
45
|
+
@d << {:name => 'abc', :value => 123}
|
46
|
+
@d << {:name => 'abc', :value => 456}
|
47
|
+
@d << {:name => 'def', :value => 789}
|
48
|
+
@d.filter(:name => 'abc').update(:value => 530)
|
49
|
+
|
50
|
+
# the third record should stay the same
|
51
|
+
# floating-point precision bullshit
|
52
|
+
@d[:name => 'def'][:value].should == 789
|
53
|
+
@d.filter(:value => 530).count.should == 2
|
54
|
+
end
|
55
|
+
|
56
|
+
specify "should delete records correctly" do
|
57
|
+
@d << {:name => 'abc', :value => 123}
|
58
|
+
@d << {:name => 'abc', :value => 456}
|
59
|
+
@d << {:name => 'def', :value => 789}
|
60
|
+
@d.filter(:name => 'abc').delete
|
61
|
+
|
62
|
+
@d.count.should == 1
|
63
|
+
@d.first[:name].should == 'def'
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should be able to literalize booleans" do
|
67
|
+
proc {@d.literal(true)}.should_not raise_error
|
68
|
+
proc {@d.literal(false)}.should_not raise_error
|
69
|
+
end
|
70
|
+
|
71
|
+
specify "should quote fields using back-ticks" do
|
72
|
+
@d.select(:name).sql.should == \
|
73
|
+
'SELECT `name` FROM items'
|
74
|
+
|
75
|
+
@d.select('COUNT(*)').sql.should == \
|
76
|
+
'SELECT COUNT(*) FROM items'
|
77
|
+
|
78
|
+
@d.select(:value.MAX).sql.should == \
|
79
|
+
'SELECT max(`value`) FROM items'
|
80
|
+
|
81
|
+
@d.order(:name.DESC).sql.should == \
|
82
|
+
'SELECT * FROM items ORDER BY `name` DESC'
|
83
|
+
|
84
|
+
@d.insert_sql(:value => 333).should == \
|
85
|
+
'INSERT INTO items (`value`) VALUES (333)'
|
86
|
+
end
|
87
|
+
|
88
|
+
specify "should support ORDER clause in UPDATE statements" do
|
89
|
+
@d.order(:name).update_sql(:value => 1).should == \
|
90
|
+
'UPDATE items SET `value` = 1 ORDER BY `name`'
|
91
|
+
end
|
92
|
+
|
93
|
+
specify "should support LIMIT clause in UPDATE statements" do
|
94
|
+
@d.limit(10).update_sql(:value => 1).should == \
|
95
|
+
'UPDATE items SET `value` = 1 LIMIT 10'
|
96
|
+
end
|
97
|
+
|
98
|
+
specify "should support transactions" do
|
99
|
+
MYSQL_DB.transaction do
|
100
|
+
@d << {:name => 'abc', :value => 1}
|
101
|
+
end
|
102
|
+
|
103
|
+
@d.count.should == 1
|
104
|
+
end
|
105
|
+
end
|
data/spec/core_ext_spec.rb
CHANGED
@@ -71,6 +71,13 @@ context "String#split_sql" do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
context "String#to_time" do
|
75
|
+
specify "should convert the string into a Time object" do
|
76
|
+
"2007-07-11".to_time.should == Time.parse("2007-07-11")
|
77
|
+
"06:30".to_time.should == Time.parse("06:30")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
74
81
|
context "Symbol#DESC" do
|
75
82
|
specify "should append the symbol with DESC" do
|
76
83
|
:hey.DESC.should == 'hey DESC'
|
data/spec/database_spec.rb
CHANGED
@@ -363,4 +363,83 @@ context "Database#uri_to_options" do
|
|
363
363
|
h[:port].should == 1234
|
364
364
|
h[:database].should == 'blah'
|
365
365
|
end
|
366
|
+
end
|
367
|
+
|
368
|
+
context "A single threaded database" do
|
369
|
+
teardown do
|
370
|
+
Sequel::Database.single_threaded = false
|
371
|
+
end
|
372
|
+
|
373
|
+
specify "should use a SingleThreadedPool instead of a ConnectionPool" do
|
374
|
+
db = Sequel::Database.new(:single_threaded => true)
|
375
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
376
|
+
end
|
377
|
+
|
378
|
+
specify "should be constructable using :single_threaded => true option" do
|
379
|
+
db = Sequel::Database.new(:single_threaded => true)
|
380
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
381
|
+
end
|
382
|
+
|
383
|
+
specify "should be constructable using Database.single_threaded = true" do
|
384
|
+
Sequel::Database.single_threaded = true
|
385
|
+
db = Sequel::Database.new
|
386
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context "A single threaded database" do
|
391
|
+
setup do
|
392
|
+
conn = 1234567
|
393
|
+
@db = Sequel::Database.new(:single_threaded => true) do
|
394
|
+
conn += 1
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
specify "should invoke connection_proc only once" do
|
399
|
+
@db.pool.hold {|c| c.should == 1234568}
|
400
|
+
@db.pool.hold {|c| c.should == 1234568}
|
401
|
+
end
|
402
|
+
|
403
|
+
specify "should convert an Exception into a RuntimeError" do
|
404
|
+
db = Sequel::Database.new(:single_threaded => true) do
|
405
|
+
raise Exception
|
406
|
+
end
|
407
|
+
|
408
|
+
proc {db.pool.hold {|c|}}.should raise_error(RuntimeError)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
context "A database" do
|
413
|
+
setup do
|
414
|
+
Sequel::Database.single_threaded = false
|
415
|
+
end
|
416
|
+
|
417
|
+
teardown do
|
418
|
+
Sequel::Database.single_threaded = false
|
419
|
+
end
|
420
|
+
|
421
|
+
specify "should be either single_threaded? or multi_threaded?" do
|
422
|
+
db = Sequel::Database.new(:single_threaded => true)
|
423
|
+
db.should be_single_threaded
|
424
|
+
db.should_not be_multi_threaded
|
425
|
+
|
426
|
+
db = Sequel::Database.new(:max_options => 1)
|
427
|
+
db.should_not be_single_threaded
|
428
|
+
db.should be_multi_threaded
|
429
|
+
|
430
|
+
db = Sequel::Database.new
|
431
|
+
db.should_not be_single_threaded
|
432
|
+
db.should be_multi_threaded
|
433
|
+
|
434
|
+
Sequel::Database.single_threaded = true
|
435
|
+
|
436
|
+
db = Sequel::Database.new
|
437
|
+
db.should be_single_threaded
|
438
|
+
db.should_not be_multi_threaded
|
439
|
+
|
440
|
+
db = Sequel::Database.new(:max_options => 4)
|
441
|
+
db.should be_single_threaded
|
442
|
+
db.should_not be_multi_threaded
|
443
|
+
|
444
|
+
end
|
366
445
|
end
|
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.1.
|
7
|
-
date: 2007-07-
|
6
|
+
version: 0.1.9
|
7
|
+
date: 2007-07-21 00:00:00 +03:00
|
8
8
|
summary: Concise ORM for Ruby.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -33,12 +33,14 @@ files:
|
|
33
33
|
- README
|
34
34
|
- Rakefile
|
35
35
|
- bin/sequel
|
36
|
+
- doc/rdoc
|
36
37
|
- spec/adapters
|
37
38
|
- spec/connection_pool_spec.rb
|
38
39
|
- spec/core_ext_spec.rb
|
39
40
|
- spec/database_spec.rb
|
40
41
|
- spec/dataset_spec.rb
|
41
42
|
- spec/expressions_spec.rb
|
43
|
+
- spec/adapters/mysql_spec.rb
|
42
44
|
- spec/adapters/sqlite_spec.rb
|
43
45
|
- lib/sequel
|
44
46
|
- lib/sequel.rb
|