og 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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