og 0.20.0 → 0.21.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/CHANGELOG +796 -664
- data/INSTALL +24 -24
- data/README +39 -32
- data/Rakefile +41 -42
- data/benchmark/bench.rb +36 -36
- data/doc/AUTHORS +15 -12
- data/doc/LICENSE +3 -3
- data/doc/RELEASES +311 -243
- data/doc/config.txt +1 -1
- data/examples/mysql_to_psql.rb +15 -15
- data/examples/run.rb +92 -92
- data/install.rb +7 -17
- data/lib/og.rb +76 -75
- data/lib/og/collection.rb +203 -160
- data/lib/og/entity.rb +168 -169
- data/lib/og/errors.rb +5 -5
- data/lib/og/manager.rb +179 -178
- data/lib/og/mixin/hierarchical.rb +107 -107
- data/lib/og/mixin/optimistic_locking.rb +36 -36
- data/lib/og/mixin/orderable.rb +148 -148
- data/lib/og/mixin/timestamped.rb +8 -8
- data/lib/og/mixin/tree.rb +124 -124
- data/lib/og/relation.rb +237 -213
- data/lib/og/relation/belongs_to.rb +5 -5
- data/lib/og/relation/has_many.rb +60 -58
- data/lib/og/relation/joins_many.rb +93 -47
- data/lib/og/relation/refers_to.rb +25 -21
- data/lib/og/store.rb +210 -207
- data/lib/og/store/filesys.rb +79 -79
- data/lib/og/store/kirby.rb +263 -258
- data/lib/og/store/memory.rb +261 -261
- data/lib/og/store/mysql.rb +288 -284
- data/lib/og/store/psql.rb +261 -244
- data/lib/og/store/sql.rb +873 -720
- data/lib/og/store/sqlite.rb +177 -175
- data/lib/og/store/sqlserver.rb +204 -214
- data/lib/og/types.rb +1 -1
- data/lib/og/validation.rb +57 -57
- data/lib/vendor/mysql.rb +376 -376
- data/lib/vendor/mysql411.rb +10 -10
- data/test/og/mixin/tc_hierarchical.rb +59 -59
- data/test/og/mixin/tc_optimistic_locking.rb +40 -40
- data/test/og/mixin/tc_orderable.rb +67 -67
- data/test/og/mixin/tc_timestamped.rb +19 -19
- data/test/og/store/tc_filesys.rb +46 -46
- data/test/og/tc_inheritance.rb +81 -81
- data/test/og/tc_join.rb +67 -0
- data/test/og/tc_polymorphic.rb +49 -49
- data/test/og/tc_relation.rb +57 -30
- data/test/og/tc_select.rb +49 -0
- data/test/og/tc_store.rb +345 -337
- data/test/og/tc_types.rb +11 -11
- metadata +11 -18
@@ -16,42 +16,42 @@ end
|
|
16
16
|
# http://en.wikipedia.org/wiki/Optimistic_concurrency_control
|
17
17
|
|
18
18
|
module Locking
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
19
|
+
property :lock_version, Fixnum, :default => 0
|
20
|
+
pre "@lock_version = 0", :on => :og_insert
|
21
|
+
|
22
|
+
def self.append_features(base) #:nodoc:
|
23
|
+
PropertyUtils.copy_features(self, base)
|
24
|
+
|
25
|
+
super
|
26
|
+
|
27
|
+
base.module_eval do
|
28
|
+
def self.enchant
|
29
|
+
self.send :alias_method, :update_without_lock, :update
|
30
|
+
self.send :alias_method, :update, :update_with_lock
|
31
|
+
self.send :alias_method, :save_without_lock, :save
|
32
|
+
self.send :alias_method, :save, :save_with_lock
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_with_lock
|
38
|
+
lock = @lock_version
|
39
|
+
@lock_version += 1
|
40
|
+
|
41
|
+
unless update_without_lock(:condition => "lock_version=#{lock}") == 1
|
42
|
+
raise(StaleObjectError, 'Attempted to update a stale object')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def save_with_lock
|
47
|
+
lock = @lock_version
|
48
|
+
@lock_version += 1
|
49
|
+
|
50
|
+
unless save_without_lock(:condition => "lock_version=#{lock}") == 1
|
51
|
+
raise(StaleObjectError, 'Attempted to update a stale object')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
55
|
end
|
56
56
|
|
57
57
|
end
|
data/lib/og/mixin/orderable.rb
CHANGED
@@ -6,154 +6,154 @@ module Og
|
|
6
6
|
|
7
7
|
module Orderable
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
9
|
+
def self.append_dynamic_features(base, options)
|
10
|
+
o = {
|
11
|
+
:position => 'position',
|
12
|
+
:type => Fixnum,
|
13
|
+
}
|
14
|
+
o.update(options) if options
|
15
|
+
|
16
|
+
if o[:scope].is_a?(Symbol) && o[:scope].to_s !~ /_oid$/
|
17
|
+
o[:scope] = "#{o[:scope]}_oid".intern
|
18
|
+
end
|
19
|
+
|
20
|
+
position = o[:position]
|
21
|
+
scope = o[:scope]
|
22
|
+
|
23
|
+
if scope
|
24
|
+
if scope.is_a?(Symbol)
|
25
|
+
scope = %{(#{scope} ? "#{scope} = \#{@#{scope}}" : "#{scope} IS NULL")}
|
26
|
+
end
|
27
|
+
|
28
|
+
cond = 'condition => ' + scope
|
29
|
+
cond_and = ':condition => ' + scope + ' + " AND " +'
|
30
|
+
else
|
31
|
+
cond = ':condition => nil'
|
32
|
+
cond_and = ':condition => '
|
33
|
+
end
|
34
|
+
|
35
|
+
code = %{
|
36
|
+
property :#{position}, #{o[:type]}
|
37
|
+
|
38
|
+
pre "add_to_bottom", :on => :og_insert
|
39
|
+
pre "decrement_position_of_lower_items", :on => :og_delete
|
40
|
+
|
41
|
+
def move_higher
|
42
|
+
if higher = higher_item
|
43
|
+
#{base}.transaction do
|
44
|
+
higher.increment_position
|
45
|
+
decrement_position
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def move_lower
|
51
|
+
if lower = lower_item
|
52
|
+
#{base}.transaction do
|
53
|
+
lower.decrement_position
|
54
|
+
increment_position
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def move_to_top
|
60
|
+
#{base}.transaction do
|
61
|
+
increment_position_of_higher_items
|
62
|
+
set_top_position
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def move_to_bottom
|
67
|
+
#{base}.transaction do
|
68
|
+
decrement_position_of_lower_items
|
69
|
+
set_bottom_position
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def move_to
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_to_top
|
77
|
+
increment_position_of_all_items
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_to_bottom
|
81
|
+
@#{position} = bottom_position + 1
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_to
|
85
|
+
end
|
86
|
+
|
87
|
+
def higher_item
|
88
|
+
#{base}.one(#{cond_and}"#{position}=\#\{@#{position} - 1\}")
|
89
|
+
end
|
90
|
+
alias_method :previous_item, :higher_item
|
91
|
+
|
92
|
+
def lower_item
|
93
|
+
#{base}.one(#{cond_and}"#{position}=\#\{@#{position} + 1\}")
|
94
|
+
end
|
95
|
+
alias_method :next_item, :lower_item
|
96
|
+
|
97
|
+
def top_item
|
98
|
+
end
|
99
|
+
alias_method :first_item, :top_item
|
100
|
+
|
101
|
+
def bottom_item
|
102
|
+
#{base}.one(#{cond}, :order => "#{position} DESC", :limit => 1)
|
103
|
+
end
|
104
|
+
alias_method :last_item, :last_item
|
105
|
+
|
106
|
+
def top?
|
107
|
+
@#{position} == 1
|
108
|
+
end
|
109
|
+
alias_method :first?, :top?
|
110
|
+
|
111
|
+
def bottom?
|
112
|
+
@#{position} == bottom_position
|
113
|
+
end
|
114
|
+
alias_method :last?, :bottom?
|
115
|
+
|
116
|
+
def increment_position
|
117
|
+
@#{position} += 1
|
118
|
+
update(:only=>[:#{position}])
|
119
|
+
end
|
120
|
+
|
121
|
+
def decrement_position
|
122
|
+
@#{position} -= 1
|
123
|
+
update(:only=>[:#{position}])
|
124
|
+
end
|
125
|
+
|
126
|
+
def bottom_position
|
127
|
+
item = bottom_item
|
128
|
+
item ? item.#{position} : 0
|
129
|
+
end
|
130
|
+
|
131
|
+
def set_top_position
|
132
|
+
@#{position} = 1
|
133
|
+
update(:only=>[:#{position}])
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_bottom_position
|
137
|
+
@#{position} = bottom_position + 1
|
138
|
+
update(:only=>[:#{position}])
|
139
|
+
end
|
140
|
+
|
141
|
+
def increment_position_of_higher_items
|
142
|
+
#{base}.update_property("#{position}=(#{position} + 1)", #{cond_and}"#{position} < \#\{@#{position}\}")
|
143
|
+
end
|
144
|
+
|
145
|
+
def increment_position_of_all_items
|
146
|
+
#{base}.update_property("#{position}=(#{position} + 1)", #{cond})
|
147
|
+
end
|
148
|
+
|
149
|
+
def decrement_position_of_lower_items
|
150
|
+
#{base}.update_property("#{position}=(#{position} - 1)", #{cond_and}"#{position} > \#\{@#{position}\}")
|
151
|
+
end
|
152
|
+
}
|
153
|
+
|
154
|
+
base.module_eval(code)
|
155
|
+
end
|
156
|
+
|
157
157
|
end
|
158
158
|
|
159
159
|
end
|
data/lib/og/mixin/timestamped.rb
CHANGED
@@ -3,16 +3,16 @@ module Og
|
|
3
3
|
# Adds timestamping functionality.
|
4
4
|
|
5
5
|
module Timestamped
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
property :create_time, Time
|
7
|
+
property :update_time, Time
|
8
|
+
property :access_time, Time
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
pre "@create_time = @update_time = Time.now", :on => :og_insert
|
11
|
+
pre "@update_time = Time.now", :on => :og_update
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def touch!
|
14
|
+
@access_time = Time.now
|
15
|
+
end
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
data/lib/og/mixin/tree.rb
CHANGED
@@ -11,16 +11,16 @@ module Og
|
|
11
11
|
# article (http://www.dbazine.com/tropashko4.shtml)
|
12
12
|
|
13
13
|
module TreeTraversal
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
|
15
|
+
# The default prefix for the tree traversal helpers.
|
16
|
+
|
17
|
+
cattr_accessor :prefix, 'tree'
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
def self.child(sum, n)
|
20
|
+
power = 2 ** n
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
return sum * power
|
23
|
+
end
|
24
24
|
|
25
25
|
end
|
26
26
|
|
@@ -30,15 +30,15 @@ end
|
|
30
30
|
__END__
|
31
31
|
|
32
32
|
def xcoord(numer, denom)
|
33
|
-
|
34
|
-
|
33
|
+
num = numer + 1
|
34
|
+
den = denom * 2
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
while (num / 2).floor == (num / 2)
|
37
|
+
num /= 2
|
38
|
+
den /= 2
|
39
|
+
end
|
40
40
|
|
41
|
-
|
41
|
+
return num, den
|
42
42
|
end
|
43
43
|
|
44
44
|
#--
|
@@ -46,111 +46,111 @@ end
|
|
46
46
|
#++
|
47
47
|
|
48
48
|
def ycoord(numer, denom)
|
49
|
-
|
49
|
+
num, den = xcoord(numer, denom)
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
while den < denom
|
52
|
+
num *= 2
|
53
|
+
den *= 2
|
54
|
+
end
|
55
55
|
|
56
|
-
|
56
|
+
num = numer - num
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
while (num / 2).floor == (num / 2)
|
59
|
+
num /= 2
|
60
|
+
den /= 2
|
61
|
+
end
|
62
62
|
|
63
|
-
|
63
|
+
return num, den
|
64
64
|
end
|
65
65
|
|
66
66
|
def parent(numer, denom)
|
67
|
-
|
67
|
+
return nil if numer == 3
|
68
68
|
|
69
|
-
|
70
|
-
|
69
|
+
num = (numer - 1) / 2
|
70
|
+
den = denom / 2
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
72
|
+
while ((num-1)/4).floor == ((num-1)/4)
|
73
|
+
num = (num + 1) / 2
|
74
|
+
den = den / 2
|
75
|
+
end
|
76
|
+
|
77
|
+
return num, den
|
78
78
|
end
|
79
79
|
|
80
80
|
def sibling(numer, denom)
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
81
|
+
return nil if numer == 3
|
82
|
+
|
83
|
+
num = (numer - 1) / 2
|
84
|
+
den = denom / 2
|
85
|
+
sib = 1
|
86
|
+
|
87
|
+
while ((num-1)/4).floor == ((num-1)/4)
|
88
|
+
return sib if num == 1 and den == 1
|
89
|
+
num = (num + 1) / 2
|
90
|
+
den /= 2
|
91
|
+
sib += 1
|
92
|
+
end
|
93
|
+
|
94
|
+
return sib
|
95
95
|
end
|
96
96
|
|
97
97
|
def child(numer, denom, n)
|
98
|
-
|
98
|
+
power = 2 ** n
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
num = (numer * power) + 3 - power
|
101
|
+
den = denom * power
|
102
102
|
|
103
|
-
|
103
|
+
return num, den
|
104
104
|
end
|
105
105
|
|
106
106
|
def path(numer, denom)
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
return '' if numer == nil
|
108
|
+
n, d = parent(numer, denom)
|
109
|
+
return "#{path(n, d)}.#{sibling(numer, denom)}"
|
110
110
|
end
|
111
111
|
|
112
112
|
def encode(path)
|
113
|
-
|
114
|
-
|
113
|
+
num = den = 1
|
114
|
+
postfix = ".#{path}."
|
115
115
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
while postfix.length > 1
|
117
|
+
sibling, postfix = postfix.split('.', 2)
|
118
|
+
num, den = child(num, den, sibling.to_i)
|
119
|
+
end
|
120
120
|
|
121
|
-
|
121
|
+
return num, den
|
122
122
|
end
|
123
123
|
|
124
124
|
|
125
125
|
require 'og'
|
126
126
|
|
127
127
|
class Comment
|
128
|
-
|
129
|
-
|
128
|
+
property :path, String
|
129
|
+
property :x, :y, Float
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
131
|
+
def initialize(path = nil, x = nil, y = nil)
|
132
|
+
@path, @x, @y = path, x, y
|
133
|
+
end
|
134
134
|
end
|
135
135
|
|
136
136
|
Og::Database.new(
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
137
|
+
:database => 'test',
|
138
|
+
:adapter => 'psql',
|
139
|
+
:user => 'postgres',
|
140
|
+
:password => 'navelrulez',
|
141
|
+
:connection_count => 1,
|
142
|
+
:drop => true
|
143
143
|
)
|
144
144
|
|
145
145
|
def dp(path)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
146
|
+
n, d = encode(path)
|
147
|
+
n, d = Float(n), Float(d)
|
148
|
+
# puts "#{path} -> n: #{n} d: #{d} c: #{n/d}"
|
149
|
+
p = path(n, d)
|
150
|
+
# puts "=== #{p}"
|
151
|
+
xn, xd = xcoord(n, d)
|
152
|
+
yn, yd = ycoord(n, d)
|
153
|
+
Comment.create(path, xn/xd, yn/yd)
|
154
154
|
end
|
155
155
|
|
156
156
|
dp '1.1'
|
@@ -168,20 +168,20 @@ dp '1.5'
|
|
168
168
|
dp '1.5.1'
|
169
169
|
|
170
170
|
for c in Comment.all('ORDER BY x DESC, y ASC')
|
171
|
-
|
171
|
+
puts "#{c.path.ljust(16)}#{c.inspect}"
|
172
172
|
end
|
173
173
|
|
174
174
|
class Article
|
175
|
-
|
176
|
-
|
175
|
+
property :title, :body, String
|
176
|
+
has_many: :comments, Comment, :tree => true
|
177
177
|
end
|
178
178
|
|
179
179
|
class Comment
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
180
|
+
property :body, String
|
181
|
+
belongs_to :article, Article
|
182
|
+
belongs_to :parent, Comment
|
183
|
+
has_many :children, Comment, :tree => true
|
184
|
+
has_many :roles, Role, :list => true
|
185
185
|
end
|
186
186
|
|
187
187
|
|
@@ -190,37 +190,37 @@ comment.add_child(Comment.new('hello'))
|
|
190
190
|
comment.children_tree
|
191
191
|
comment.children
|
192
192
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
193
|
+
if options[:tree]
|
194
|
+
code << %{
|
195
|
+
property :#{prefix}_x, Fixnum
|
196
|
+
property :#{prefix}_y, Fixnum
|
197
|
+
sql_index '#{prefix}_x, #{prefix}_y'
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
if options[:tree]
|
202
|
+
|
203
|
+
code << %{
|
204
|
+
def #{name}_tree(extrasql = nil)
|
205
|
+
Og.db.select("SELECT * FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\} ORDER BY #{prefix}_x DESC, #{prefix}_y ASC", #{klass})
|
206
|
+
end
|
207
|
+
}
|
208
|
+
|
209
|
+
elsif options[:list]
|
210
|
+
|
211
|
+
else
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
}
|
216
|
+
|
217
|
+
if options[:tree]
|
218
|
+
code << %{
|
219
|
+
n = Og.db.count("#{linkback}=\#\@oid", #{klass})
|
220
|
+
ptx = @#{prefix}_x || 0
|
221
|
+
pty = @#{prefix}_y || 0
|
222
|
+
obj.#{prefix}_x, obj.#{prefix}_y = TreeTraversal.child(ptx + pty, n)
|
223
|
+
}
|
224
|
+
end
|
225
|
+
|
226
|
+
code << %{
|