rhubarb 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,4 +1,15 @@
1
- version 0.2.3
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.3
1
+ 0.2.4
@@ -68,7 +68,19 @@ module Rhubarb
68
68
  end
69
69
 
70
70
  def delete_all
71
- self.db.execute("DELETE from #{table_name}")
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
- res = self.db.execute(find_query, arg)
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
- res = self.db.get_first_row(find_query, arg)
133
- res ? self.new(res) : nil
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
- self.db.get_first_row("select * from #{table_name} where row_id = ?", tid)
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
@@ -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
- version: 0.2.3
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-02-26 00:00:00 -06:00
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
- type: :development
18
- version_requirement:
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
- version:
32
+ type: :development
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: sqlite3-ruby
27
- type: :runtime
28
- version_requirement:
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
- version:
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.5
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"