og 0.23.0 → 0.24.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 (55) hide show
  1. data/ProjectInfo +58 -0
  2. data/README +5 -4
  3. data/Rakefile +2 -2
  4. data/doc/AUTHORS +10 -7
  5. data/doc/RELEASES +108 -0
  6. data/lib/og.rb +1 -3
  7. data/lib/og/collection.rb +4 -4
  8. data/lib/og/entity.rb +96 -27
  9. data/lib/og/evolution.rb +78 -0
  10. data/lib/og/manager.rb +29 -32
  11. data/lib/og/mixin/hierarchical.rb +1 -1
  12. data/lib/og/mixin/optimistic_locking.rb +5 -8
  13. data/lib/og/mixin/orderable.rb +15 -2
  14. data/lib/og/mixin/schema_inheritance_base.rb +12 -0
  15. data/lib/og/mixin/taggable.rb +29 -25
  16. data/lib/og/mixin/timestamped.rb +4 -2
  17. data/lib/og/mixin/tree.rb +0 -1
  18. data/lib/og/relation.rb +161 -116
  19. data/lib/og/relation/all.rb +6 -0
  20. data/lib/og/relation/belongs_to.rb +4 -1
  21. data/lib/og/relation/has_many.rb +6 -5
  22. data/lib/og/relation/joins_many.rb +13 -12
  23. data/lib/og/relation/refers_to.rb +3 -3
  24. data/lib/og/store.rb +9 -9
  25. data/lib/og/store/{filesys.rb → alpha/filesys.rb} +0 -0
  26. data/lib/og/store/alpha/kirby.rb +284 -0
  27. data/lib/og/store/{memory.rb → alpha/memory.rb} +2 -0
  28. data/lib/og/store/{sqlserver.rb → alpha/sqlserver.rb} +6 -6
  29. data/lib/og/store/kirby.rb +145 -162
  30. data/lib/og/store/mysql.rb +58 -27
  31. data/lib/og/store/psql.rb +15 -13
  32. data/lib/og/store/sql.rb +136 -135
  33. data/lib/og/store/sqlite.rb +13 -12
  34. data/lib/og/validation.rb +2 -2
  35. data/lib/vendor/kbserver.rb +20 -0
  36. data/lib/vendor/kirbybase.rb +2790 -1601
  37. data/test/og/CONFIG.rb +79 -0
  38. data/test/og/mixin/tc_hierarchical.rb +1 -1
  39. data/test/og/mixin/tc_optimistic_locking.rb +1 -3
  40. data/test/og/mixin/tc_orderable.rb +42 -1
  41. data/test/og/mixin/tc_taggable.rb +1 -1
  42. data/test/og/mixin/tc_timestamped.rb +1 -1
  43. data/test/og/store/tc_filesys.rb +1 -2
  44. data/test/og/tc_delete_all.rb +45 -0
  45. data/test/og/tc_inheritance.rb +10 -38
  46. data/test/og/tc_join.rb +2 -11
  47. data/test/og/tc_multiple.rb +3 -16
  48. data/test/og/tc_override.rb +3 -3
  49. data/test/og/tc_polymorphic.rb +3 -13
  50. data/test/og/tc_relation.rb +8 -6
  51. data/test/og/tc_reverse.rb +2 -11
  52. data/test/og/tc_select.rb +2 -15
  53. data/test/og/tc_store.rb +4 -63
  54. data/test/og/tc_types.rb +1 -2
  55. metadata +80 -77
@@ -0,0 +1,58 @@
1
+ --- %YAML:1.0
2
+
3
+ TITLE : &title Og
4
+ NAME : &pkg og
5
+ VERSION : '0.24.0'
6
+ STATUS : beta
7
+
8
+ AUTHOR : George Moschovitis
9
+ EMAIL : &email gm@navel.gr
10
+ HOMEPAGE : "http://www.nitrohq.com"
11
+
12
+ SUMMARY: State of the art object-relational mapping system.
13
+
14
+ DESCRIPTION: >
15
+ Object Graph (Og) is a state of the art ORM system.
16
+ Og serializes standard Ruby objects to Mysql, Postgres, Sqlite,
17
+ KirbyBase, Filesystem and more.
18
+
19
+ DEPENDENCIES:
20
+ - [ glue, '= 0.24.0' ]
21
+
22
+ DISTRIBUTE: [ gem, tgz, zip ]
23
+
24
+ RUBYFORGE:
25
+ PROJECT: 'nitro'
26
+ USERNAME: 'gmosx'
27
+
28
+ # Anything to require upfront?
29
+ #TEST:
30
+ # fixture: ''
31
+
32
+ ANNOUNCE:
33
+ to: george.moschovitis@gmail.com
34
+ from: gm@navel.gr
35
+ domain: navel.gr
36
+ server: mail
37
+ port: 25 #587
38
+ account: gm@navel.gr
39
+ authtype: login #cram_md5 #plain
40
+ sectype: tls # ~, tls, ssl (tls is broke)
41
+ file: ANN
42
+ slogan: Og (ObjectGraph)
43
+
44
+
45
+
46
+ links:
47
+ - http://www.nitrohq.com
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
data/README CHANGED
@@ -1,4 +1,4 @@
1
- = Og 0.23.0 README
1
+ = Og 0.24.0 README
2
2
 
3
3
  Og (ObjectGraph) is a powerful and elegant object-relational mapping
4
4
  library. Og manages the lifecycle of Ruby objects and provides
@@ -16,7 +16,7 @@ automatically generates join tables for many_to_many relations
16
16
  and provides a collection of usefull Mixins to synthesize
17
17
  common Entities.
18
18
 
19
- Adapters for PostgreSQL, MySQL, SQLite3, Memory, Filesystem,
19
+ Adapters for PostgreSQL, MySQL, SQLite3, KirbyBase, Memory, Filesystem,
20
20
  Oracle and SQL Server are included.
21
21
 
22
22
  Og is part of the Nitro project, released as a stand-alone library
@@ -29,10 +29,10 @@ distribution (http://www.nitrohq.com).
29
29
  The library provides the following features:
30
30
 
31
31
  * Object-Relational mapping, automatically maps standard
32
- Ruby objects to sql schemas
32
+ Ruby objects to sql schemas.
33
33
  * Absolutely no configuration files.
34
34
  * Multiple stores (PostgreSQL, MySQL, SQLite, Oraclei, SqlServer, ..).
35
- * Supports non SQL stores (in-memory, filesystem, ..).
35
+ * Supports non SQL stores (KirbyBase, Memory, filesystem, ..).
36
36
  * Can 'reverse engineer' legacy database schemase.
37
37
  * Fine-grained or High-level customization of the generated
38
38
  schema.
@@ -50,6 +50,7 @@ The library provides the following features:
50
50
  * SQL transactions.
51
51
  * Aspect oriented constructs allow interception of lifecycle callbacks.
52
52
  * Transparent support for cascading deletes for all backends.
53
+ * Can annotate and manage existing Ruby classes.
53
54
  * Hierarchical structures (nested sets)
54
55
  * Works safely as part of distributed application.
55
56
  * Optimistic locking.
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ Name = Release[/\D+/].sub(/\-+$/, '') || 'unknown'
10
10
  Version = Release[/[\d.]+/] || 'unknown'
11
11
 
12
12
  AuthorName, AuthorMail = 'George Moschovitis', 'gm@navel.gr'
13
- RubyVersion = '1.8.2'
13
+ RubyVersion = '1.8.3'
14
14
 
15
15
  # Description = (readme[/README\s+(.+?)\n\n/m, 1] || "unknown").gsub(/\s+/, " ")
16
16
  # Summary = Description[/^.+?>/] || "unknown"
@@ -62,7 +62,7 @@ spec = Gem::Specification.new do |s|
62
62
  #s.add_dependency 'sqlite3-ruby', '>= 1.0.0'
63
63
  #s.add_dependency 'mysql', '>= 2.5.1'
64
64
 
65
- s.required_ruby_version = '>= 1.8.2'
65
+ s.required_ruby_version = '= 1.8.3'
66
66
 
67
67
  s.files = FileList[
68
68
  '[A-Z]*', 'install.rb', '{bin,benchmark,examples,doc,lib,test,vendor}/**/*'
@@ -9,23 +9,26 @@ IDEAS, ADDITIONAL CODING, SUPPORT:
9
9
  * Michael Neumann <mneumann@ntecs.de>
10
10
  Design, additional coding and bug reports.
11
11
 
12
- * Anastasios Koutoumanos <ak@navel.gr>
13
- Design, additional coding.
14
-
15
- * Matt Bowen <matt.bowen@farweststeel.com>
16
- Oracle driver, documentation.
17
-
18
12
  * Ysabel <deb@ysabel.org>
19
13
  Refactoring, patches.
20
14
 
15
+ * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
16
+ Tons of patches.
17
+
21
18
  * Aleksi Niemela <Aleksi.Niemela@cs.helsinki.fi>
22
19
  Bug reports and patches.
20
+
21
+ * Anastasios Koutoumanos <ak@navel.gr>
22
+ Design, additional coding.
23
23
 
24
- * Julien Perrot <jperrot@exosec.fr>
24
+ * Julien Perrot <jperrot@exosec.fr>
25
25
  Bug reports and patches.
26
26
 
27
27
  * Ghislain Mary <gmary@lunacymaze.org>
28
28
  Bug reports and patches (sqlite3 driver).
29
29
 
30
+ * Matt Bowen <matt.bowen@farweststeel.com>
31
+ Oracle driver, documentation.
32
+
30
33
  * Thomas Quas <tquas@yahoo.com>
31
34
  Ideas, bug reports, unit tests.
@@ -1,3 +1,111 @@
1
+ == Version 0.24.0
2
+
3
+ A snapshot of the latest developments. This version features
4
+ many requested features and many many smaller features and
5
+ bug fixes.
6
+
7
+ Most notable additions:
8
+
9
+ * Totaly recoded annotation / property system. The property
10
+ system is now based on Facet annotations and inheritors.
11
+ You can now annotate every object, attribute or method
12
+ in Nitro. For example you can annotate your actions with
13
+ routing rules or sitemap strings etc, etc. One unified
14
+ system for annotations and metadata is used throughout
15
+ the whole Framework.
16
+
17
+ * Implemented one of the most requested features. An Og
18
+ frontend for KirbyBase. The KirbyBase store does not yet
19
+ support all features, but is really useful. For example
20
+ it can power the Spark wiki example. Switching between
21
+ KirbyBase, Mysql, Postgres, Sqlite, etc by changing
22
+ one line of code is really cool ;-)
23
+
24
+ * Better Seperation of Concerns for Og managed classes. Og
25
+ can now annotate and handle classes from other libraries.
26
+ Lets say you have the following class:
27
+
28
+ class User
29
+ attr_accessor :name
30
+ attr_accessor :body
31
+ end
32
+
33
+ Using Ruby's open classes and Nitro's advanced annotation
34
+ system you can easily prepare this class for Og management
35
+
36
+ class User
37
+ ann :user, :klass => String
38
+ ann :body, :klass => String
39
+ end
40
+
41
+ or even better:
42
+
43
+ class User
44
+ property :user, String
45
+ property :body, String
46
+ end
47
+
48
+ This style promotes SOC: You define your classes in one
49
+ place and annotate them for Og in another place.
50
+
51
+ * Simple Og automatic evolution system. Lets say you have a class Article
52
+
53
+ class Article
54
+ property :title, String
55
+ property :nbody, String
56
+ property :dumy, Fixnum
57
+ end
58
+
59
+ lets you want to change your
60
+ class to this one:
61
+
62
+ class NewArticle
63
+ property :ntitle, String
64
+ property :nbody, String
65
+ property :new, Float
66
+ end
67
+
68
+ First you export the database:
69
+
70
+ og.export
71
+
72
+ Then you import the database. Some rules
73
+ are needed when renaming classes or properties.
74
+ New properties or deleted properties are handled
75
+ automatically.
76
+
77
+ rules = {
78
+ :Article => {
79
+ :self => :NewArticle, # rename the class
80
+ :title => :ntitle,
81
+ :body => :nbody
82
+ }
83
+ }
84
+ og.import :evolution => rules
85
+
86
+ Thats all. In a future version this will be integrated into
87
+ the default runner scripts.
88
+
89
+ * Og helpers to create simple rdbms management scripts. Here
90
+ is an example:
91
+
92
+ mysql "-u root -p", <<-END
93
+ drop database if exists weblog_development;
94
+ create database weblog_development;
95
+ grant all on weblog_development.* to #{`id -un`.strip}@localhost;
96
+ END
97
+
98
+ At the moment this is only available for Mysql.
99
+
100
+ * Cleaned up Og implementation.
101
+
102
+ * Fixed minor Ruby 1.8.3 compatibility issues.
103
+
104
+ * Even better integration with Ruby Facets.
105
+
106
+ * Tons of bug fixes and small but useful features.
107
+
108
+
1
109
  == Version 0.23.0
2
110
 
3
111
  The summer vacations are over and there is a brand new Nitro
data/lib/og.rb CHANGED
@@ -13,8 +13,6 @@ require 'mega/syncarray'
13
13
 
14
14
  require 'glue'
15
15
  require 'glue/logger'
16
- require 'glue/attribute'
17
- require 'glue/property'
18
16
  require 'glue/validation'
19
17
  require 'glue/aspects'
20
18
  require 'glue/configuration'
@@ -45,7 +43,7 @@ module Og
45
43
 
46
44
  # The version.
47
45
 
48
- Version = '0.23.0'
46
+ Version = '0.24.0'
49
47
 
50
48
  # Library path.
51
49
 
@@ -64,7 +64,7 @@ class Collection
64
64
  # Load the members of the collection.
65
65
 
66
66
  def load_members
67
- unless @loaded
67
+ unless @loaded or @owner.unsaved?
68
68
  @members = @owner.send(@find_proc, @find_options)
69
69
  @loaded = true
70
70
  end
@@ -73,7 +73,7 @@ class Collection
73
73
 
74
74
  # Reload the collection.
75
75
 
76
- def reload(options)
76
+ def reload(options = {})
77
77
  # gmosx, NOOO: this was a bug! it corrupts the default options.
78
78
  # @find_options = options
79
79
  @members = @owner.send(@find_proc, options)
@@ -172,7 +172,7 @@ class Collection
172
172
 
173
173
  def remove_all
174
174
  @owner.transaction do
175
- @members.each { |obj| @owner.send(@remove_proc, obj) }
175
+ self.each { |obj| @owner.send(@remove_proc, obj) }
176
176
  end
177
177
  @members.clear
178
178
  end
@@ -183,7 +183,7 @@ class Collection
183
183
 
184
184
  def delete_all
185
185
  @owner.transaction do
186
- @members.each { |obj| obj.delete }
186
+ self.each { |obj| obj.delete }
187
187
  end
188
188
  @members.clear
189
189
  end
@@ -1,4 +1,5 @@
1
1
  require 'og/relation'
2
+ require 'og/mixin/schema_inheritance_base'
2
3
 
3
4
  module Og
4
5
 
@@ -48,8 +49,8 @@ module EntityMixin
48
49
 
49
50
  # Delete this entity instance from the store.
50
51
 
51
- def delete
52
- self.class.ogmanager.store.delete(self)
52
+ def delete(cascade = true)
53
+ self.class.ogmanager.store.delete(self, self.class, cascade)
53
54
  end
54
55
  alias_method :delete!, :delete
55
56
 
@@ -65,9 +66,27 @@ module EntityMixin
65
66
  def og_quote(obj)
66
67
  self.class.ogmanager.store.quote(obj)
67
68
  end
69
+
70
+ def assign_properties(values, options = {})
71
+ Property.populate_object(self, values, options)
72
+ return self
73
+ end
74
+ alias_method :assign, :assign_properties
68
75
  end_eval
69
76
 
70
- base.send(:include, RelationMacros)
77
+ base.send :include, RelationDSL
78
+
79
+ # If base is a Module setup a propageting
80
+ # append_features method.
81
+
82
+ unless base.is_a? Class
83
+ base.module_eval do
84
+ def self.append_features(cbase)
85
+ super
86
+ cbase.send :include, EntityMixin
87
+ end
88
+ end
89
+ end
71
90
  end
72
91
 
73
92
  module ClassMethods
@@ -78,6 +97,11 @@ module EntityMixin
78
97
  return obj
79
98
  end
80
99
 
100
+ def assign_properties(values, options)
101
+ Property.fill(self.new, values, options)
102
+ end
103
+ alias_method :assign, :assign_properties
104
+
81
105
  # Load an instance of this Entity class using the primary
82
106
  # key.
83
107
 
@@ -92,16 +116,13 @@ module EntityMixin
92
116
  end
93
117
 
94
118
  def find(options = {})
95
- # gmosx, FIXME: this code seems too complex,
96
- # improve this!
97
-
98
- if find_options = self.__meta[:find_options]
119
+ if find_options = self.ann.this[:find_options]
99
120
  options = find_options.first.dup.update(options)
100
121
  end
122
+
101
123
  options[:class] = self
102
- if self.metadata.superclass
103
- options[:type] = self
104
- end
124
+ options[:type] = self if self.schema_inheritance_child?
125
+
105
126
  ogmanager.store.find(options)
106
127
  end
107
128
  alias_method :all, :find
@@ -129,11 +150,24 @@ module EntityMixin
129
150
  # Delete an instance of this Entity class using the actual
130
151
  # instance or the primary key.
131
152
 
132
- def delete(obj_or_pk)
133
- ogmanager.store.delete(obj_or_pk, self)
153
+ def delete(obj_or_pk, cascade = true)
154
+ ogmanager.store.delete(obj_or_pk, self, cascade)
134
155
  end
135
156
  alias_method :delete!, :delete
136
157
 
158
+ # Delete all objects of this Entity class.
159
+ #--
160
+ # TODO: add cascade option.
161
+ #++
162
+
163
+ def delete_all
164
+ ogmanager.store.delete_all(self)
165
+ end
166
+
167
+ def destroy
168
+ ogmanager.store.send :destroy, self
169
+ end
170
+
137
171
  def escape(str)
138
172
  ogmanager.store.escape(str)
139
173
  end
@@ -149,16 +183,16 @@ module EntityMixin
149
183
  end
150
184
 
151
185
  def primary_key
152
- unless @__meta and @__meta[:primary_key]
153
- self.meta :primary_key, Entity.resolve_primary_key(self)
186
+ if ann.this.primary_key.nil?
187
+ ann :this, :primary_key => Entity.resolve_primary_key(self)
154
188
  end
155
- @__meta[:primary_key].flatten
189
+ return ann.this.primary_key
156
190
  end
157
191
 
158
192
  # Set the default find options for this entity.
159
193
 
160
194
  def set_find_options(options)
161
- meta :find_options, options
195
+ ann :this, :find_options => options
162
196
  end
163
197
  alias_method :find_options, :set_find_options
164
198
 
@@ -166,34 +200,59 @@ module EntityMixin
166
200
  # The Single Table Inheritance pattern is used.
167
201
 
168
202
  def set_schema_inheritance
169
- meta :schema_inheritance
203
+ include Og::SchemaInheritanceBase
170
204
  end
171
205
  alias_method :schema_inheritance, :set_schema_inheritance
206
+
207
+ def schema_inheritance?
208
+ ancestors.include? Og::SchemaInheritanceBase
209
+ end
210
+
211
+ def schema_inheritance_child?
212
+ schema_inheritance? and superclass.respond_to?(:schema_inheritance?)
213
+ end
214
+
215
+ def schema_inheritance_root?
216
+ schema_inheritance? and (!superclass.respond_to?(:schema_inheritance?))
217
+ end
218
+
219
+ #--
220
+ # farms/rp: is there not another way to access the root class?
221
+ #++
172
222
 
223
+ def schema_inheritance_root_class
224
+ klass = self
225
+ until !Og.manager.manageable?(klass) or klass.schema_inheritance_root?
226
+ klass = klass.superclass
227
+ end
228
+ return klass
229
+ end
230
+
173
231
  # Set the default order option for this entity.
174
232
 
175
233
  def set_order(order_str)
176
- meta :find_options, :order => order_str
234
+ # FIXME
235
+ # self.ann :this, :find_options, :order => order_str
177
236
  end
178
237
  alias_method :order, :set_order
179
238
 
180
239
  # Set a custom table name.
181
240
 
182
241
  def set_sql_table(table)
183
- meta :sql_table, table.to_s
242
+ ann :this, :sql_table => table.to_s
184
243
  end
185
244
  alias_method :set_table, :set_sql_table
186
245
 
187
246
  # Set the primary key.
188
247
 
189
248
  def set_primary_key(pk, pkclass = Fixnum)
190
- meta :primary_key, pk, pkclass
249
+ ann :this, :primary_key => Property.new(:symbol => pk, :klass => pkclass)
191
250
  end
192
251
 
193
252
  # Is this entity a polymorphic parent?
194
253
 
195
254
  def polymorphic_parent?
196
- self.to_s == self.metadata.polymorphic.to_s
255
+ self.to_s == self.ann.this.polymorphic.to_s
197
256
  end
198
257
 
199
258
  # Used internally to fix the forward reference problem.
@@ -204,24 +263,34 @@ module EntityMixin
204
263
  end
205
264
  end
206
265
 
207
- # A helper class.
266
+ # An Og Managed class. Also contains helper
267
+ # methods.
208
268
 
209
269
  class Entity
210
270
  class << self
211
271
  def resolve_primary_key(klass)
212
- if pk = klass.__meta[:primary_key]
272
+ # Is the class annotated with a primary key?
273
+
274
+ if pk = klass.ann.this[:primary_key]
213
275
  return pk
214
276
  end
215
- for p in klass.properties
216
- if p.meta[:primary_key]
217
- return p.symbol, p.klass
277
+
278
+ # Search the properties, try to find one annotated as primary_key.
279
+
280
+ for p in klass.properties.values
281
+ if p.primary_key
282
+ return Property.new(:symbol => p.symbol, :klass => p.klass)
218
283
  end
219
284
  end
220
- return :oid, Fixnum
285
+
286
+ # The default primary key is oid.
287
+
288
+ return Property.new(:symbol => :oid, :klass => Fixnum)
221
289
  end
222
290
  end
223
291
 
224
292
  include EntityMixin
225
293
  end
226
294
 
295
+
227
296
  end