og 0.6.0 → 0.7.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.
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: psql.rb 185 2004-12-10 13:29:09Z gmosx $
5
+ # $Id: psql.rb 194 2004-12-20 20:23:57Z gmosx $
6
6
 
7
7
  require "postgres"
8
8
 
@@ -137,6 +137,8 @@ end
137
137
  # = PsqlBackend
138
138
  #
139
139
  # Implements a PostgreSQL powered backend.
140
+ # This backend is compatible with Michael Neumann's postgres-pr
141
+ # pure ruby driver.
140
142
  #
141
143
  class PsqlBackend < Og::Backend
142
144
 
@@ -240,21 +242,7 @@ class PsqlBackend < Og::Backend
240
242
  # and constrains are created (indicices, sequences, etc).
241
243
  #
242
244
  def create_table(klass)
243
- fields = []
244
-
245
- klass.__props.each do |p|
246
- klass.sql_index(p.symbol) if p.meta[:sql_index]
247
-
248
- field = "#{p.symbol}"
249
-
250
- if p.meta and p.meta[:sql]
251
- field << " #{p.meta[:sql]}"
252
- else
253
- field << " #{TYPEMAP[p.klass]}"
254
- end
255
-
256
- fields << field
257
- end
245
+ fields = create_fields(klass, TYPEMAP)
258
246
 
259
247
  sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
260
248
 
@@ -319,7 +307,7 @@ class PsqlBackend < Og::Backend
319
307
  join_src = "#{Og::Utils.encode(klass)}_oid"
320
308
  join_dst = "#{Og::Utils.encode(join_class)}_oid"
321
309
  begin
322
- exec "CREATE TABLE #{join_table} ( key1 integer, key2 integer )"
310
+ exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
323
311
  exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
324
312
  exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
325
313
  rescue => ex
data/lib/og/meta.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: meta.rb 185 2004-12-10 13:29:09Z gmosx $
5
+ # $Id: meta.rb 198 2004-12-22 11:26:59Z gmosx $
6
6
 
7
7
  require 'og/backend'
8
8
  require 'glue/inflector'
@@ -17,7 +17,9 @@ module MetaUtils # :nodoc: all
17
17
 
18
18
  # Conver the klass to a string representation
19
19
  # The leading module if available is removed.
20
- #
20
+ #--
21
+ # gmosx, FIXME: unify with the ogutils.encode method?
22
+ #++
21
23
  def self.expand(klass)
22
24
  return klass.name.gsub(/^.*::/, '').gsub(/::/, '_').downcase
23
25
  end
@@ -46,7 +48,7 @@ module MetaLanguage
46
48
  # Example:
47
49
  #
48
50
  # class MyObject
49
- # belongs_to AnotherObject, :parent
51
+ # belongs_to AnotherObject, :prop => :parent
50
52
  # end
51
53
  #
52
54
  # creates the code:
@@ -56,8 +58,12 @@ module MetaLanguage
56
58
  # def parent=(obj_or_oid); ... end
57
59
  #
58
60
  def belongs_to(name, klass, options = {})
61
+ prop_eval = "prop_accessor Fixnum, :#{name}_oid"
62
+ prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
63
+ prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
64
+
59
65
  module_eval %{
60
- prop_accessor Fixnum, :#{name}_oid
66
+ #{prop_eval}
61
67
 
62
68
  def #{name}
63
69
  $og.load_by_oid(@#{name}_oid, #{klass})
@@ -75,14 +81,14 @@ module MetaLanguage
75
81
  # Example:
76
82
  #
77
83
  # class MyObject
78
- # has_one :children, AnotherObject
84
+ # has_one AnotherObject
79
85
  # end
80
86
  #
81
87
  # creates the code:
82
88
  #
83
- # def children; ... end
89
+ # ...
84
90
  #
85
- def has_one(klass, name, options = {})
91
+ def has_one(name, klass, options = {})
86
92
  # linkback is the property of the child object that 'links back'
87
93
  # to this object.
88
94
  linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
@@ -117,6 +123,8 @@ module MetaLanguage
117
123
  # def children; ... end
118
124
  #
119
125
  def has_many(name, klass, options = {})
126
+ name_s = G::Inflector.singularize(name.to_s)
127
+
120
128
  # linkback is the property of the child object that 'links back'
121
129
  # to this object.
122
130
  linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
@@ -138,6 +146,11 @@ module MetaLanguage
138
146
  def #{name}_count(extrasql = nil)
139
147
  $og.count("SELECT COUNT(*) FROM #{Utils.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
140
148
  end
149
+
150
+ def add_#{name_s}(obj, extra = nil)
151
+ obj.#{linkback} = @oid
152
+ obj.save!
153
+ end
141
154
  }
142
155
  end
143
156
 
@@ -145,10 +158,12 @@ module MetaLanguage
145
158
  # Two objects are associated using an intermediate join table.
146
159
  # Automatically enchants the calling class with helper methods.
147
160
  #
161
+ # Options:
162
+ #
148
163
  # Example:
149
164
  #
150
165
  # class Article
151
- # many_to_many :children, Categories
166
+ # many_to_many :categories, Category, :linkback => articles
152
167
  # end
153
168
  #
154
169
  # article.categories
@@ -162,15 +177,15 @@ module MetaLanguage
162
177
  #--
163
178
  # FIXME: make more compatible with other enchant methods.
164
179
  #++
165
- def many_to_many(klass, options = {})
166
- name1 = options[:name1] || G::Inflector.name(self)
167
- pname1 = options[:list_name1] || G::Inflector.plural_name(self)
168
- name2 = options[:name2] || G::Inflector.name(klass)
169
- pname2 = options[:list_name2] || G::Inflector.plural_name(klass)
180
+ def many_to_many(name, klass, options = {})
181
+ list_o = name.to_s
182
+ prop_o = G::Inflector.singularize(list_o)
183
+ list_m = options[:linkback] || G::Inflector.plural_name(self)
184
+ prop_m = G::Inflector.singularize(list_m)
170
185
 
171
186
  # exit if the class is allready indirectly 'enchanted' from the
172
187
  # other class of the many_to_many relation.
173
- return if self.respond_to?(name1)
188
+ return if self.respond_to?(prop_m)
174
189
 
175
190
  # Add some metadata to the class to allow for automatic join table
176
191
  # calculation.
@@ -181,24 +196,24 @@ module MetaLanguage
181
196
  # enchant this class
182
197
 
183
198
  module_eval %{
184
- def #{pname2}(extrasql = nil)
199
+ def #{list_o}(extrasql = nil)
185
200
  $og.select("SELECT d.* FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
186
201
  end
187
202
 
188
- def #{pname2}_count(extrasql = nil)
203
+ def #{list_o}_count(extrasql = nil)
189
204
  $og.select("SELECT COUNT(*) FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
190
205
  end
191
206
 
192
- def add_#{name2}(obj, extra = nil)
207
+ def add_#{prop_o}(obj, extra = nil)
193
208
  $og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\@oid, \#\{obj.oid\})")
194
209
  end
195
210
 
196
- def del_#{name2}(obj_or_oid, extra = nil)
211
+ def del_#{prop_o}(obj_or_oid, extra = nil)
197
212
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\{obj_or_oid.to_i\}")
198
213
  end
199
- alias_method :delete_#{name2}, :del_#{name2}
214
+ alias_method :delete_#{prop_o}, :del_#{prop_o}
200
215
 
201
- def clear_#{pname2}
216
+ def clear_#{list_o}
202
217
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\@oid")
203
218
  end
204
219
  }
@@ -206,24 +221,24 @@ module MetaLanguage
206
221
  # indirectly enchant the other class of the relation.
207
222
 
208
223
  klass.module_eval %{
209
- def #{pname1}(extrasql = nil)
224
+ def #{list_m}(extrasql = nil)
210
225
  $og.select("SELECT s.* FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
211
226
  end
212
227
 
213
- def #{pname1}_count(extrasql = nil)
228
+ def #{list_m}_count(extrasql = nil)
214
229
  $og.select("SELECT COUNT(*) FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
215
230
  end
216
231
 
217
- def add_#{name1}(obj, extra = nil)
232
+ def add_#{prop_m}(obj, extra = nil)
218
233
  $og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\{obj.oid\}, \#\@oid)")
219
234
  end
220
235
 
221
- def del_#{name1}(obj_or_oid, extra = nil)
236
+ def del_#{prop_m}(obj_or_oid, extra = nil)
222
237
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\{obj_or_oid.to_i\}")
223
238
  end
224
- alias_method :delete_#{name1}, :del_#{name1}
239
+ alias_method :delete_#{prop_m}, :del_#{prop_m}
225
240
 
226
- def clear_#{pname1}
241
+ def clear_#{list_m}
227
242
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\@oid")
228
243
  end
229
244
  }
data/lib/og/mock.rb ADDED
@@ -0,0 +1,223 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ # * Thomas Quas <tquas@yahoo.com>
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id$
7
+
8
+ require 'og'
9
+
10
+ require 'rubygems'
11
+ require_gem 'flexmock'
12
+
13
+ module Og
14
+
15
+ # = MockDatabase
16
+ #
17
+ # A utility object to Mock a Database in test units.
18
+ # Extends the standard FlexMock object.
19
+ #
20
+ #--
21
+ # TODO: Factor out common functionality with Database
22
+ # to avoid code duplication.
23
+ #++
24
+ class MockDatabase < ::FlexMock
25
+
26
+ # Managed class metadata
27
+ #
28
+ class ManagedClassMeta
29
+ # The managed class.
30
+ attr_accessor :klass
31
+
32
+ # A mapping of the database fields to the object properties.
33
+ attr_accessor :field_index
34
+
35
+ def initialize(klass = nil)
36
+ @klass = klass
37
+ @field_index = {}
38
+ end
39
+ end
40
+
41
+ # hash of configuration options.
42
+ attr_accessor :config
43
+
44
+ # Pool of connections to the backend.
45
+ attr_accessor :connection_pool
46
+
47
+ # Managed classes.
48
+ attr_accessor :managed_classes
49
+
50
+ # Initialize the database interface.
51
+ #
52
+ def initialize
53
+ # Initialize FlexMock
54
+ super
55
+
56
+ @managed_classes = G::SafeHash.new
57
+
58
+ $log.info "Using mock database."
59
+
60
+ if $og_auto_manage_classes
61
+ # automatically manage classes with properties and metadata.
62
+ # gmosx: Any idea how to optimize this?
63
+ classes_to_manage = []
64
+ ObjectSpace.each_object(Class) do |c|
65
+ if c.respond_to?(:__props) and c.__props
66
+ classes_to_manage << c
67
+ end
68
+ end
69
+ $log.info "Og auto manages the following classes:"
70
+ $log.info "#{classes_to_manage.inspect}"
71
+ manage_classes(*classes_to_manage)
72
+ end
73
+ end
74
+
75
+ # Shutdown the database interface.
76
+ #
77
+ def shutdown
78
+ end
79
+ alias_method :close, :shutdown
80
+
81
+ # Register a standard Ruby class as managed.
82
+ #
83
+ def manage(klass)
84
+ return if managed?(klass) or klass.ancestors.include?(Og::Unmanageable)
85
+
86
+ @managed_classes[klass] = ManagedClassMeta.new(klass)
87
+
88
+ # Add standard og methods to the class.
89
+ convert(klass)
90
+
91
+ # Add helper methods to the class.
92
+ enchant(klass) if $og_enchant_managed_classes
93
+ end
94
+
95
+ # Helper method to set multiple managed classes.
96
+ #
97
+ def manage_classes(*klasses)
98
+ for klass in klasses
99
+ manage(klass)
100
+ end
101
+ end
102
+
103
+ # Stop managing a Ruby class
104
+ #
105
+ def unmanage(klass)
106
+ @managed_classes.delete(klass)
107
+ end
108
+
109
+ # Is this class managed?
110
+ #
111
+ def managed?(klass)
112
+ return @managed_classes.include?(klass)
113
+ end
114
+
115
+ # Add standard og functionality to the class
116
+ #
117
+ def convert(klass)
118
+ klass.class_eval %{
119
+ DBTABLE = "#{Og::Utils.table(klass)}"
120
+ DBSEQ = "#{Og::Utils.table(klass)}_oids_seq"
121
+
122
+ def to_i()
123
+ @oid
124
+ end
125
+ }
126
+ end
127
+
128
+ # Enchant a managed class. Add useful DB related methods to the
129
+ # class and its instances.
130
+ #
131
+ def enchant(klass)
132
+ klass.class_eval %{
133
+ def self.save(obj)
134
+ $og << obj
135
+ end
136
+
137
+ def self.load(oid_or_name)
138
+ $og.load(oid_or_name, #{klass})
139
+ end
140
+
141
+ def self.[](oid_or_name)
142
+ $og.load(oid_or_name, #{klass})
143
+ end
144
+
145
+ def self.load_all(extra_sql = nil)
146
+ $og.load_all(#{klass}, extra_sql)
147
+ end
148
+
149
+ def self.all(extra_sql = nil)
150
+ $og.load_all(#{klass}, extra_sql)
151
+ end
152
+
153
+ def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
154
+ $og.count(sql, #{klass})
155
+ end
156
+
157
+ def self.select(sql)
158
+ $og.select(sql, #{klass})
159
+ end
160
+
161
+ def self.select_one(sql)
162
+ $og.select_one(sql, #{klass})
163
+ end
164
+
165
+ def self.delete(obj_or_oid)
166
+ $og.delete(obj_or_oid, #{klass})
167
+ end
168
+
169
+ def save
170
+ $og << self
171
+ return self
172
+ end
173
+ alias_method :save!, :save
174
+
175
+ def update_properties(updatesql)
176
+ $og.pupdate(updatesql, self.oid, #{klass})
177
+ end
178
+ alias_method :pupdate!, :update_properties
179
+
180
+ def delete!
181
+ $og.delete(@oid, #{klass})
182
+ end
183
+ }
184
+ end
185
+
186
+ # Automatically wrap connection methods.
187
+ #
188
+ def self.wrap_method(method, args)
189
+ args = args.split(/,/)
190
+ class_eval %{
191
+ def #{method}(#{args.join(", ")})
192
+ # nop
193
+ end
194
+ }
195
+ end
196
+ =begin
197
+ wrap_method :create_table, "klass"
198
+ wrap_method :drop_table, "klass"
199
+ wrap_method :save, "obj"; alias_method :<<, :save; alias_method :put, :save
200
+ wrap_method :insert, "obj"
201
+ wrap_method :update, "obj"
202
+ wrap_method :update_properties, "update_sql, obj_or_oid, klass = nil"
203
+ wrap_method :pupdate, "update_sql, obj_or_oid, klass = nil"
204
+ wrap_method :load, "oid, klass"; alias_method :get, :load
205
+ wrap_method :load_by_oid, "oid, klass"
206
+ wrap_method :load_by_name, "name, klass"
207
+ wrap_method :load_all, "klass, extrasql = nil"
208
+ wrap_method :select, "sql, klass"
209
+ wrap_method :select_one, "sql, klass"
210
+ wrap_method :count, "sql, klass = nil"
211
+ wrap_method :delete, "obj_or_oid, klass = nil"
212
+ wrap_method :query, "sql"
213
+ wrap_method :exec, "sql"
214
+ =end
215
+ def self.create_db!(config)
216
+ end
217
+
218
+ def self.drop_db!(config)
219
+ end
220
+ end
221
+
222
+ end # module
223
+
data/lib/og/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: version.rb 175 2004-11-26 16:11:27Z gmosx $
5
+ # $Id: version.rb 198 2004-12-22 11:26:59Z gmosx $
6
6
 
7
7
  # The version of Og.
8
- $og_version = '0.6.0'
8
+ $og_version = '0.7.0'