og 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG +796 -664
  2. data/INSTALL +24 -24
  3. data/README +39 -32
  4. data/Rakefile +41 -42
  5. data/benchmark/bench.rb +36 -36
  6. data/doc/AUTHORS +15 -12
  7. data/doc/LICENSE +3 -3
  8. data/doc/RELEASES +311 -243
  9. data/doc/config.txt +1 -1
  10. data/examples/mysql_to_psql.rb +15 -15
  11. data/examples/run.rb +92 -92
  12. data/install.rb +7 -17
  13. data/lib/og.rb +76 -75
  14. data/lib/og/collection.rb +203 -160
  15. data/lib/og/entity.rb +168 -169
  16. data/lib/og/errors.rb +5 -5
  17. data/lib/og/manager.rb +179 -178
  18. data/lib/og/mixin/hierarchical.rb +107 -107
  19. data/lib/og/mixin/optimistic_locking.rb +36 -36
  20. data/lib/og/mixin/orderable.rb +148 -148
  21. data/lib/og/mixin/timestamped.rb +8 -8
  22. data/lib/og/mixin/tree.rb +124 -124
  23. data/lib/og/relation.rb +237 -213
  24. data/lib/og/relation/belongs_to.rb +5 -5
  25. data/lib/og/relation/has_many.rb +60 -58
  26. data/lib/og/relation/joins_many.rb +93 -47
  27. data/lib/og/relation/refers_to.rb +25 -21
  28. data/lib/og/store.rb +210 -207
  29. data/lib/og/store/filesys.rb +79 -79
  30. data/lib/og/store/kirby.rb +263 -258
  31. data/lib/og/store/memory.rb +261 -261
  32. data/lib/og/store/mysql.rb +288 -284
  33. data/lib/og/store/psql.rb +261 -244
  34. data/lib/og/store/sql.rb +873 -720
  35. data/lib/og/store/sqlite.rb +177 -175
  36. data/lib/og/store/sqlserver.rb +204 -214
  37. data/lib/og/types.rb +1 -1
  38. data/lib/og/validation.rb +57 -57
  39. data/lib/vendor/mysql.rb +376 -376
  40. data/lib/vendor/mysql411.rb +10 -10
  41. data/test/og/mixin/tc_hierarchical.rb +59 -59
  42. data/test/og/mixin/tc_optimistic_locking.rb +40 -40
  43. data/test/og/mixin/tc_orderable.rb +67 -67
  44. data/test/og/mixin/tc_timestamped.rb +19 -19
  45. data/test/og/store/tc_filesys.rb +46 -46
  46. data/test/og/tc_inheritance.rb +81 -81
  47. data/test/og/tc_join.rb +67 -0
  48. data/test/og/tc_polymorphic.rb +49 -49
  49. data/test/og/tc_relation.rb +57 -30
  50. data/test/og/tc_select.rb +49 -0
  51. data/test/og/tc_store.rb +345 -337
  52. data/test/og/tc_types.rb +11 -11
  53. metadata +11 -18
@@ -4,11 +4,11 @@ module Og
4
4
 
5
5
  class BelongsTo < RefersTo
6
6
 
7
- def enchant
8
- super
9
- target_class.meta :descendants, [owner_class, foreign_key]
10
- end
11
-
7
+ def enchant
8
+ super
9
+ target_class.meta :descendants, [owner_class, foreign_key]
10
+ end
11
+
12
12
  end
13
13
 
14
14
  end
@@ -4,6 +4,7 @@ require 'facet/string/underscore'
4
4
 
5
5
  require 'og/relation'
6
6
  require 'og/collection'
7
+ require 'og/relation/belongs_to'
7
8
 
8
9
  module Og
9
10
 
@@ -19,70 +20,71 @@ end
19
20
  # article.comments.size
20
21
 
21
22
  class HasMany < Relation
22
- =begin
23
- def initialize(args, options = {})
24
- super
23
+ def resolve_polymorphic
24
+ if target_class.relations
25
+ unless target_class.relations.find { |r| r.is_a?(BelongsTo) and r.target_class == owner_class }
26
+ target_class.belongs_to(owner_class)
27
+ end
28
+ end
29
+ end
25
30
 
26
- # TODO: clean this up.
27
-
28
- unless target_class.relations.find { |r| r.is_a?(BelongsTo) and r.target_class == owner_class }
29
- target_class.belongs_to(owner_class)
30
- end
31
- end
32
- =end
33
- def resolve_polymorphic
34
- if target_class.relations
35
- unless target_class.relations.find { |r| r.is_a?(BelongsTo) and r.target_class == owner_class }
36
- target_class.belongs_to(owner_class)
37
- end
38
- end
39
- end
31
+ def enchant
32
+ self[:owner_singular_name] = owner_class.to_s.demodulize.underscore.downcase
33
+ self[:target_singular_name] = target_plural_name.to_s.singular
34
+ self[:foreign_key] = "#{foreign_name || owner_singular_name}_#{owner_pk}"
35
+
36
+ owner_class.module_eval %{
37
+ attr_accessor :#{target_plural_name}
40
38
 
41
- def enchant
42
- self[:owner_singular_name] = owner_class.to_s.demodulize.underscore.downcase
43
- self[:target_singular_name] = target_plural_name.to_s.singular
44
- self[:foreign_key] = "#{foreign_name || owner_singular_name}_#{owner_pk}"
45
-
46
- owner_class.module_eval %{
47
- attr_accessor :#{target_plural_name}
39
+ def #{target_plural_name}(options = nil)
40
+ unless @#{target_plural_name}
41
+ @#{target_plural_name} = HasManyCollection.new(
42
+ self,
43
+ :add_#{target_singular_name},
44
+ :remove_#{target_singular_name},
45
+ :find_#{target_plural_name},
46
+ :count_#{target_plural_name},
47
+ options
48
+ )
49
+ end
50
+
51
+ @#{target_plural_name}.find_options = options
52
+ @#{target_plural_name}.reload(options) if options and options[:reload]
53
+ @#{target_plural_name}
54
+ end
48
55
 
49
- def #{target_plural_name}(options = nil)
50
- unless @#{target_plural_name}
51
- @#{target_plural_name} = HasManyCollection.new(
52
- self,
53
- :add_#{target_singular_name},
54
- :remove_#{target_singular_name},
55
- :find_#{target_plural_name},
56
- options
57
- )
58
- end
56
+ def add_#{target_singular_name}(obj, options = nil)
57
+ return unless obj
58
+ obj.#{foreign_key} = @#{owner_pk}
59
+ obj.save
60
+ end
59
61
 
60
- @#{target_plural_name}.reload(options) if options and options[:reload]
61
- @#{target_plural_name}
62
- end
63
-
64
- def add_#{target_singular_name}(obj)
65
- obj.#{foreign_key} = @#{owner_pk}
66
- obj.save
67
- end
68
-
69
- def remove_#{target_singular_name}(obj)
70
- obj.#{foreign_key} = nil
71
- end
72
-
73
- def find_#{target_plural_name}(options = {})
74
- find_options = {
75
- :condition => "#{foreign_key} = \#\{@#{owner_pk}\}"
76
- }
77
- find_options.update(options) if options
78
- #{"find_options.update(:order => #{options[:order].inspect})" if options[:order]}
79
- #{target_class}.find(find_options)
80
- end
81
- }
82
- end
62
+ def remove_#{target_singular_name}(obj)
63
+ obj.#{foreign_key} = nil
64
+ end
65
+
66
+ def find_#{target_plural_name}(options = {})
67
+ find_options = {
68
+ :condition => "#{foreign_key} = \#\{@#{owner_pk}\}"
69
+ }
70
+ if options
71
+ if condition = options.delete(:condition)
72
+ find_options[:condition] += " AND (\#{condition})"
73
+ end
74
+ find_options.update(options)
75
+ end
76
+ #{target_class}.find(find_options)
77
+ end
78
+
79
+ def count_#{target_plural_name}
80
+ #{target_class}.count(:condition => "#{foreign_key} = \#\{@#{owner_pk}\}")
81
+ end
82
+ }
83
+ end
83
84
 
84
85
  end
85
86
 
86
87
  end
87
88
 
88
- __END__
89
+ # * George Moschovitis <gm@navel.gr>
90
+ # * Guillaunne Pierronnet <guillaunne.pierronnet@laposte.net>
@@ -21,54 +21,100 @@ end
21
21
 
22
22
  class JoinsMany < Relation
23
23
 
24
- def enchant
25
- self[:owner_singular_name] = owner_class.to_s.demodulize.underscore.downcase
26
- self[:target_singular_name] = target_plural_name.to_s.singular
27
-
28
- store = owner_class.ogmanager.store
29
- join_table, oidx, tidx = store.join_table(owner_class, target_class)
30
- owner_class.meta :join_tables, join_table
31
-
32
- owner_class.module_eval %{
33
- attr_accessor :#{target_plural_name}
34
-
35
- def #{target_plural_name}(options = nil)
36
- reload = options and options[:reload]
37
-
38
- unless @#{target_plural_name}
39
- @#{target_plural_name} = JoinsManyCollection.new(
40
- self,
41
- :add_#{target_singular_name},
42
- :remove_#{target_singular_name},
43
- :find_#{target_plural_name}
44
- )
45
- end
46
-
47
- @#{target_plural_name}.reload(options) if options and options[:reload]
48
- @#{target_plural_name}
49
- end
50
-
51
- def add_#{target_singular_name}(obj)
52
- obj.save
53
- obj.class.ogmanager.store.join(self, obj, "#{join_table}")
54
- end
55
-
56
- def remove_#{target_singular_name}(obj)
57
- obj.class.ogmanager.store.unjoin(self, obj, "#{join_table}")
58
- end
59
-
60
- def find_#{target_plural_name}(options = {})
61
- find_options = {
62
- :join_table => "#{join_table}",
63
- :join_condition => "#{join_table}.key#{tidx}=#{store.table(target_class)}.oid",
64
- :condition => "#{join_table}.key#{oidx}=\#\{@#{owner_pk}\}"
65
- }
66
- find_options.update(options) if options
67
- #{target_class}.find(find_options)
68
- end
69
- }
70
- end
24
+ def enchant
25
+ self[:owner_singular_name] = owner_class.to_s.demodulize.underscore.downcase
26
+ self[:target_singular_name] = target_plural_name.to_s.singular
27
+
28
+ store = owner_class.ogmanager.store
29
+ join_table_info = store.join_table_info(owner_class, target_class)
30
+
31
+ if through = self[:through]
32
+ # A custom class is used for the join. Use the class
33
+ # table and don't create a new table.
34
+ through = resolve_symbol(through, owner_class) if through.is_a?(Symbol)
35
+ join_table = self[:join_table] = through.table
36
+ else
37
+ # Calculate the name of the join table
38
+ join_table = self[:join_table] = join_table_info[:table]
39
+ # Create a join table.
40
+ owner_class.meta :join_tables, join_table_info
41
+ end
42
+
43
+ owner_key = join_table_info[:owner_key]
44
+ target_key = join_table_info[:target_key]
45
+
46
+ owner_class.module_eval %{
47
+ attr_accessor :#{target_plural_name}
48
+
49
+ def #{target_plural_name}(options = nil)
50
+ reload = options and options[:reload]
51
+
52
+ unless @#{target_plural_name}
53
+ @#{target_plural_name} = JoinsManyCollection.new(
54
+ self,
55
+ :add_#{target_singular_name},
56
+ :remove_#{target_singular_name},
57
+ :find_#{target_plural_name},
58
+ :count_#{target_plural_name},
59
+ options
60
+ )
61
+ end
62
+
63
+ @#{target_plural_name}.find_options = options
64
+ @#{target_plural_name}.reload(options) if options and options[:reload]
65
+ @#{target_plural_name}
66
+ end
67
+
68
+ def add_#{target_singular_name}(obj, options = nil)
69
+ obj.save
70
+ obj.class.ogmanager.store.join(self, obj, "#{join_table}", options)
71
+ end
72
+
73
+ def remove_#{target_singular_name}(obj)
74
+ obj.class.ogmanager.store.unjoin(self, obj, "#{join_table}")
75
+ end
76
+
77
+ def find_#{target_plural_name}(options = {})
78
+ find_options = {
79
+ :join_table => "#{join_table}",
80
+ :join_condition => "#{join_table}.#{target_key}=#{store.table(target_class)}.oid",
81
+ :condition => "#{join_table}.#{owner_key}=\#\{@#{owner_pk}\}"
82
+ }
83
+ if options
84
+ if condition = options.delete(:condition)
85
+ find_options[:condition] += " AND (\#{condition})"
86
+ end
87
+ find_options.update(options)
88
+ end
89
+ #{target_class}.find(find_options)
90
+ end
91
+
92
+ #--
93
+ # TODO: optimize this!!
94
+ #++
95
+
96
+ def count_#{target_plural_name}
97
+ find_options = {
98
+ :join_table => "#{join_table}",
99
+ :join_condition => "#{join_table}.#{target_key}=#{store.table(target_class)}.oid",
100
+ :condition => "#{join_table}.#{owner_key}=\#\{@#{owner_pk}\}"
101
+ }
102
+ #{target_class}.find(find_options).size
103
+ end
104
+ }
105
+
106
+ if through
107
+ owner_class.module_eval %{
108
+ def #{target_singular_name}_join_data(t)
109
+ #{through}.find_one(:condition => "#{owner_key}=\#{@#{owner_pk}} and #{target_key}=\#{t.pk}")
110
+ end
111
+ }
112
+ end
113
+ end
71
114
 
72
115
  end
73
116
 
74
117
  end
118
+
119
+ # * George Moschovitis <gm@navel.gr>
120
+ # * Ysabel <deb@ysabel.org>
@@ -4,28 +4,32 @@ module Og
4
4
 
5
5
  class RefersTo < Relation
6
6
 
7
- def enchant
8
- self[:foreign_key] = "#{foreign_name || target_singular_name}_#{target_pk}"
9
-
10
- owner_class.module_eval %{
11
- attr_accessor :#{target_singular_name}
12
- prop_accessor :#{foreign_key}, #{target_pkclass}
13
-
14
- def #{target_singular_name}(reload = false)
15
- unless reload
16
- @#{target_singular_name} = #{target_class}[@#{foreign_key}] unless @#{target_singular_name}
17
- return @#{target_singular_name}
18
- else
19
- return #{target_class}[@#{foreign_key}]
20
- end
21
- end
22
-
23
- def #{target_singular_name}=(obj)
24
- @#{foreign_key} = obj.#{target_pk}
25
- end
26
- }
27
- end
7
+ def enchant
8
+ self[:foreign_key] = "#{foreign_name || target_singular_name}_#{target_pk}"
9
+
10
+ owner_class.module_eval %{
11
+ attr_accessor :#{target_singular_name}
12
+ prop_accessor :#{foreign_key}, #{target_pkclass}
13
+
14
+ def #{target_singular_name}(reload = false)
15
+ return nil if @#{foreign_key}.nil?
16
+
17
+ # will reload if forced or first load or
18
+ if reload or not @#{target_singular_name}
19
+ @#{target_singular_name} = #{target_class}[@#{foreign_key}]
20
+ end
21
+ @#{target_singular_name}
22
+ end
23
+
24
+ def #{target_singular_name}=(obj)
25
+ @#{foreign_key} = obj.#{target_pk} if obj
26
+ end
27
+ }
28
+ end
28
29
 
29
30
  end
30
31
 
31
32
  end
33
+
34
+ # * George Moschovitis <gm@navel.gr>
35
+ # * Michael Neumann <mneumann@ntecs.de>
@@ -3,223 +3,226 @@ module Og
3
3
  # A Store is responsible for the peristance of the ObjectGraph.
4
4
 
5
5
  class Store
6
-
7
- # Options.
8
-
9
- attr_accessor :options
10
-
11
- # Transaction nesting.
12
-
13
- attr_accessor :transaction_nesting
6
+
7
+ # Options.
8
+
9
+ attr_accessor :options
10
+
11
+ # Transaction nesting.
12
+
13
+ attr_accessor :transaction_nesting
14
14
 
15
- # :section: Store methods.
15
+ # :section: Store methods.
16
16
 
17
- # Return the store for the given name.
17
+ # Return the store for the given name.
18
18
 
19
- def self.for_name(name)
20
- # gmosx: to keep RDoc happy.
19
+ def self.for_name(name)
20
+ # gmosx: to keep RDoc happy.
21
21
  eval %{
22
- require 'og/store/#{name}'
23
- return #{name.to_s.capitalize}Store
24
- }
25
- end
26
-
27
- # Creates a store.
28
-
29
- def self.create(options)
30
- end
31
-
32
- # Destroys a store.
33
-
34
- def self.destroy(options)
35
- end
36
-
37
- # :section: Misc methods.
38
-
39
- # Create a session to the store.
40
-
41
- def initialize(options)
42
- @options = options
43
- @transaction_nesting = 0
44
- end
45
-
46
- # Close the session to the store.
47
-
48
- def close
49
- end
50
-
51
- # Enchants a class.
52
-
53
- def enchant(klass, manager)
54
- klass.class.send(:define_method, :index) do |arg|
55
- meta :index, arg
56
- end
57
-
58
- pk = klass.primary_key.first
59
-
60
- klass.module_eval %{
61
- def saved?
62
- return @#{klass.primary_key.first}
63
- end
64
-
65
- def unsaved?
66
- return !@#{klass.primary_key.first}
67
- end
68
-
69
- # Evaluate an alias for the primary key.
70
-
71
- alias_method :pk, :#{pk}
72
- alias_method :pk=, :#{pk}=
73
-
74
- def self.pk_symbol
75
- :#{klass.primary_key.first}
76
- end
77
- }
78
-
79
- # Generate finder methods.
80
-
81
- code = ''
82
-
83
- for p in klass.properties
84
- # gmosx: :uniq does NOT set a unique constrain in the
85
- # database.
86
- finder = p.meta[:uniq] || p.meta[:unique] ? 'find_one' : 'find'
87
-
88
- code << %{
89
- def self.find_by_#{p.symbol}(val, operator = '=', options = {})
90
- options.update(
91
- :class => #{klass},
92
- :condition => "#{p.symbol}\#{operator}\#{ogmanager.store.quote(val)}"
93
- )
94
- ogmanager.store.#{finder}(options)
95
- end;
96
- }
97
- end
98
-
99
- klass.module_eval(code)
100
- end
101
-
102
- # :section: Lifecycle methods.
103
-
104
- # Loads an object from the store using the primary key.
105
-
106
- def load(pk, klass)
107
- end
108
-
109
- # Reloads an object from the store.
110
-
111
- def reload(obj)
112
- end
113
-
114
- # Save an object to store. Insert if this is a new object or
115
- # update if this is already inserted in the database.
116
-
117
- def save(obj, options = nil)
118
- if obj.saved?
119
- obj.og_update(self, options)
120
- else
121
- obj.og_insert(self)
122
- end
123
- end
124
- alias_method :<<, :save
125
-
126
- # Insert an object in the store.
127
-
128
- def insert(obj)
129
- obj.og_insert(self)
130
- end
131
-
132
- # Update an object in the store.
133
-
134
- def update(obj, options = nil)
135
- obj.og_update(self, options)
136
- end
137
-
138
- # Update selected properties of an object or class of
139
- # objects.
140
-
141
- def update_properties(obj_or_class, props, options = nil)
142
- end
143
- alias_method :pupdate, :update_properties
144
- alias_method :update_property, :update_properties
145
-
146
- # Permanently delete an object from the store.
147
-
148
- def delete(obj_or_pk, klass = nil, cascade = true)
149
- unless obj_or_pk.is_a?(EntityMixin)
150
- # create a dummy instance to keep the og_delete
151
- # method as an instance method like the other lifecycle
152
- # methods.
153
- klass.allocate.og_delete(self, obj_or_pk, cascade)
154
- else
155
- obj_or_pk.og_delete(self, nil, cascade)
156
- end
157
- end
158
-
159
- # Perform a query.
160
-
161
- def find(klass, options)
162
- end
163
-
164
- # Count the results returned by the query.
165
-
166
- def count(options)
167
- end
168
-
169
- # :section: Transaction methods.
170
-
171
- # Start a new transaction.
172
-
173
- def start
174
- raise 'Not implemented'
175
- true if @transaction_nesting < 1
176
- @transaction_nesting += 1
177
- end
178
-
179
- # Commit a transaction.
180
-
181
- def commit
182
- raise 'Not implemented'
183
- @transaction_nesting -= 1
184
- true if @transaction_nesting < 1
185
- end
186
-
187
- # Rollback a transaction.
188
-
189
- def rollback
190
- @transaction_nesting -= 1
191
- true if @transaction_nesting < 1
192
- end
193
-
194
- # Transaction helper. In the transaction block use
195
- # the db pointer to the backend.
196
-
197
- def transaction(&block)
198
- begin
199
- start
200
- yield(self)
201
- commit
202
- rescue => ex
203
- Logger.error 'Error in transaction'
204
- Logger.error ex
205
- Logger.error ex.backtrace
206
- rollback
207
- end
208
- end
22
+ require 'og/store/#{name}'
23
+ return #{name.to_s.capitalize}Store
24
+ }
25
+ end
26
+
27
+ # Creates a store.
28
+
29
+ def self.create(options)
30
+ end
31
+
32
+ # Destroys a store.
33
+
34
+ def self.destroy(options)
35
+ end
36
+
37
+ # :section: Misc methods.
38
+
39
+ # Create a session to the store.
40
+
41
+ def initialize(options)
42
+ @options = options
43
+ @transaction_nesting = 0
44
+ end
45
+
46
+ # Close the session to the store.
47
+
48
+ def close
49
+ end
50
+
51
+ # Enchants a class.
52
+
53
+ def enchant(klass, manager)
54
+ klass.class.send(:define_method, :index) do |arg|
55
+ meta :index, arg
56
+ end
57
+
58
+ pk = klass.primary_key.first
59
+
60
+ klass.module_eval %{
61
+ def saved?
62
+ return @#{klass.primary_key.first}
63
+ end
64
+
65
+ def unsaved?
66
+ return !@#{klass.primary_key.first}
67
+ end
68
+
69
+ # Evaluate an alias for the primary key.
70
+
71
+ alias_method :pk, :#{pk}
72
+ alias_method :pk=, :#{pk}=
73
+
74
+ def self.pk_symbol
75
+ :#{klass.primary_key.first}
76
+ end
77
+ }
78
+
79
+ # Generate finder methods.
80
+
81
+ code = ''
82
+
83
+ for p in klass.properties
84
+ # gmosx: :uniq does NOT set a unique constrain in the
85
+ # database.
86
+ finder = p.meta[:uniq] || p.meta[:unique] ? 'find_one' : 'find'
87
+
88
+ code << %{
89
+ def self.find_by_#{p.symbol}(val, operator = '=', options = {})
90
+ options.update(
91
+ :class => #{klass},
92
+ :condition => "#{p.symbol}\#{operator}\#{ogmanager.store.quote(val)}"
93
+ )
94
+ ogmanager.store.#{finder}(options)
95
+ end;
96
+ }
97
+ end
98
+
99
+ klass.module_eval(code)
100
+ end
101
+
102
+ # :section: Lifecycle methods.
103
+
104
+ # Loads an object from the store using the primary key.
105
+
106
+ def load(pk, klass)
107
+ end
108
+
109
+ # Reloads an object from the store.
110
+
111
+ def reload(obj)
112
+ end
113
+
114
+ # Save an object to store. Insert if this is a new object or
115
+ # update if this is already inserted in the database.
116
+
117
+ def save(obj, options = nil)
118
+ if obj.saved?
119
+ obj.og_update(self, options)
120
+ else
121
+ obj.og_insert(self)
122
+ end
123
+ end
124
+ alias_method :<<, :save
125
+
126
+ # Insert an object in the store.
127
+
128
+ def insert(obj)
129
+ obj.og_insert(self)
130
+ end
131
+
132
+ # Update an object in the store.
133
+
134
+ def update(obj, options = nil)
135
+ obj.og_update(self, options)
136
+ end
137
+
138
+ # Update selected properties of an object or class of
139
+ # objects.
140
+
141
+ def update_properties(obj_or_class, props, options = nil)
142
+ end
143
+ alias_method :pupdate, :update_properties
144
+ alias_method :update_property, :update_properties
145
+
146
+ # Permanently delete an object from the store.
147
+
148
+ def delete(obj_or_pk, klass = nil, cascade = true)
149
+ unless obj_or_pk.is_a?(EntityMixin)
150
+ # create a dummy instance to keep the og_delete
151
+ # method as an instance method like the other lifecycle
152
+ # methods.
153
+ klass.allocate.og_delete(self, obj_or_pk, cascade)
154
+ else
155
+ obj_or_pk.og_delete(self, nil, cascade)
156
+ end
157
+ end
158
+
159
+ # Perform a query.
160
+
161
+ def find(klass, options)
162
+ end
163
+
164
+ # Count the results returned by the query.
165
+
166
+ def count(options)
167
+ end
168
+
169
+ # :section: Transaction methods.
170
+
171
+ # Start a new transaction.
172
+
173
+ def start
174
+ raise 'Not implemented'
175
+ true if @transaction_nesting < 1
176
+ @transaction_nesting += 1
177
+ end
178
+
179
+ # Commit a transaction.
180
+
181
+ def commit
182
+ raise 'Not implemented'
183
+ @transaction_nesting -= 1
184
+ true if @transaction_nesting < 1
185
+ end
186
+
187
+ # Rollback a transaction.
188
+
189
+ def rollback
190
+ @transaction_nesting -= 1
191
+ true if @transaction_nesting < 1
192
+ end
193
+
194
+ # Transaction helper. In the transaction block use
195
+ # the db pointer to the backend.
196
+
197
+ def transaction(&block)
198
+ begin
199
+ start
200
+ yield(self)
201
+ commit
202
+ rescue => ex
203
+ Logger.error 'Error in transaction'
204
+ Logger.error ex
205
+ Logger.error ex.backtrace
206
+ rollback
207
+ end
208
+ end
209
209
 
210
210
  private
211
211
 
212
- def eval_og_insert(klass)
213
- end
212
+ def eval_og_insert(klass)
213
+ end
214
214
 
215
- def eval_og_update(klass)
216
- end
215
+ def eval_og_update(klass)
216
+ end
217
217
 
218
- def eval_og_read(klass)
219
- end
218
+ def eval_og_read(klass)
219
+ end
220
220
 
221
- def eval_og_delete(klass)
222
- end
221
+ def eval_og_delete(klass)
222
+ end
223
+
224
+ def eval_og_create_schema(klass)
225
+ end
223
226
  end
224
227
 
225
228
  end