og 0.28.0 → 0.29.0

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