lib/og/mixin/tree.rb in og-0.20.0 vs lib/og/mixin/tree.rb in og-0.21.0
- old
+ new
@@ -9,150 +9,150 @@
# A useful encapsulation of the nested intervals pattern for
# hierarchical SQL queries. Slightly adapted from the original
# article (http://www.dbazine.com/tropashko4.shtml)
module TreeTraversal
-
- # The default prefix for the tree traversal helpers.
-
- cattr_accessor :prefix, 'tree'
+
+ # The default prefix for the tree traversal helpers.
+
+ cattr_accessor :prefix, 'tree'
- def self.child(sum, n)
- power = 2 ** n
+ def self.child(sum, n)
+ power = 2 ** n
- return sum * power
- end
+ return sum * power
+ end
end
end
__END__
def xcoord(numer, denom)
- num = numer + 1
- den = denom * 2
+ num = numer + 1
+ den = denom * 2
- while (num / 2).floor == (num / 2)
- num /= 2
- den /= 2
- end
+ while (num / 2).floor == (num / 2)
+ num /= 2
+ den /= 2
+ end
- return num, den
+ return num, den
end
#--
# TODO: optimize this
#++
def ycoord(numer, denom)
- num, den = xcoord(numer, denom)
+ num, den = xcoord(numer, denom)
- while den < denom
- num *= 2
- den *= 2
- end
+ while den < denom
+ num *= 2
+ den *= 2
+ end
- num = numer - num
+ num = numer - num
- while (num / 2).floor == (num / 2)
- num /= 2
- den /= 2
- end
+ while (num / 2).floor == (num / 2)
+ num /= 2
+ den /= 2
+ end
- return num, den
+ return num, den
end
def parent(numer, denom)
- return nil if numer == 3
+ return nil if numer == 3
- num = (numer - 1) / 2
- den = denom / 2
+ num = (numer - 1) / 2
+ den = denom / 2
- while ((num-1)/4).floor == ((num-1)/4)
- num = (num + 1) / 2
- den = den / 2
- end
-
- return num, den
+ while ((num-1)/4).floor == ((num-1)/4)
+ num = (num + 1) / 2
+ den = den / 2
+ end
+
+ return num, den
end
def sibling(numer, denom)
- return nil if numer == 3
+ return nil if numer == 3
- num = (numer - 1) / 2
- den = denom / 2
- sib = 1
-
- while ((num-1)/4).floor == ((num-1)/4)
- return sib if num == 1 and den == 1
- num = (num + 1) / 2
- den /= 2
- sib += 1
- end
-
- return sib
+ num = (numer - 1) / 2
+ den = denom / 2
+ sib = 1
+
+ while ((num-1)/4).floor == ((num-1)/4)
+ return sib if num == 1 and den == 1
+ num = (num + 1) / 2
+ den /= 2
+ sib += 1
+ end
+
+ return sib
end
def child(numer, denom, n)
- power = 2 ** n
+ power = 2 ** n
- num = (numer * power) + 3 - power
- den = denom * power
+ num = (numer * power) + 3 - power
+ den = denom * power
- return num, den
+ return num, den
end
def path(numer, denom)
- return '' if numer == nil
- n, d = parent(numer, denom)
- return "#{path(n, d)}.#{sibling(numer, denom)}"
+ return '' if numer == nil
+ n, d = parent(numer, denom)
+ return "#{path(n, d)}.#{sibling(numer, denom)}"
end
def encode(path)
- num = den = 1
- postfix = ".#{path}."
+ num = den = 1
+ postfix = ".#{path}."
- while postfix.length > 1
- sibling, postfix = postfix.split('.', 2)
- num, den = child(num, den, sibling.to_i)
- end
+ while postfix.length > 1
+ sibling, postfix = postfix.split('.', 2)
+ num, den = child(num, den, sibling.to_i)
+ end
- return num, den
+ return num, den
end
require 'og'
class Comment
- property :path, String
- property :x, :y, Float
+ property :path, String
+ property :x, :y, Float
- def initialize(path = nil, x = nil, y = nil)
- @path, @x, @y = path, x, y
- end
+ def initialize(path = nil, x = nil, y = nil)
+ @path, @x, @y = path, x, y
+ end
end
Og::Database.new(
- :database => 'test',
- :adapter => 'psql',
- :user => 'postgres',
- :password => 'navelrulez',
- :connection_count => 1,
- :drop => true
+ :database => 'test',
+ :adapter => 'psql',
+ :user => 'postgres',
+ :password => 'navelrulez',
+ :connection_count => 1,
+ :drop => true
)
def dp(path)
- n, d = encode(path)
- n, d = Float(n), Float(d)
- # puts "#{path} -> n: #{n} d: #{d} c: #{n/d}"
- p = path(n, d)
- # puts "=== #{p}"
- xn, xd = xcoord(n, d)
- yn, yd = ycoord(n, d)
- Comment.create(path, xn/xd, yn/yd)
+ n, d = encode(path)
+ n, d = Float(n), Float(d)
+ # puts "#{path} -> n: #{n} d: #{d} c: #{n/d}"
+ p = path(n, d)
+ # puts "=== #{p}"
+ xn, xd = xcoord(n, d)
+ yn, yd = ycoord(n, d)
+ Comment.create(path, xn/xd, yn/yd)
end
dp '1.1'
dp '1.2'
dp '1.3'
@@ -166,61 +166,61 @@
dp '1.2.1.2'
dp '1.5'
dp '1.5.1'
for c in Comment.all('ORDER BY x DESC, y ASC')
- puts "#{c.path.ljust(16)}#{c.inspect}"
+ puts "#{c.path.ljust(16)}#{c.inspect}"
end
class Article
- property :title, :body, String
- has_many: :comments, Comment, :tree => true
+ property :title, :body, String
+ has_many: :comments, Comment, :tree => true
end
class Comment
- property :body, String
- belongs_to :article, Article
- belongs_to :parent, Comment
- has_many :children, Comment, :tree => true
- has_many :roles, Role, :list => true
+ property :body, String
+ belongs_to :article, Article
+ belongs_to :parent, Comment
+ has_many :children, Comment, :tree => true
+ has_many :roles, Role, :list => true
end
article.comments_tree
comment.add_child(Comment.new('hello'))
comment.children_tree
comment.children
- if options[:tree]
- code << %{
- property :#{prefix}_x, Fixnum
- property :#{prefix}_y, Fixnum
- sql_index '#{prefix}_x, #{prefix}_y'
- }
- end
+ if options[:tree]
+ code << %{
+ property :#{prefix}_x, Fixnum
+ property :#{prefix}_y, Fixnum
+ sql_index '#{prefix}_x, #{prefix}_y'
+ }
+ end
- if options[:tree]
+ if options[:tree]
- code << %{
- def #{name}_tree(extrasql = nil)
- Og.db.select("SELECT * FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\} ORDER BY #{prefix}_x DESC, #{prefix}_y ASC", #{klass})
- end
- }
+ code << %{
+ def #{name}_tree(extrasql = nil)
+ Og.db.select("SELECT * FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\} ORDER BY #{prefix}_x DESC, #{prefix}_y ASC", #{klass})
+ end
+ }
- elsif options[:list]
+ elsif options[:list]
- else
+ else
- end
+ end
- }
-
- if options[:tree]
- code << %{
- n = Og.db.count("#{linkback}=\#\@oid", #{klass})
- ptx = @#{prefix}_x || 0
- pty = @#{prefix}_y || 0
- obj.#{prefix}_x, obj.#{prefix}_y = TreeTraversal.child(ptx + pty, n)
- }
- end
-
- code << %{
+ }
+
+ if options[:tree]
+ code << %{
+ n = Og.db.count("#{linkback}=\#\@oid", #{klass})
+ ptx = @#{prefix}_x || 0
+ pty = @#{prefix}_y || 0
+ obj.#{prefix}_x, obj.#{prefix}_y = TreeTraversal.child(ptx + pty, n)
+ }
+ end
+
+ code << %{