rhubarb 0.2.3 → 0.2.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/CHANGES +12 -1
- data/VERSION +1 -1
- data/lib/rhubarb/classmixins.rb +23 -6
- data/lib/rhubarb/persisting.rb +8 -1
- data/test/test_rhubarb.rb +35 -0
- metadata +28 -13
data/CHANGES
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
version 0.2.
|
1
|
+
version 0.2.4
|
2
|
+
|
3
|
+
* More aggressive use of prepared statements, which should result
|
4
|
+
in more speedups. (In particular, finding tuples by identity now
|
5
|
+
uses a prepared statement.)
|
6
|
+
|
7
|
+
* Persisting#to_hash method added.
|
8
|
+
|
9
|
+
* delete_where method added to persisting classes; it enables deleting
|
10
|
+
many rows satisfying some criterion in a single query.
|
11
|
+
|
12
|
+
version 0.2.3 (20bee926a142d505441716762a72a82cbfb87378)
|
2
13
|
|
3
14
|
* Rhubarb now uses prepared statements almost exclusively. This
|
4
15
|
should result in an appreciable speedup (I observed around 10% on
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.4
|
data/lib/rhubarb/classmixins.rb
CHANGED
@@ -68,7 +68,19 @@ module Rhubarb
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def delete_all
|
71
|
-
|
71
|
+
da_text = "DELETE from #{table_name}"
|
72
|
+
da_stmt = (db.stmts[da_text] ||= db.prepare(da_text))
|
73
|
+
da_stmt.execute!
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete_where(arg_hash)
|
77
|
+
arg_hash = arg_hash.dup
|
78
|
+
valid_cols = self.colnames.intersection arg_hash.keys
|
79
|
+
select_criteria = valid_cols.map {|col| "#{col.to_s} = #{col.inspect}"}.join(" AND ")
|
80
|
+
arg_hash.each {|k,v| arg_hash[k] = v.row_id if v.respond_to? :row_id}
|
81
|
+
dw_text = "DELETE FROM #{table_name} WHERE #{select_criteria}"
|
82
|
+
dw_stmt = (db.stmts[dw_text] ||= db.prepare(dw_text))
|
83
|
+
dw_stmt.execute!(arg_hash)
|
72
84
|
end
|
73
85
|
|
74
86
|
# Declares a query method named +name+ and adds it to this class. The query method returns a list of objects corresponding to the rows returned by executing "+SELECT * FROM+ _table_ +WHERE+ _query_" on the database.
|
@@ -109,7 +121,7 @@ module Rhubarb
|
|
109
121
|
|
110
122
|
find_method_name = "find_by_#{cname}".to_sym
|
111
123
|
find_first_method_name = "find_first_by_#{cname}".to_sym
|
112
|
-
find_query = "select * from #{table_name} where #{cname} = ?"
|
124
|
+
find_query = "select * from #{table_name} where #{cname} = ? order by row_id"
|
113
125
|
|
114
126
|
get_method_name = "#{cname}".to_sym
|
115
127
|
set_method_name = "#{cname}=".to_sym
|
@@ -124,13 +136,16 @@ module Rhubarb
|
|
124
136
|
klass = (class << self; self end)
|
125
137
|
klass.class_eval do
|
126
138
|
define_method find_method_name do |arg|
|
127
|
-
|
139
|
+
fq_stmt = (self.db.stmts[find_query] ||= db.prepare(find_query))
|
140
|
+
res = fq_stmt.execute!(arg)
|
128
141
|
res.map {|row| self.new(row)}
|
129
142
|
end
|
130
143
|
|
131
144
|
define_method find_first_method_name do |arg|
|
132
|
-
|
133
|
-
|
145
|
+
fq_stmt = (self.db.stmts[find_query] ||= db.prepare(find_query))
|
146
|
+
result = nil
|
147
|
+
fq_stmt.execute!(arg) {|row| result = self.new(row) ; break }
|
148
|
+
result
|
134
149
|
end
|
135
150
|
end
|
136
151
|
|
@@ -281,7 +296,9 @@ module Rhubarb
|
|
281
296
|
end
|
282
297
|
|
283
298
|
def find_tuple(tid)
|
284
|
-
|
299
|
+
ft_text = "select * from #{table_name} where row_id = ?"
|
300
|
+
ft_stmt = (self.db.stmts[ft_text] ||= db.prepare(ft_text))
|
301
|
+
return ft_stmt.execute!(tid)[0]
|
285
302
|
end
|
286
303
|
|
287
304
|
include FindFreshest
|
data/lib/rhubarb/persisting.rb
CHANGED
@@ -70,6 +70,14 @@ module Rhubarb
|
|
70
70
|
@row_id = nil
|
71
71
|
end
|
72
72
|
|
73
|
+
def to_hash
|
74
|
+
result = {}
|
75
|
+
@tuple.each_pair do |key, value|
|
76
|
+
result[key.to_sym] = value unless key.class == Fixnum
|
77
|
+
end
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
73
81
|
## Begin private methods
|
74
82
|
|
75
83
|
private
|
@@ -132,6 +140,5 @@ module Rhubarb
|
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
135
|
-
|
136
143
|
end
|
137
144
|
end
|
data/test/test_rhubarb.rb
CHANGED
@@ -171,6 +171,41 @@ class BackendBasicTests < Test::Unit::TestCase
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
174
|
+
|
175
|
+
def test_to_hash
|
176
|
+
(0..5).each do |foo|
|
177
|
+
("A".."C").each do |bar|
|
178
|
+
TestClass.create(:foo=>foo, :bar=>bar)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
TestClass.find_all.each do |tc|
|
183
|
+
tch = tc.to_hash
|
184
|
+
[:foo,:bar,:created,:updated].each do |msg|
|
185
|
+
assert_equal(tch[msg], tc.send(msg))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_delete_where
|
191
|
+
(0..10).each do |foo|
|
192
|
+
("A".."G").each do |bar|
|
193
|
+
TestClass.create(:foo=>foo, :bar=>bar)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
old_count = TestClass.count
|
198
|
+
|
199
|
+
TestClass.delete_where(:foo=>1, :bar=>"B")
|
200
|
+
|
201
|
+
assert_equal(old_count - 1, TestClass.count)
|
202
|
+
assert_equal([], TestClass.find_by(:foo=>1, :bar=>"B"))
|
203
|
+
|
204
|
+
TestClass.delete_where(:bar=>"C")
|
205
|
+
assert_equal(old_count - 12, TestClass.count)
|
206
|
+
assert_equal([], TestClass.find_by(:bar=>"C"))
|
207
|
+
|
208
|
+
end
|
174
209
|
|
175
210
|
def test_instance_methods_dont_include_class_methods
|
176
211
|
["foo", "bar"].each do |prefix|
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhubarb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 4
|
9
|
+
version: 0.2.4
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- William Benton
|
@@ -9,29 +14,37 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-23 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rspec
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
23
31
|
version: 1.2.9
|
24
|
-
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: sqlite3-ruby
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
38
|
requirements:
|
31
39
|
- - ">="
|
32
40
|
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 2
|
44
|
+
- 2
|
33
45
|
version: 1.2.2
|
34
|
-
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
35
48
|
description: Rhubarb is a simple object-graph persistence library implemented as a mixin. It also works with the SPQR library for straightforward object publishing over QMF.
|
36
49
|
email: willb@redhat.com
|
37
50
|
executables: []
|
@@ -75,18 +88,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
88
|
requirements:
|
76
89
|
- - ">="
|
77
90
|
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
78
93
|
version: "0"
|
79
|
-
version:
|
80
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
95
|
requirements:
|
82
96
|
- - ">="
|
83
97
|
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
84
100
|
version: "0"
|
85
|
-
version:
|
86
101
|
requirements: []
|
87
102
|
|
88
103
|
rubyforge_project:
|
89
|
-
rubygems_version: 1.3.
|
104
|
+
rubygems_version: 1.3.6
|
90
105
|
signing_key:
|
91
106
|
specification_version: 3
|
92
107
|
summary: "Rhubarb: object graph persistence, easy as pie"
|