sequel 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|