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
@@ -9,152 +9,176 @@ module Og
9
9
 
10
10
  class Relation
11
11
 
12
- attr_accessor :options
13
-
14
- attr_accessor :is_polymorphic
15
-
16
- # A generalized initialize method for all relations.
17
- # Contains common setup code.
18
-
19
- def initialize(args, options = {})
20
- @options = options
21
- @options.update(args.pop) if args.last.is_a?(Hash)
22
-
23
- if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
24
- raise 'Class of target not defined'
25
- end
26
-
27
- @options[:target_class] = args.pop
28
-
29
- if target_class == Object
30
- # If the target class is just an Object mark that class
31
- # as a polymorphic parent class.
32
- # This class acts as template
33
- # to generate customized versions of this class.
34
-
35
- owner_class.meta(:polymorphic, owner_class)
36
- elsif target_class.respond_to?(:metadata) and target_class.metadata.polymorphic
37
- # If the target class is polymorphic, create a specialized
38
- # version of the class enclosed in the owner namespace.
39
-
40
- target_dm = target_class.to_s.demodulize
41
- owner_class.module_eval %{
42
- class #{owner_class}::#{target_dm} < #{target_class}
43
- end
44
- }
45
- eval %{
46
- @options[:target_class] = #{owner_class}::#{target_dm}
47
- }
48
- end
49
-
50
- target_name = if collection
51
- :target_plural_name
52
- else
53
- :target_singular_name
54
- end
55
-
56
- # Inflect the relation name.
57
-
58
- unless args.empty?
59
- @options[target_name] = args.first
60
- else
61
- @options[target_name] = if collection
62
- target_class.to_s.demodulize.underscore.downcase.plural.intern
63
- else
64
- target_class.to_s.demodulize.underscore.downcase.intern
65
- end
66
- end
67
-
68
- @options[:name] = options[target_name]
69
- end
70
-
71
- def [](key)
72
- @options[key]
73
- end
74
-
75
- def []=(key, val)
76
- @options[key] = val
77
- end
78
-
79
- # Is the relation polymorphic?
80
-
81
- def polymorphic?
82
- target_class == Object
83
- end
84
-
85
- #--
86
- # gmosx, TODO: remove, this is not really needed.
87
- #++
88
-
89
- def resolve_options
90
- @options[:owner_pk], @options[:owner_pkclass] = owner_class.primary_key
91
- if target_class.respond_to?(:primary_key)
92
- @options[:target_pk], @options[:target_pkclass] = target_class.primary_key
93
- end
94
- end
95
-
96
- # To avoid forward declarations, references to undefined
97
- # (at the time of the creation of the relation) classes are
98
- # stored as symbols. These symbols are resolved by this
99
- # method.
100
- #--
101
- # FIXME: do something more elegant here.
102
- #++
103
-
104
- def resolve_target
105
- if target_class.is_a?(Symbol)
106
- c = owner_class.name.dup
107
- c = "::" + c unless c =~ /::/
108
- c.gsub!(/::.*$/, '::')
109
- c << target_class.to_s
110
- begin
111
- klass = constant(c)
112
- rescue
113
- unless c == target_class
114
- c = target_class
115
- retry
116
- end
117
- end
118
- @options[:target_class] = klass
119
- end
120
- end
121
-
122
- # Resolve a polymorphic target class.
123
- # Overrided in subclasses.
124
-
125
- def resolve_polymorphic
126
- end
127
-
128
- # This method is implemented in subclasses.
129
-
130
- def enchant
131
- end
132
-
133
- # Access the hash values as methods.
134
-
135
- def method_missing(sym, *args)
136
- return @options[sym]
137
- end
138
-
139
- class << self
140
-
141
- def resolve(klass, action)
142
- if klass.__meta[:relations]
143
- for relation in klass.__meta[:relations]
144
- relation.send(action)
145
- end
146
- end
147
- end
148
-
149
- def enchant(klass)
150
- if klass.__meta[:relations]
151
- for relation in klass.__meta[:relations]
152
- relation.enchant unless relation.target_class == Object
153
- end
154
- end
155
- end
156
-
157
- end
12
+ attr_accessor :options
13
+
14
+ attr_accessor :is_polymorphic
15
+
16
+ # A generalized initialize method for all relations.
17
+ # Contains common setup code.
18
+
19
+ def initialize(args, options = {})
20
+ @options = options
21
+ @options.update(args.pop) if args.last.is_a?(Hash)
22
+
23
+ if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
24
+ raise 'Class of target not defined'
25
+ end
26
+
27
+ @options[:target_class] = args.pop
28
+
29
+ if target_class == Object
30
+ # If the target class is just an Object mark that class
31
+ # as a polymorphic parent class.
32
+ # This class acts as template
33
+ # to generate customized versions of this class.
34
+
35
+ owner_class.meta(:polymorphic, owner_class)
36
+ elsif target_class.respond_to?(:metadata) and target_class.metadata.polymorphic
37
+ # If the target class is polymorphic, create a specialized
38
+ # version of the class enclosed in the owner namespace.
39
+
40
+ target_dm = target_class.to_s.demodulize
41
+ owner_class.module_eval %{
42
+ class #{owner_class}::#{target_dm} < #{target_class}
43
+ end
44
+ }
45
+ eval %{
46
+ @options[:target_class] = #{owner_class}::#{target_dm}
47
+ }
48
+ end
49
+
50
+ target_name = if collection
51
+ :target_plural_name
52
+ else
53
+ :target_singular_name
54
+ end
55
+
56
+ # Inflect the relation name.
57
+
58
+ unless args.empty?
59
+ @options[target_name] = args.first
60
+ else
61
+ @options[target_name] = if collection
62
+ target_class.to_s.demodulize.underscore.downcase.plural.intern
63
+ else
64
+ target_class.to_s.demodulize.underscore.downcase.intern
65
+ end
66
+ end
67
+
68
+ @options[:name] = options[target_name]
69
+ end
70
+
71
+ def [](key)
72
+ @options[key]
73
+ end
74
+
75
+ def []=(key, val)
76
+ @options[key] = val
77
+ end
78
+
79
+ # Is the relation polymorphic?
80
+
81
+ def polymorphic?
82
+ target_class == Object
83
+ end
84
+
85
+ #--
86
+ # gmosx, TODO: remove, this is not really needed.
87
+ #++
88
+
89
+ def resolve_options
90
+ @options[:owner_pk], @options[:owner_pkclass] = owner_class.primary_key
91
+ if target_class.respond_to?(:primary_key)
92
+ @options[:target_pk], @options[:target_pkclass] = target_class.primary_key
93
+ end
94
+ end
95
+
96
+ # To avoid forward declarations, references to undefined
97
+ # (at the time of the creation of the relation) classes are
98
+ # stored as symbols. These symbols are resolved by this
99
+ # method.
100
+ #--
101
+ # FIXME: do something more elegant here.
102
+ #++
103
+
104
+ def resolve_symbol(sym, owner_class)
105
+ c = owner_class.name.dup
106
+ c = "::" + c unless c =~ /::/
107
+ c.gsub!(/::.*$/, '::')
108
+ c << sym.to_s
109
+ begin
110
+ return constant(c)
111
+ rescue
112
+ unless c == sym
113
+ c = sym
114
+ retry
115
+ end
116
+ end
117
+ end
118
+
119
+ def resolve_target
120
+ if target_class.is_a?(Symbol)
121
+ klass = resolve_symbol(target_class, owner_class)
122
+ @options[:target_class] = klass
123
+ end
124
+ end
125
+
126
+ =begin
127
+ def resolve_target
128
+ if target_class.is_a?(Symbol)
129
+ c = owner_class.name.dup
130
+ c = "::" + c unless c =~ /::/
131
+ c.gsub!(/::.*$/, '::')
132
+ c << target_class.to_s
133
+ begin
134
+ klass = constant(c)
135
+ rescue
136
+ unless c == target_class
137
+ c = target_class
138
+ retry
139
+ end
140
+ end
141
+ @options[:target_class] = klass
142
+ end
143
+ end
144
+ =end
145
+
146
+ # Resolve a polymorphic target class.
147
+ # Overrided in subclasses.
148
+
149
+ def resolve_polymorphic
150
+ end
151
+
152
+ # This method is implemented in subclasses.
153
+
154
+ def enchant
155
+ end
156
+
157
+ # Access the hash values as methods.
158
+
159
+ def method_missing(sym, *args)
160
+ return @options[sym]
161
+ end
162
+
163
+ class << self
164
+
165
+ def resolve(klass, action)
166
+ if klass.__meta[:relations]
167
+ for relation in klass.__meta[:relations]
168
+ relation.send(action)
169
+ end
170
+ end
171
+ end
172
+
173
+ def enchant(klass)
174
+ if klass.__meta[:relations]
175
+ for relation in klass.__meta[:relations]
176
+ relation.enchant unless relation.target_class == Object
177
+ end
178
+ end
179
+ end
180
+
181
+ end
158
182
 
159
183
  end
160
184
 
@@ -162,73 +186,73 @@ end
162
186
  # relations.
163
187
 
164
188
  module RelationMacros
165
- def self.append_features(base)
166
- super
167
- base.extend(ClassMethods)
168
- end
169
-
170
- module ClassMethods
171
-
172
- # === Examples
173
- #
174
- # belongs_to Article
175
- # belongs_to :article, Article
176
- # belongs_to :article, Article, :view => 'lala'
177
-
178
- def belongs_to(*args)
179
- require 'og/relation/belongs_to'
180
- meta :relations, Og::BelongsTo.new(args, :owner_class => self)
181
- end
182
-
183
- # === Examples
184
- #
185
- # refers_to Topic
186
-
187
- def refers_to(*args)
188
- require 'og/relation/refers_to'
189
- meta :relations, Og::RefersTo.new(args, :owner_class => self)
190
- end
191
-
192
- # === Examples
193
- #
194
- # has_one User
195
-
196
- def has_one(*args)
197
- require 'og/relation/has_one'
198
- meta :relations, Og::HasOne.new(args, :owner_class => self)
199
- end
200
-
201
- # === Examples
202
- #
203
- # has_many Comment
204
- # has_many :comments, Comment
205
-
206
- def has_many(*args)
207
- require 'og/relation/has_many'
208
- meta :relations, Og::HasMany.new(args, :owner_class => self, :collection => true)
209
- end
210
-
211
- def joins_many(*args)
212
- require 'og/relation/joins_many'
213
- meta :relations, Og::JoinsMany.new(args, :owner_class => self, :collection => true)
214
- end
215
-
216
- def many_to_many(*args)
217
- require 'og/relation/many_to_many'
218
- meta :relations, Og::ManyToMany.new(args, :owner_class => self, :collection => true)
219
- end
220
-
221
- def inspect_relations
222
- __meta[:relations]
223
- end
224
- alias_method :relations, :inspect_relations
225
-
226
- def inspect_relation(name)
227
- __meta[:relations].find { |r| r[:name] == name }
228
- end
229
- alias_method :relation, :inspect_relation
230
-
231
- end
189
+ def self.append_features(base)
190
+ super
191
+ base.extend(ClassMethods)
192
+ end
193
+
194
+ module ClassMethods
195
+
196
+ # === Examples
197
+ #
198
+ # belongs_to Article
199
+ # belongs_to :article, Article
200
+ # belongs_to :article, Article, :view => 'lala'
201
+
202
+ def belongs_to(*args)
203
+ require 'og/relation/belongs_to'
204
+ meta :relations, Og::BelongsTo.new(args, :owner_class => self)
205
+ end
206
+
207
+ # === Examples
208
+ #
209
+ # refers_to Topic
210
+
211
+ def refers_to(*args)
212
+ require 'og/relation/refers_to'
213
+ meta :relations, Og::RefersTo.new(args, :owner_class => self)
214
+ end
215
+
216
+ # === Examples
217
+ #
218
+ # has_one User
219
+
220
+ def has_one(*args)
221
+ require 'og/relation/has_one'
222
+ meta :relations, Og::HasOne.new(args, :owner_class => self)
223
+ end
224
+
225
+ # === Examples
226
+ #
227
+ # has_many Comment
228
+ # has_many :comments, Comment
229
+
230
+ def has_many(*args)
231
+ require 'og/relation/has_many'
232
+ meta :relations, Og::HasMany.new(args, :owner_class => self, :collection => true)
233
+ end
234
+
235
+ def joins_many(*args)
236
+ require 'og/relation/joins_many'
237
+ meta :relations, Og::JoinsMany.new(args, :owner_class => self, :collection => true)
238
+ end
239
+
240
+ def many_to_many(*args)
241
+ require 'og/relation/many_to_many'
242
+ meta :relations, Og::ManyToMany.new(args, :owner_class => self, :collection => true)
243
+ end
244
+
245
+ def inspect_relations
246
+ __meta[:relations]
247
+ end
248
+ alias_method :relations, :inspect_relations
249
+
250
+ def inspect_relation(name)
251
+ __meta[:relations].find { |r| r[:name] == name }
252
+ end
253
+ alias_method :relation, :inspect_relation
254
+
255
+ end
232
256
  end
233
257
 
234
258
  end