og 0.20.0 → 0.21.0

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.
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