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.
- data/ProjectInfo +2 -2
- data/README +1 -1
- data/doc/RELEASES +34 -0
- data/lib/glue/cacheable.rb +3 -1
- data/lib/glue/hierarchical.rb +3 -3
- data/lib/glue/orderable.rb +1 -1
- data/lib/glue/taggable.rb +71 -21
- data/lib/glue/timestamped.rb +2 -2
- data/lib/og.rb +16 -3
- data/lib/og/entity.rb +58 -10
- data/lib/og/ez/clause.rb +2 -1
- data/lib/og/manager.rb +38 -7
- data/lib/og/relation/joins_many.rb +1 -1
- data/lib/og/store/mysql.rb +2 -18
- data/lib/og/store/psql.rb +2 -1
- data/lib/og/store/sql.rb +79 -26
- data/lib/og/test/assertions.rb +1 -1
- data/lib/og/test/testcase.rb +3 -3
- data/test/glue/tc_revisable.rb +1 -1
- data/test/og/mixin/tc_hierarchical.rb +2 -0
- data/test/og/mixin/tc_orderable.rb +2 -3
- data/test/og/mixin/tc_taggable.rb +8 -11
- data/test/og/mixin/tc_timestamped.rb +1 -1
- data/test/og/store/tc_sti.rb +53 -0
- data/test/og/tc_aggregations_calculations.rb +44 -0
- data/test/og/tc_cacheable.rb +164 -29
- data/test/og/tc_inheritance.rb +4 -1
- data/test/og/tc_multi_validations.rb +1 -0
- data/test/og/tc_override.rb +6 -0
- metadata +11 -10
- data/lib/og/store/alpha/kirby.rb +0 -284
data/test/og/tc_cacheable.rb
CHANGED
@@ -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
|
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 =
|
26
|
-
|
27
|
-
|
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
|
-
|
32
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
116
|
+
assert_equal u, @og.cache.get(u.og_cache_key), msg
|
39
117
|
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
+
|
data/test/og/tc_inheritance.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/test/og/tc_override.rb
CHANGED
@@ -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.
|
7
|
-
date: 2006-
|
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:
|
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.
|
158
|
+
version: 0.29.0
|
158
159
|
version:
|
data/lib/og/store/alpha/kirby.rb
DELETED
@@ -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>
|