Hello Jeremy

Thank you for your advice. 

I'll think to store the path as a column.
It seems faster then rcte_tree for search path.

But I'm wondering move operation slower than rcte_tree 

So I would like to know much about rcte_tree plugin.

Question
  Could you tell me common method to find specified node like ("/a/b/c") 
with rcte_tree?
  Please tell me if you know alternative approach.

  I implemented two method. (find_node_recursive and find_node_ancestors)

  Is it possible to use ancestors method for that? 
  (Is it return sorted node list?) 
 
Thanks 
--
Hiroyuki Sato.


P.S. 
   FYI
  rcte_tree plugin does not work OSX marveriks until install sqlite3 >= 
3.8.3 by myself.
  bundled version is 3.7.13 and it does not support supports common table 
expressions.

require 'sqlite3'
require 'sequel'
require 'pp'

def traverse_to_root(node,path)
  path << node.name 
  traverse_to_root(node.parent,path) if node.parent
end

def find_node_recursive(search_path)
  last_node = search_path.split('/')[-1]

  match_node = nil

  FileTree.filter("name = ?",last_node).each do |node|
    nodes = []
    traverse_to_root(node,nodes)
    cur_path = nodes.reverse.join("/")
    if( cur_path == search_path )
      match_node = node
      break
    end
  end
  match_node
end

def find_node_ancestors(search_path)
  last_node = search_path.split('/')[-1]

  match_node = nil

  FileTree.filter("name = ?",last_node).each do |node|
    #
    # node.ancestors return sorted lists?
    #
    cur_path = [node.ancestors.reverse.map(&:name),node.name].join("/")
    if( cur_path == search_path )
      match_node = node
      break
    end
  end
  match_node
end

dbpath = File.expand_path(File.dirname(__FILE__),"tree.db")

DB = Sequel.connect("sqlite://#{dbpath}")


unless DB.table_exists?(:file_trees)

  # create table
  DB.create_table :file_trees do
    primary_key :id
    String  :name
    Integer :uid
    Integer :gid
    foreign_key :parent_id, :file_trees
  end

end

class FileTree < Sequel::Model
  plugin :rcte_tree, :single_root => true
end

#
#  / +- a
#    +- b
#       +- c
#          +- f
#       +- d
#       +- e
#
unless FileTree.root
  FileTree.create(:name => "")
  FileTree.create(:name => "a",:parent_id => FileTree.root.id)
  b = FileTree.create(:name => "b",:parent_id => FileTree.root.id)
  c = FileTree.create(:name => "c",:parent_id => b.id)
  FileTree.create(:name => "d",:parent_id => b.id)
  FileTree.create(:name => "e",:parent_id => b.id)
  f = FileTree.create(:name => "f",:parent_id => c.id)

end


node_f = find_node_recursive("/b/c/f")
pp node_f

node_f = find_node_ancestors("/b/c/f")
pp node_f

----- output 
#<FileTree @values={:id=>7, :name=>"f", :uid=>nil, :gid=>nil, 
:parent_id=>4}>
#<FileTree @values={:id=>7, :name=>"f", :uid=>nil, :gid=>nil, 
:parent_id=>4}>



2014年6月27日金曜日 0時08分24秒 UTC+9 Jeremy Evans:
>
> On Thursday, June 26, 2014 6:22:01 AM UTC-7, Hiroyuki Sato wrote:
>>
>> Dear members.
>>
>> I'm newbie Sequel.
>>   Could you tell me best approach and example to represent Unix directory
>> hierarchy with Sequel and Sqlite3?
>>
>> Especially, I would like to know the following
>>
>>   How to find '/path/to/deepchild' node with small cost.
>>   
>> It's tree, and I found rcte_tree plugin. and I wrote the following code.
>>
>> Alternatively, Should I uses "Nested Sets Model" for that?
>>
>> Sincerely. 
>>
>>     require 'sqlite3'
>>     require 'sequel'
>>     require 'pp'
>>     
>>     dbpath = File.expand_path(File.dirname(__FILE__),"tree.db")
>>     
>>     DB = Sequel.connect("sqlite://#{dbpath}")
>>     
>>     
>>     unless DB.table_exists?(:file_trees)
>>     
>>       # create table
>>       DB.create_table :file_trees do
>>         primary_key :id
>>         String  :name
>>         Integer :uid
>>         Integer :gid
>>         # And some attributes
>>         Numeric :parent_id
>>
>
> Note that using Numeric here is a bad idea.  This is a relationship, you 
> want to use foreign_key:
>
>   foreign_key :parent_id, :file_trees
>  
>
>>       end
>>     
>>     end
>>     
>>     class FileTree < Sequel::Model
>>       plugin :rcte_tree, :single_root => true
>>     end
>>     
>>     FileTree.create(:name => "root")
>>     FileTree.create(:name => "child",:parent_id => FileTree.root.id)
>>
>> My Goal
>>
>> represent common file operation logging like the following.
>>
>>   * create new node in '/path/to/deepchild'
>>   * list child in '/path/to/deepchild'
>>   * move node from '/path/to/a' to '/new/path/b' 
>>   * remove node '/path/to/a' and child.
>>   * copy node '/path/to/a' to '/new/path/to/b'
>>
>
> Using rcte_tree should work. An alternative approach is just to store the 
> path as a column (either instead of or in addition to the name column). 
>  With an index on the path, most directory operations should be fast, 
> probably faster than rcte_tree in some use cases and slower in others. 
> Doing this means you don't need to store a foreign key to the parent, you 
> just operate on the path. Not sure which way is better.
>
> Thanks,
> Jeremy
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to