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 << %{