og 0.18.1 → 0.19.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.
data/CHANGELOG CHANGED
@@ -1,5 +1,128 @@
1
+ 17-06-2005 George Moschovitis <gm@navel.gr>
2
+
3
+ * examples/run.rb: fixes to make it run again.
4
+
5
+ * README: updated.
6
+
7
+ 15-06-2005 George Moschovitis <gm@navel.gr>
8
+
9
+ * lib/og/store/psql.rb: minor changes while applying michael's
10
+ patch.
11
+
12
+ * yeah, the new code passes tc_store.rb
13
+
14
+ * lib/og/sql.rb: don't create tables for polymorphic parents.
15
+
16
+ * lib/og/entity.rb (#polymorphic_parent?): implemented
17
+
18
+ * lib/og/relation/has_many.rb: (#initialize): imply belongs_to
19
+ relation if missing!,
20
+ (#resolve): gets symbol for resolve method.
21
+
22
+ * lib/og/relation.rb: fixes for polymorphic relations,
23
+ (#initialize): fix for non polymorphic.
24
+
25
+ 15-06-2005 Michael Neumann <mneumann@ntecs.de>
26
+
27
+ * lib/og.rb (Blob): introduced.
28
+
29
+ 14-06-2005 George Moschovitis <gm@navel.gr>
30
+
31
+ * lib/og/relation.rb: added support for polymorphic relations,
32
+ (#polymorphic?): added.
33
+
34
+ * back from vacations, lets rock!
35
+
36
+ 09-06-2005 George Moschovitis <gm@navel.gr>
37
+
38
+ * test/og/tc_polymorphic.rb: introduced.
39
+
40
+ 08-06-2005 George Moschovitis <gm@navel.gr>
41
+
42
+ * doc/AUTHORS: updated.
43
+
44
+ * lib/og/store/mysql.rb: added :table_type options so you can
45
+ use InnoDB tables.
46
+
47
+ 07-06-2005 George Moschovitis <gm@navel.gr>
48
+
49
+ * lib/og/manager.rb (#manage): call specialized enchanting
50
+ code.
51
+
52
+ * lib/og/mixin/optimistic_locking.rb: after some fixes it kinda
53
+ works,
54
+ correclty overloads #update.
55
+ overload #save.
56
+
57
+ 06-06-2005 George Moschovitis <gm@navel.gr>
58
+
59
+ * lib/og/store/*: implemented sql_update for psql, mysql, sqlite3.
60
+
61
+ * lib/og/mixin/optimistic_locking.rb: introduced,
62
+ (#update_with_lock): implemented.
63
+
64
+ * test/og/tc_store.rb: added extra tests for extra functionality,
65
+ updated ...update tests.
66
+
67
+ * lib/og/entity.rb (#select/#select_one): added,
68
+ added exist? alias.
69
+
70
+ * lib/og/store/sql.rb: (#read_one): use ensure res.close [ghislain]
71
+ (#read_all): ditto,
72
+ (#select): implemented,
73
+ (#select_one): implemented.
74
+ Auto add SELECT * FROM table if missing for extra convienience,
75
+ (#find): handle :sql option.
76
+ added exist? alias,
77
+ (#sql_update): introduced.
78
+ (#update, #update_properties): use sql_update.
79
+ (#update_condition): implemented.
80
+ use update_condition to simplify the code.
81
+ (#update): new more flexible interface.
82
+
83
+ 05-06-2005 George Moschovitis <gm@navel.gr>
84
+
85
+ * lib/og/store/*: adapted og insert in all stores.
86
+
87
+ * COOL: SuperClass.all returns an array of subclasses,
88
+ correctly typed.
89
+
90
+ * lib/og/store/sql.rb: added more comments, cleaned up,
91
+ sanitized usage of res, row and res_row,
92
+ (#og_allocate): implemented.
93
+
94
+ 04-06-2005 George Moschovitis <gm@navel.gr>
95
+
96
+ * lib/og/entity.rb (#all): correctly passes :type find option
97
+ for STI classes.
98
+
99
+ * lib/og/store/mysql.rb (#eval_og_insert): handle STI.
100
+
101
+ * lib/og/store/sql.rb (#fields_for_class): calculates extra
102
+ fields for STI tables,
103
+ (#find): added support for type in finders.
104
+
105
+ * doc/AUTHORS: updated.
106
+
107
+ * lib/og/entity.rb (#schema_inheritance): added.
108
+
109
+ * lib/og/manager.rb (#manageable?): introduced,
110
+ (#manage): keep inheritance metadata,
111
+ first resolve inheritance.
112
+
113
+ 03-06-2005 George Moschovitis <gm@navel.gr>
114
+
115
+ * test/og/tc_inheritance.rb: introduced.
116
+
117
+ 02-06-2005 Ghislain Mary <gmary@lunacymaze.org>
118
+
119
+ * lib/og/store/sqlite.rb: fixed typo.
120
+ (#og_insert): fixet last_insert_rowid calculation.
121
+
1
122
  29-05-2005 George Moschovitis <gm@navel.gr>
2
123
 
124
+ * --- VERSION 0.18.0 ---
125
+
3
126
  * lib/og/relation/has_many.rb: takes :order into account.
4
127
 
5
128
  * lib/og/entity.rb (#find/#all): take find_options into account,
data/README CHANGED
@@ -58,8 +58,19 @@ The latest version of Og can be found at
58
58
 
59
59
  * http://nitro.rubyforge.org
60
60
 
61
- Documentation for Og can be found in the distribution. You can find
62
- a nice tutorial at www.rubygarden.com.
61
+ == Documentation
62
+
63
+ Documentation for Og can be found at
64
+
65
+ * http://nitro.rubyforge.org
66
+
67
+ Don't forget to read the file doc/RELEASES for usefull
68
+ documentation bits. Also, have a look at the test cases in
69
+ the test directory for examples of usage.
70
+
71
+ You can find a nice tutorial at www.rubygarden.com. Be warned
72
+ that this tutorial describes an earlier version of Og. A *LOT*
73
+ of new features have been added in the meantime.
63
74
 
64
75
 
65
76
  == Requirements
@@ -13,10 +13,13 @@ IDEAS, ADDITIONAL CODING, SUPPORT:
13
13
  Design, additional coding.
14
14
 
15
15
  * Matt Bowen <matt.bowen@farweststeel.com>
16
- Additional code and documentation.
16
+ Oracle dirver, documentation.
17
17
 
18
18
  * Julien Perrot <jperrot@exosec.fr>
19
19
  Bug reports and patches.
20
20
 
21
+ * Ghislain Mary <gmary@lunacymaze.org>
22
+ Bug reports and patches (sqlite3 driver).
23
+
21
24
  * Thomas Quas <tquas@yahoo.com>
22
25
  Ideas, bug reports, unit tests.
@@ -1,4 +1,75 @@
1
- == Version 0.18.0
1
+ == Version 0.19.0
2
+
3
+ Og reloaded part 2: Another superb release introducing a balanced
4
+ mix of innovative new features, common but useful stuff and bug
5
+ fixes.
6
+
7
+ Some notable changes:
8
+
9
+ * Og polymorphic relations. A groundbreaking feature made possible
10
+ by Og's unique design and Ruby's power. Let's use an example
11
+ to explain the concept:
12
+
13
+ class Comment
14
+ ...
15
+ belongs_to Object # polymorphic marker
16
+ end
17
+
18
+ class User
19
+ ...
20
+ has_many Comment
21
+ end
22
+
23
+ class Article
24
+ ...
25
+ has_many Comment
26
+ end
27
+
28
+ u = User.new
29
+ u.comments << User::Comment('Hello')
30
+
31
+ a = Article.new
32
+ a.comments << Article::Comment('Wow!')
33
+
34
+ User::Comment and Article::Comment where automatically created
35
+ by Og and are serialized in different tables (also automatically
36
+ created by Og). This is the next step in DRY!
37
+
38
+ * Og now supports inheritance using the well known Single Table
39
+ Inheritance pattern. Thanks to Og's advanced design the pattern
40
+ is fully encapsulated:
41
+
42
+ class Document
43
+ ...
44
+ schema_inheritance
45
+ end
46
+
47
+ class Article < Document
48
+ ..
49
+ end
50
+
51
+ class Photo < Document
52
+ ..
53
+ end
54
+
55
+ Document.all # => includes Articles and Photos
56
+ Article.all # => only Articles
57
+
58
+ User.documents # => Articles and Photos
59
+ User.documents(:type => Photo) # => only photos.
60
+
61
+ Btw, this feature is orthogonal to the polymorphic relations
62
+ feature just described, giving the developer great
63
+ flexibility.
64
+
65
+ * Integrated an SQLite3 patch by Ghislain Mary.
66
+
67
+ * Integrated PostgreSQL binary data patch by Michael Neumann.
68
+
69
+ * Fixed all reported bugs.
70
+
71
+
72
+ == Version 0.18.0 was released on 01/06/2005.
2
73
 
3
74
  Mainly a bug fix release. Many small improvements were
4
75
  implemented. All reported bugs were fixed, as well as bugs found
@@ -204,7 +204,7 @@ Article.all.each { |a| puts a }
204
204
  # when there are many updates or you dont care about speed.
205
205
  # You can also update specific fields
206
206
  a2.title = 'A specific title'
207
- a2.update(:title)
207
+ a2.update(:properties => [:title])
208
208
 
209
209
  puts "\n\n"
210
210
  Article.all.each { |a| puts a }
@@ -245,8 +245,8 @@ article.parts.each { |pa| puts pa }
245
245
  puts "\n\n"
246
246
  puts '---'
247
247
 
248
- c1 = Category.new('Category1').save!
249
- c2 = Category.new('Category2').save!
248
+ c1 = Category.create('Category1')
249
+ c2 = Category.create('Category2')
250
250
 
251
251
  article.categories << c1
252
252
  article.categories << c2
data/lib/og.rb CHANGED
@@ -73,7 +73,7 @@ module Og
73
73
 
74
74
  # The version.
75
75
 
76
- Version = '0.18.1'
76
+ Version = '0.19.0'
77
77
 
78
78
  # Library path.
79
79
 
@@ -133,6 +133,11 @@ module Og
133
133
  # The active manager
134
134
 
135
135
  mattr_accessor :manager
136
+
137
+ # Pseudo type for binary data
138
+
139
+ class Blob; end
140
+
136
141
  end
137
142
 
138
143
  # gmosx: leave this here.
@@ -141,3 +146,5 @@ require 'og/manager'
141
146
  require 'og/errors'
142
147
  require 'og/types'
143
148
  require 'og/validation'
149
+
150
+ # * George Moschovitis <gm@navel.gr>
@@ -170,3 +170,6 @@ private
170
170
  end
171
171
 
172
172
  end
173
+
174
+ # * George Moschovitis <gm@navel.gr>
175
+ # * Julien Perrot <jperrot@exosec.fr>
@@ -12,9 +12,9 @@ module EntityMixin
12
12
  base.extend(ClassMethods)
13
13
 
14
14
  base.module_eval <<-end_eval, __FILE__, __LINE__
15
- def save
16
- self.class.ogmanager.store.save(self)
17
- return self
15
+ def save(options = nil)
16
+ self.class.ogmanager.store.save(self, options)
17
+ # return self
18
18
  end
19
19
  alias_method :save!, :save
20
20
 
@@ -23,9 +23,8 @@ module EntityMixin
23
23
  return self
24
24
  end
25
25
 
26
- def update(*properties)
27
- properties = nil if properties.empty?
28
- self.class.ogmanager.store.update(self, properties)
26
+ def update(options = nil)
27
+ self.class.ogmanager.store.update(self, options)
29
28
  end
30
29
 
31
30
  def update_properties(set)
@@ -62,6 +61,7 @@ module EntityMixin
62
61
  ogmanager.store.load(pk, self)
63
62
  end
64
63
  alias_method :[], :load
64
+ alias_method :exist?, :load
65
65
 
66
66
  def update_properties(set, options = nil)
67
67
  ogmanager.store.update_properties(self, set, options)
@@ -75,6 +75,9 @@ module EntityMixin
75
75
  options = find_options.first.update(options)
76
76
  end
77
77
  options[:class] = self
78
+ if self.metadata.superclass
79
+ options[:type] = self
80
+ end
78
81
  ogmanager.store.find(options)
79
82
  end
80
83
  alias_method :all, :find
@@ -86,6 +89,14 @@ module EntityMixin
86
89
  alias_method :one, :find_one
87
90
  alias_method :first, :find_one
88
91
 
92
+ def select(sql)
93
+ ogmanager.store.select(sql, self)
94
+ end
95
+
96
+ def select_one(sql)
97
+ ogmanager.store.select_one(sql, self)
98
+ end
99
+
89
100
  def count(options = {})
90
101
  options[:class] = self
91
102
  ogmanager.store.count(options)
@@ -122,8 +133,17 @@ module EntityMixin
122
133
  def order(order_str)
123
134
  meta :find_options, :order => order_str
124
135
  end
125
- end
136
+
137
+ def schema_inheritance
138
+ meta :schema_inheritance
139
+ end
126
140
 
141
+ # Is this entity a polymorphic parent?
142
+
143
+ def polymorphic_parent?
144
+ self.to_s == self.metadata.polymorphic.to_s
145
+ end
146
+ end
127
147
  end
128
148
 
129
149
  # A helper class.
@@ -83,6 +83,23 @@ class Manager
83
83
  end
84
84
  end
85
85
 
86
+ # Resolves the inheritance for a class.
87
+
88
+ def resolve_inheritance(klass)
89
+ if has_super?(klass)
90
+ sclass = klass.superclass
91
+ klass.meta :superclass, sclass
92
+ klass.meta :schema_inheritance
93
+ sclass.meta :subclasses, klass
94
+ end
95
+ end
96
+
97
+ # Resolve polymorphic relations.
98
+
99
+ def resolve_polymorphic(klass)
100
+ Relations.resolve_polymorphic(klass)
101
+ end
102
+
86
103
  # Manage a class. Converts the class to an Entity.
87
104
 
88
105
  def manage(klass)
@@ -90,6 +107,11 @@ class Manager
90
107
 
91
108
  info = EntityInfo.new(klass)
92
109
 
110
+ # ensure that the superclass is managed before the
111
+ # subclass.
112
+
113
+ manage(klass.superclass) if has_super?(klass)
114
+
93
115
  klass.module_eval %{
94
116
  def ==(other)
95
117
  other ? @#{klass.primary_key.first} == other.#{klass.primary_key.first} : false
@@ -103,10 +125,20 @@ class Manager
103
125
 
104
126
  # FIXME: uggly!
105
127
  store.enchant(klass, self); put_store
128
+
129
+ # Call special class enchanting code.
130
+
131
+ klass.enchant if klass.respond_to?(:enchant)
106
132
 
107
133
  @entities[klass] = info
108
134
  end
109
135
 
136
+ # Is this class manageable by Og?
137
+
138
+ def manageable?(klass)
139
+ klass.respond_to?(:__props) and (!klass.__props.empty?)
140
+ end
141
+
110
142
  # Is the class managed by Og?
111
143
 
112
144
  def managed?(klass)
@@ -114,6 +146,13 @@ class Manager
114
146
  end
115
147
  alias_method :entity?, :managed?
116
148
 
149
+ # Has this class a superclass?
150
+
151
+ def has_super?(klass)
152
+ manageable?(sclass = klass.superclass) and
153
+ (klass.metadata.schema_inheritance || sclass.metadata.schema_inheritance)
154
+ end
155
+
117
156
  # Use Ruby's advanced reflection features to find
118
157
  # all manageable classes. Managable are all classes that
119
158
  # define Properties.
@@ -122,7 +161,7 @@ class Manager
122
161
  classes = []
123
162
 
124
163
  ObjectSpace.each_object(Class) do |c|
125
- if c.respond_to?(:__props) and (!c.__props.empty?)
164
+ if manageable?(c)
126
165
  classes << c
127
166
  end
128
167
  end
@@ -135,8 +174,12 @@ class Manager
135
174
  # Manage a collection of classes.
136
175
 
137
176
  def manage_classes(*classes)
138
- classes = manageable_classes if classes.empty?
139
- classes.flatten.each { |c| manage(c) }
177
+ classes = manageable_classes.flatten if classes.empty?
178
+ classes.each { |c| resolve_inheritance(c) }
179
+ classes.each { |c| Relation.resolve(c, :resolve_target) }
180
+ classes.each { |c| Relation.resolve(c, :resolve_polymorphic) }
181
+ classes.each { |c| Relation.resolve(c, :resolve_options) }
182
+ classes.each { |c| manage(c) }
140
183
  end
141
184
 
142
185
  end