Hi,

I started a nested sets implementation
Just sharing the code. I welcome any thoughts you have

2 files - nstree_controller (just quick and dirty tests of the model),
and nstree_model

[nstree_controller :]

t1 = nstree(db, db.tree1)

def index():
    return dict(message="Version " + nstree.version)

def test_path():
    _id = 33
    return dict(message = " > ".join([node.name for node in t1.path
(_id)]))

def test_removetree():
    _id = request.vars.id if request.vars.id else 3
    t1.remove_tree(_id)
    return dict(message="Success")

def test_delete():
    _id = request.vars.id if request.vars.id else 19
    node = t1.delete(_id)
    return dict(message= node.name + " deleted ")

def test_get():
    _id = request.vars.id if request.vars.id else 15
    #nodes = t1.ancestors(_id)
    #nodes = t1.descendants(_id)
    nodes = t1.children(_id)
    return dict(message= ", ".join([node.name for node in nodes]))

def test_gettree():
    root_id = request.vars.root_id if request.vars.root_id else 1
    nodes = t1.tree(root_id)
    return dict(message="Count "+str(len(nodes)))

def test_add():
    root_id = request.vars.root_id if request.vars.root_id else
t1.roots()[0].id
    r1 = t1.add(root_id, name='1')
    r2 = t1.add(root_id, name='2')
    r3 = t1.add(root_id, name='3')
    t1.add(r1, name='11')
    t1.add(r1, name='12')
    return dict(message="Success")

def test_create_roots():
    '''
    t1.create_root(name='root1')
    t1.create_root(name='root2')
    t1.create_root(name='root3')
    t1.create_root(name='root4')
    '''
    roots = t1.roots()
    return dict(message="Roots count : " + str(len(roots)))


[nstree_model:]

db.define_table('tree1',
    SQLField('name', "string", 128),
    SQLField('lft','integer'),
    SQLField('rgt','integer'),
    SQLField('level','integer'),
    SQLField('root_id','integer'),
    SQLField('parent_id','reference tree1'),
    )
#
#  A Nested Sets implementation
#  need to pass a table with following fields:
#  lft, rgt, level, parent_id, root_id - all fields of type int
#  -------
#  Notes:
#  - table can contain multiple roots
#
class nstree:
    version = "1.0.0.04"
    def __init__(self, db, dbtable):
        self.db = db
        self.dbtable = dbtable
        #self.lft = dbtable.lft
        #self.rgt = dbtable.rgt
        #self.level = dbtable.level
        #self.parent_id = dbtable.parent_id
        #self.root_id = dbtable.root_id
    #
    #  Methods for building tree (create, delete nodes)
    #
    def create_root(self, **fields):
        _id = self.dbtable.insert(lft=1, rgt=2, level=0, **fields)
        _root = self.dbtable[_id]
        _root.update_record(root_id  = _id)
        return _root
    def add(self, parent_id, **fields): return self.add_last_child
(parent_id, **fields)
    def add_last_child(self, parent_id, **fields):
        _parent = self.dbtable[parent_id]
        q1 = self.dbtable.rgt >= _parent.rgt
        q2 = self.dbtable.lft >= _parent.rgt
        q3 = self.dbtable.root_id == _parent.root_id
        self.db(q1)(q3).update(rgt=self.dbtable.rgt+2)
        self.db(q2)(q3).update(lft=self.dbtable.lft+2)
        return self.dbtable.insert(
            parent_id = parent_id,
            lft = _parent.rgt,
            rgt = _parent.rgt+1,
            level = _parent.level+1,
            root_id = _parent.root_id,
            **fields
        )
    def delete(self, id): return self.remove(id)
    def remove(self, id):
        node = self.dbtable[id]
        delta = node.rgt - node.lft + 1
        q1 = self.dbtable.lft >= node.lft
        q2 = self.dbtable.rgt <= node.rgt
        self.db(q1)(q2).delete()
        self.db(self.dbtable.lft > node.rgt).update(lft =
self.dbtable.lft - delta)
        self.db(self.dbtable.rgt > node.rgt).update(rgt =
self.dbtable.rgt - delta)
        return node
    def remove_descendants(self, id):
        node = self.dbtable[id]
        delta = node.rgt - node.lft + 1
        q1 = self.dbtable.lft > node.lft
        q2 = self.dbtable.rgt < node.rgt
        self.db(q1)(q2).delete()
        self.db(self.dbtable.lft > node.rgt).update(lft =
self.dbtable.lft - delta)
        self.db(self.dbtable.rgt > node.rgt).update(rgt =
self.dbtable.rgt - delta)
    def remove_tree(self, id):
        self.db(self.dbtable.root_id == id).delete()
    #
    #  Methods for retrieving nodes
    #
    def roots(self): return self.db(self.dbtable.lft == 1).select()
    def tree(self, root_id): return self.db(self.dbtable.root_id ==
root_id).select(orderby = self.dbtable.lft)
    def ancestors(self, id):
        node = self.dbtable[id]
        q1 = self.dbtable.lft < node.lft
        q2 = self.dbtable.rgt > node.rgt
        q3 = self.dbtable.root_id == node.root_id
        return self.db(q1)(q2)(q3).select(orderby = self.dbtable.lft)
    def path(self, id):
        node = self.dbtable[id]
        q1 = self.dbtable.lft <= node.lft
        q2 = self.dbtable.rgt >= node.rgt
        q3 = self.dbtable.root_id == node.root_id
        return self.db(q1)(q2)(q3).select(orderby = self.dbtable.lft)
    def descendants(self, id):
        node = self.dbtable[id]
        q1 = self.dbtable.lft > node.lft
        q2 = self.dbtable.rgt < node.rgt
        q3 = self.dbtable.root_id == node.root_id
        return self.db(q1)(q2)(q3).select(orderby = self.dbtable.lft)
    def children(self, id): return self.db(self.dbtable.parent_id ==
id).select(orderby = self.dbtable.lft)
    #
    #  Methods for checking or getting state of node(s)
    #
    def num_children(self, node): return int((node.rgt-node.lft-1)/2)
    def is_root(self, node): return node.id == node.root_id
    def is_leaf(self, node): return node.lft == node.rgt-1
    def is_child(self, node1, node2): return node1.lft > node2.lft
and node1.rgt < node2.rgt

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To post to this group, send email to web2py@googlegroups.com
To unsubscribe from this group, send email to 
web2py+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to