Metadata-Version: 1.1
Name: Fangorn
Version: 0.2.1
Summary: Nested Sets SQL Tree for Python
Home-page: http://code.google.com/p/fangorn-py/
Author: saaj
Author-email: mail@saaj.me
License: LGPL
Description: 
        *******
        Fangorn
        *******
        
        Nested Sets aka Modified Pre-order Tree Traversal (MPTT) *SQL* tree implemented in Python 
        for *MySQL* and *SQLite*. Uses both traversal markup (left, right) and adjacency list 
        parentId for more ad-hoc query flexibility. 
        
        Provides tree structure validation and "memorization" via SQLite *:memory:* for quick reads. 
        
        Example
        =======
        
        We want to achieve the following tree. Node is represented by ``name id->parentId (l, r)``. 
        To output a tree this way ``fangorn.test.visualize`` function can be used. 
        
        .. code-block::
        
          R 1->None (1, 18)
          └─A1 2->1 (2, 5)
            └─B1 3->2 (3, 4)
          └─A2 4->1 (6, 13)
            └─B2 5->4 (7, 8)
            └─B3 6->4 (9, 12)
              └─C1 7->6 (10, 11)
          └─A3 8->1 (14, 17)
            └─B4 9->8 (15, 16)
        
        First we need a table to represent the tree. And we want a tree node to have a name.    
        
        .. code-block:: python
        
          import MySQLdb as mysql
          conn = mysql.connect(user = 'guest', db = 'test')
          conn.query('''
            CREATE TABLE `node` (
              `node_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
              `parent_id` int(10) unsigned DEFAULT NULL,
              `l` int(10) unsigned NOT NULL,
              `r` int(10) unsigned NOT NULL,
              `name` varchar(8) NOT NULL,
              PRIMARY KEY (`node_id`),
              KEY `l` (`l`),
              KEY `r` (`r`),
              KEY `parent_id` (`parent_id`),
              CONSTRAINT `node_has_node` FOREIGN KEY (`parent_id`)
                REFERENCES `node` (`node_id`)
                ON DELETE CASCADE
                ON UPDATE CASCADE
            ) ENGINE=InnoDB;
          ''')
        
        Now we can create tree instance. Note that DAO that the tree relies on is expected to support 
        *named* DB-API paramstyle (i.e. `WHERE nodeId = :nodeId`). Also transaction control methods 
        are recommended to implement nested transaction support. However testsuite requires nested 
        transactions to run. For `MySQLdb` and `sqlite3` there're compatibility wrappers under 
        `fangorn.compat`. 
        
        .. code-block:: python
        
          import fangorn
          from fangorn.compat.mysqldb import Mysqldb as MysqldbWrapper
          tree = fangorn.NestedSetsTree(MysqldbWrapper(conn), 'node', ('name',))
          
          rId  = tree.add(dict(name = 'R'))
          a1Id = tree.add(dict(name = 'A1'), parentId = rId)
          tree.add(dict(name = 'B1'), parentId = a1Id)
          a2Id = tree.add(dict(name = 'A2'), parentId = rId)
          b2Id = tree.add(dict(name = 'B2'), parentId = a2Id)
          b3Id = tree.add(dict(name = 'B3'), prevId = b2Id)
          tree.add(dict(name = 'C1'), parentId = b3Id)
          a3Id = tree.add(dict(name = 'A3'), parentId = rId)
          tree.add(dict(name = 'B4'), parentId = a3Id)
          
          tree.move(a1Id, rId)
          tree.move(a3Id, prevId = a2Id)
          
        Now we can play with the tree.
        
        .. code-block:: python
        
          print tree.isDescendantOf(a2Id, 4) # False
          print tree.isDescendantOf(a2Id, 6) # True
          print tree.isDescendantOf(a2Id, 7) # True
          print tree.isDescendantOf(a2Id, 9) # False
        
          print [n['name'] for n in tree.getChildren(a2Id)]    # ['B2', 'B3']
          print [n['name'] for n in tree.getDescendants(a2Id)] # ['B2', 'B3', 'C1']
          print [n['name'] for n in tree.getPath(7)]           # ['R', 'A2', 'B3', 'C1']
        
          print tree.getNode(8)   # {'left': 14L, 'right': 17L, 'nodeId': 8L, 'name': 'A3', 'parentId': 1L}
          print tree.getParent(8) # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'R', 'parentId': None}
          print tree.getRoot()    # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'R', 'parentId': None}
        
          tree.edit(1, dict(name = 'RR'))
          print tree.getRoot() # {'left': 1L, 'right': 18L, 'nodeId': 1L, 'name': 'RR', 'parentId': None}
        
          print [n['name'] for n in tree.getDescendants(a2Id)] # ['B2', 'B3', 'C1']
          tree.remove(b3Id)
          print [n['name'] for n in tree.getDescendants(a2Id)] # ['B2']
          
        
        For more usage examples look at project's 
        `test suite <http://code.google.com/p/fangorn-py/source/browse/#hg%2Ffangorn%2Ftest>`_.
Platform: Any
Classifier: Topic :: Database
Classifier: Programming Language :: Python :: 2.7
Classifier: Intended Audience :: Developers
