og 0.28.0 → 0.29.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.
@@ -1,58 +1,193 @@
1
1
  require File.join(File.dirname(__FILE__), 'CONFIG.rb')
2
2
 
3
- $DBG = true
4
-
5
3
  require 'rubygems'
6
4
  require 'facets'
5
+ require 'fileutils'
7
6
  require 'test/unit'
8
7
 
9
8
  require 'og'
10
9
  require 'glue/cacheable'
11
10
  require 'glue/cache/memory'
11
+ require 'glue/cache/file'
12
+ require 'glue/cache/memcached'
12
13
  #require 'glue/cache/drb'
13
14
 
14
- class TC_Cacheable < Test::Unit::TestCase # :nodoc: all
15
- include Glue
16
-
15
+ class TC_MemoryCacheable < Test::Unit::TestCase # :nodoc: all
17
16
  class User
18
- is Cacheable
17
+ is Glue::Cacheable
19
18
 
20
19
  property :name, String
21
20
  property :age, Fixnum
22
21
  end
23
22
 
23
+ $og1.manage_classes(User)
24
+
25
+ Caches = [Glue::MemoryCache]
26
+
24
27
  def setup
25
- @og = Og.start
26
- @og.cache = MemoryCache.new
27
- # @og.cache = DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
28
+ @og = User.ogmanager
29
+ # @og.cache = Glue::DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
30
+ end
31
+
32
+ def teardown
33
+ @og.cache = nil
28
34
  end
29
35
 
30
36
  def test_all
31
- User.create_with :name => 'George'
32
- User.create_with :name => 'Stella'
37
+ Caches.each do |cache_class|
38
+ # @og.cache = DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
39
+ @og.cache = cache_class.new
40
+
41
+ msg = "Failed for cache type: #{cache_class}"
42
+
43
+ User.create_with :name => 'George'
44
+ User.create_with :name => 'Stella'
45
+
46
+ u = User[1]
47
+
48
+ assert_equal 'George', u.name, msg
49
+
50
+ # Comes from the cache.
51
+
52
+ u = User[1]
53
+ u = User[1]
54
+ u = User[1]
55
+
56
+ assert_equal u, @og.cache.get(u.og_cache_key), msg
33
57
 
34
- u = User[1]
58
+ u.name = 'Hello'
59
+ u.save
60
+
61
+ u = User[1]
62
+ u = User[1]
63
+
64
+ assert_equal u.name, @og.cache.get(u.og_cache_key).name, msg
65
+
66
+ u.delete
67
+ User.delete(2)
68
+ end
69
+ end
70
+ end
71
+
72
+ class TC_FileCacheable < Test::Unit::TestCase # :nodoc: all
73
+ class User
74
+ is Glue::Cacheable
35
75
 
36
- assert_equal 'George', u.name
76
+ property :name, String
77
+ property :age, Fixnum
78
+ end
79
+
80
+ $og1.manage_classes(User)
81
+
82
+ Caches = [Glue::FileCache]
83
+
84
+ def setup
85
+ Glue::FileCache.basedir = File.join(File.dirname(__FILE__), '..', 'cache')
86
+ FileUtils.rm_r Glue::FileCache.basedir if File.exists? Glue::FileCache.basedir
87
+
88
+ @og = User.ogmanager
89
+ # @og.cache = Glue::DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
90
+ end
91
+
92
+ def teardown
93
+ @og.cache = nil
94
+ end
95
+
96
+ def test_all
97
+ Caches.each do |cache_class|
98
+ # @og.cache = DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
99
+ @og.cache = cache_class.new
100
+
101
+ msg = "Failed for cache type: #{cache_class}"
102
+
103
+ User.create_with :name => 'George'
104
+ User.create_with :name => 'Stella'
105
+
106
+ u = User[1]
107
+
108
+ assert_equal 'George', u.name, msg
109
+
110
+ # Comes from the cache.
111
+
112
+ u = User[1]
113
+ u = User[1]
114
+ u = User[1]
37
115
 
38
- # Comes from the cache.
116
+ assert_equal u, @og.cache.get(u.og_cache_key), msg
39
117
 
40
- u = User[1]
41
- u = User[1]
42
- u = User[1]
118
+ u.name = 'Hello'
119
+ u.save
120
+
121
+ u = User[1]
122
+ u = User[1]
123
+
124
+ assert_equal u.name, @og.cache.get(u.og_cache_key).name, msg
125
+
126
+ u.delete
127
+ User.delete(2)
128
+ end
129
+ end
130
+ end
131
+
132
+ begin
133
+ Glue::MemCached.new
134
+ class TC_MemCachedCacheable < Test::Unit::TestCase # :nodoc: all
135
+ class User
136
+ is Glue::Cacheable
137
+
138
+ property :name, String
139
+ property :age, Fixnum
140
+ end
43
141
 
44
- assert_equal u, @og.cache.get(u.og_cache_key)
142
+ $og1.manage_classes(User)
143
+
144
+ Caches = [Glue::MemCached]
145
+
146
+ def setup
147
+ @og = User.ogmanager
148
+ # @og.cache = Glue::DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
149
+ end
150
+
151
+ def teardown
152
+ @og.cache = nil
153
+ end
154
+
155
+ def test_all
156
+ Caches.each do |cache_class|
157
+ # @og.cache = DrbCache.new(:address => Og.cache_address, :port => Og.cache_port)
158
+ @og.cache = cache_class.new
45
159
 
46
- u.name = 'Hello'
47
- u.save
48
-
49
- u = User[1]
50
- u = User[1]
51
-
52
- assert_equal u.name, @og.cache.get(u.og_cache_key).name
53
-
54
- u.delete
55
- User.delete(2)
160
+ msg = "Failed for cache type: #{cache_class}"
161
+
162
+ User.create_with :name => 'George'
163
+ User.create_with :name => 'Stella'
164
+
165
+ u = User[1]
166
+
167
+ assert_equal 'George', u.name, msg
168
+
169
+ # Comes from the cache.
170
+
171
+ u = User[1]
172
+ u = User[1]
173
+ u = User[1]
174
+
175
+ assert_equal u, @og.cache.get(u.og_cache_key), msg
176
+
177
+ u.name = 'Hello'
178
+ u.save
179
+
180
+ u = User[1]
181
+ u = User[1]
182
+
183
+ assert_equal u.name, @og.cache.get(u.og_cache_key).name, msg
184
+
185
+ u.delete
186
+ User.delete(2)
187
+ end
188
+ end
56
189
  end
57
-
190
+ rescue Object
191
+ puts 'MemCached sever not running, skipping test'
58
192
  end
193
+
@@ -56,7 +56,10 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
56
56
 
57
57
  def test_all
58
58
  assert_equal Document, Photo.superclass
59
- assert_equal [Photo, Article], Document.descendents
59
+ descendents = Document.descendents
60
+ assert_equal(2, descendents.size)
61
+ assert descendents.include?(Photo)
62
+ assert descendents.include?(Article)
60
63
 
61
64
  assert Document.ann.self.schema_inheritance
62
65
 
@@ -5,6 +5,7 @@ require 'test/unit'
5
5
  require 'glue'
6
6
  require 'glue/property'
7
7
  require 'glue/validation'
8
+ require 'og/validation'
8
9
 
9
10
  class TC_MultiValidation < Test::Unit::TestCase # :nodoc: all
10
11
 
@@ -20,10 +20,16 @@ class TestOg < Test::Unit::TestCase
20
20
  end
21
21
 
22
22
  def setup
23
+ @old_prefix = Og.table_prefix
23
24
  Og.table_prefix = nil
24
25
  og = Og.start
25
26
  end
26
27
 
28
+ def teardown
29
+ Og.table_prefix = @old_prefix
30
+ @old_prefix = nil
31
+ end
32
+
27
33
  def test_basic
28
34
  book = Book.create
29
35
  person = Person.create
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: og
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.28.0
7
- date: 2006-02-06 00:00:00 +02:00
6
+ version: 0.29.0
7
+ date: 2006-03-07 00:00:00 +02:00
8
8
  summary: State of the art object-relational mapping system.
9
9
  require_paths:
10
10
  - lib
@@ -15,7 +15,7 @@ description:
15
15
  autorequire:
16
16
  default_executable:
17
17
  bindir: bin
18
- has_rdoc: false
18
+ has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
21
  - - ">"
@@ -49,6 +49,7 @@ files:
49
49
  - lib/og
50
50
  - lib/glue
51
51
  - lib/og.rb
52
+ - lib/og/ez
52
53
  - lib/og/relation
53
54
  - lib/og/store
54
55
  - lib/og/test
@@ -63,8 +64,9 @@ files:
63
64
  - lib/og/errors.rb
64
65
  - lib/og/entity.rb
65
66
  - lib/og/collection.rb
66
- - lib/og/ez
67
67
  - lib/og/markers.rb
68
+ - lib/og/ez/condition.rb
69
+ - lib/og/ez/clause.rb
68
70
  - lib/og/relation/many_to_many.rb
69
71
  - lib/og/relation/refers_to.rb
70
72
  - lib/og/relation/joins_many.rb
@@ -73,22 +75,19 @@ files:
73
75
  - lib/og/relation/belongs_to.rb
74
76
  - lib/og/relation/all.rb
75
77
  - lib/og/store/alpha
76
- - lib/og/store/sqlite2.rb
77
78
  - lib/og/store/sqlite.rb
78
79
  - lib/og/store/sql.rb
79
80
  - lib/og/store/psql.rb
80
81
  - lib/og/store/mysql.rb
81
82
  - lib/og/store/kirby.rb
83
+ - lib/og/store/sqlite2.rb
82
84
  - lib/og/store/alpha/sqlserver.rb
83
85
  - lib/og/store/alpha/memory.rb
84
- - lib/og/store/alpha/kirby.rb
85
86
  - lib/og/store/alpha/filesys.rb
86
87
  - lib/og/test/testcase.rb
87
88
  - lib/og/test/assertions.rb
88
89
  - lib/og/vendor/mysql.rb
89
90
  - lib/og/vendor/README
90
- - lib/og/ez/clause.rb
91
- - lib/og/ez/condition.rb
92
91
  - lib/glue/taggable.rb
93
92
  - lib/glue/tree.rb
94
93
  - lib/glue/hierarchical.rb
@@ -112,7 +111,6 @@ files:
112
111
  - test/og/tc_polymorphic.rb
113
112
  - test/og/tc_multiple.rb
114
113
  - test/og/tc_join.rb
115
- - test/og/tc_resolve.rb
116
114
  - test/og/tc_inheritance.rb
117
115
  - test/og/CONFIG.rb
118
116
  - test/og/tc_scoped.rb
@@ -124,8 +122,10 @@ files:
124
122
  - test/og/tc_validation_loop.rb
125
123
  - test/og/tc_cacheable.rb
126
124
  - test/og/tc_multi_validations.rb
125
+ - test/og/tc_resolve.rb
127
126
  - test/og/multi_validations_model.rb
128
127
  - test/og/tc_ez.rb
128
+ - test/og/tc_aggregations_calculations.rb
129
129
  - test/og/mixin/tc_timestamped.rb
130
130
  - test/og/mixin/tc_taggable.rb
131
131
  - test/og/mixin/tc_orderable.rb
@@ -133,6 +133,7 @@ files:
133
133
  - test/og/mixin/tc_optimistic_locking.rb
134
134
  - test/og/store/tc_filesys.rb
135
135
  - test/og/store/tc_kirby.rb
136
+ - test/og/store/tc_sti.rb
136
137
  - test/glue/tc_revisable.rb
137
138
  test_files: []
138
139
 
@@ -154,5 +155,5 @@ dependencies:
154
155
  requirements:
155
156
  - - "="
156
157
  - !ruby/object:Gem::Version
157
- version: 0.28.0
158
+ version: 0.29.0
158
159
  version:
@@ -1,284 +0,0 @@
1
- begin
2
- require 'lib/vendor/kirbybase'
3
- rescue Object => ex
4
- Logger.error 'KirbyBase is not installed!'
5
- Logger.error ex
6
- end
7
-
8
- require 'og/store/sql'
9
-
10
- module Og
11
-
12
- # A Store that persists objects into an KirbyBase database.
13
- # KirbyBase is a pure-ruby database implementation.
14
- # To read documentation about the methods, consult the
15
- # documentation for SqlStore and Store.
16
-
17
- class KirbyStore < SqlStore
18
-
19
- def self.db_dir(options)
20
- "#{options[:name]}_db"
21
- end
22
-
23
- def self.destroy(options)
24
- begin
25
- FileUtils.rm_rf(db_dir(options))
26
- super
27
- rescue Object
28
- Logger.info "Cannot drop '#{options[:name]}'!"
29
- end
30
- end
31
-
32
- def initialize(options)
33
- super
34
-
35
- if options[:embedded]
36
- name = self.class.db_dir(options)
37
- FileUtils.mkdir_p(name)
38
- @conn = KirbyBase.new(:local, nil, nil, name)
39
- else
40
- # TODO
41
- end
42
- end
43
-
44
- def close
45
- super
46
- end
47
-
48
- def enchant(klass, manager)
49
- klass.property :oid, Fixnum, :sql => 'integer PRIMARY KEY'
50
- super
51
- end
52
-
53
- def query(sql)
54
- Logger.debug sql if $DBG
55
- return @conn.query(sql)
56
- rescue => ex
57
- handle_sql_exception(ex, sql)
58
- end
59
-
60
- def exec(sql)
61
- Logger.debug sql if $DBG
62
- @conn.query(sql).close
63
- rescue => ex
64
- handle_sql_exception(ex, sql)
65
- end
66
-
67
- def start
68
- # nop
69
- end
70
-
71
- def commit
72
- # nop
73
- end
74
-
75
- def rollback
76
- # nop
77
- end
78
-
79
- private
80
-
81
- def create_table(klass)
82
- fields = fields_for_class(klass)
83
-
84
- table = @conn.create_table(klass::OGTABLE, *fields) { |obj| obj.encrypt = false }
85
-
86
- # Create join tables if needed. Join tables are used in
87
- # 'many_to_many' relations.
88
-
89
- if klass.__meta and join_tables = klass.__meta[:join_tables]
90
- for join_table in join_tables
91
- begin
92
- @conn.create_table(join_table[:table],
93
- join_table[:first_key], :Integer,
94
- join_table[:second_key], :Integer)
95
- # KirbyBase doesn't support indices.
96
- rescue RuntimeError => error
97
- # Unfortunately, KirbyBase just throws RuntimeErrors
98
- # with no extra information, so we just have to look
99
- # for the error message it uses.
100
- if error.message =~ /table #{join_table[:table]} already exists/i
101
- Logger.debug 'Join table already exists' if $DBG
102
- else
103
- raise
104
- end
105
- end
106
- end
107
- end
108
- end
109
-
110
- def drop_table(klass)
111
- @conn.drop_table(klass.table) if @conn.table_exists?(klass.table)
112
- end
113
-
114
- def fields_for_class(klass)
115
- fields = []
116
-
117
- klass.properties.each do |p|
118
- klass.index(p.symbol) if p.meta[:index]
119
-
120
- fields << p.symbol
121
-
122
- type = p.klass.name.intern
123
- type = :Integer if type == :Fixnum
124
-
125
- fields << type
126
- end
127
-
128
- return fields
129
- end
130
-
131
- def create_field_map(klass)
132
- map = {}
133
- fields = @conn.get_table(klass.table).field_names
134
-
135
- fields.size.times do |i|
136
- map[fields[i]] = i
137
- end
138
-
139
- return map
140
- end
141
-
142
- # Return an sql string evaluator for the property.
143
- # No need to optimize this, used only to precalculate code.
144
- # YAML is used to store general Ruby objects to be more
145
- # portable.
146
- #--
147
- # FIXME: add extra handling for float.
148
- #++
149
-
150
- def write_prop(p)
151
- if p.klass.ancestors.include?(Integer)
152
- return "@#{p.symbol} || nil"
153
- elsif p.klass.ancestors.include?(Float)
154
- return "@#{p.symbol} || nil"
155
- elsif p.klass.ancestors.include?(String)
156
- return %|@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol})\}'" : nil|
157
- elsif p.klass.ancestors.include?(Time)
158
- return %|@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : nil|
159
- elsif p.klass.ancestors.include?(Date)
160
- return %|@#{p.symbol} ? "'#\{#{self.class}.date(@#{p.symbol})\}'" : nil|
161
- elsif p.klass.ancestors.include?(TrueClass)
162
- return "@#{p.symbol} ? \"'t'\" : nil"
163
- else
164
- # gmosx: keep the '' for nil symbols.
165
- return %|@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"|
166
- end
167
- end
168
-
169
- # Return an evaluator for reading the property.
170
- # No need to optimize this, used only to precalculate code.
171
-
172
- def read_prop(p, col)
173
- if p.klass.ancestors.include?(Integer)
174
- return "#{self.class}.parse_int(res[#{col} + offset])"
175
- elsif p.klass.ancestors.include?(Float)
176
- return "#{self.class}.parse_float(res[#{col} + offset])"
177
- elsif p.klass.ancestors.include?(String)
178
- return "res[#{col} + offset]"
179
- elsif p.klass.ancestors.include?(Time)
180
- return "#{self.class}.parse_timestamp(res[#{col} + offset])"
181
- elsif p.klass.ancestors.include?(Date)
182
- return "#{self.class}.parse_date(res[#{col} + offset])"
183
- elsif p.klass.ancestors.include?(TrueClass)
184
- return "('0' != res[#{col} + offset])"
185
- else
186
- return "YAML::load(res[#{col} + offset])"
187
- end
188
- end
189
-
190
- # :section: Lifecycle method compilers.
191
-
192
- # Compile the og_update method for the class.
193
-
194
- def eval_og_insert(klass)
195
- pk = klass.pk_symbol
196
- props = klass.properties
197
-
198
- data = props.collect {|p| ":#{p.symbol} => #{write_prop(p)}"}.join(', ')
199
- # data.gsub!(/#|\{|\}/, '')
200
-
201
- klass.module_eval %{
202
- def og_insert(store)
203
- #{Glue::Aspects.gen_advice_code(:og_insert, klass.advices, :pre) if klass.respond_to?(:advices)}
204
- store.conn.get_table('#{klass.table}').insert(#{data})
205
- #{Glue::Aspects.gen_advice_code(:og_insert, klass.advices, :post) if klass.respond_to?(:advices)}
206
- end
207
- }
208
- end
209
-
210
- # Compile the og_update method for the class.
211
-
212
- def eval_og_update(klass)
213
- pk = klass.pk_symbol
214
- props = klass.properties.reject { |p| pk == p.symbol }
215
-
216
- updates = props.collect { |p|
217
- "#{p.symbol}=#{write_prop(p)}"
218
- }
219
-
220
- sql = "UPDATE #{klass::OGTABLE} SET #{updates.join(', ')} WHERE #{pk}=#\{@#{pk}\}"
221
-
222
- klass.module_eval %{
223
- def og_update(store)
224
- #{Glue::Aspects.gen_advice_code(:og_update, klass.advices, :pre) if klass.respond_to?(:advices)}
225
- store.exec "#{sql}"
226
- #{Glue::Aspects.gen_advice_code(:og_update, klass.advices, :post) if klass.respond_to?(:advices)}
227
- end
228
- }
229
- end
230
-
231
- # Compile the og_read method for the class. This method is
232
- # used to read (deserialize) the given class from the store.
233
- # In order to allow for changing field/attribute orders a
234
- # field mapping hash is used.
235
-
236
- def eval_og_read(klass)
237
- code = []
238
- props = klass.properties
239
- field_map = create_field_map(klass)
240
-
241
- props.each do |p|
242
- if col = field_map[p.symbol]
243
- code << "@#{p.symbol} = #{read_prop(p, col)}"
244
- end
245
- end
246
-
247
- code = code.join('; ')
248
-
249
- klass.module_eval %{
250
- def og_read(res, row = 0, offset = 0)
251
- #{Glue::Aspects.gen_advice_code(:og_read, klass.advices, :pre) if klass.respond_to?(:advices)}
252
- #{code}
253
- #{Glue::Aspects.gen_advice_code(:og_read, klass.advices, :post) if klass.respond_to?(:advices)}
254
- end
255
- }
256
- end
257
-
258
- #--
259
- # FIXME: is pk needed as parameter?
260
- #++
261
-
262
- def eval_og_delete(klass)
263
- klass.module_eval %{
264
- def og_delete(store, pk, cascade = true)
265
- #{Glue::Aspects.gen_advice_code(:og_delete, klass.advices, :pre) if klass.respond_to?(:advices)}
266
- pk ||= @#{klass.pk_symbol}
267
- transaction do |tx|
268
- tx.exec "DELETE FROM #{klass.table} WHERE #{klass.pk_symbol}=\#{pk}"
269
- if cascade and #{klass}.__meta[:descendants]
270
- #{klass}.__meta[:descendants].each do |dclass, foreign_key|
271
- tx.exec "DELETE FROM \#{dclass::OGTABLE} WHERE \#{foreign_key}=\#{pk}"
272
- end
273
- end
274
- end
275
- #{Glue::Aspects.gen_advice_code(:og_delete, klass.advices, :post) if klass.respond_to?(:advices)}
276
- end
277
- }
278
- end
279
-
280
- end
281
-
282
- end
283
-
284
- # * George Moschovitis <gm@navel.gr>