3 import IdGenerator, Node, DBImpl
5 """Class manages tag tree. Note: tree name is not case sensitive.
6 Tree name is always converted to upper case
13 self.
__tagTreeTableColumns = {
'nodeid':
'unsigned long',
'nodelabel':
'string',
'lft':
'unsigned long',
'rgt':
'unsigned long',
'parentid':
'unsigned long',
'tagid':
'unsigned long',
'globalsince':
'unsigned long long',
'globaltill':
'unsigned long long'}
18 """Check if tree table exists
20 transaction=self.__session.transaction()
22 transaction.start(
True)
23 schema = self.__session.nominalSchema()
28 transaction.rollback()
29 raise Exception, str(er)
32 """Create tag tree table. Existing table will be deleted.
34 transaction=self.__session.transaction()
36 transaction.start(
False)
37 schema = self.__session.nominalSchema()
39 description = coral.TableDescription();
41 for columnName, columnType
in self.__tagTreeTableColumns.items():
42 description.insertColumn(columnName, columnType)
44 description.setNotNullConstraint(columnName,
True)
46 description.setUniqueConstraint(columnName)
50 self.__tagTreeTableHandle.privilegeManager().grantToPublic( coral.privilege_Select )
51 self.__tagTreeTableHandle.privilegeManager().grantToPublic( coral.privilege_Select )
52 self.__tagTreeTableHandle.privilegeManager().grantToPublic( coral.privilege_Select )
53 self.__tagTreeTableHandle.privilegeManager().grantToPublic( coral.privilege_Select )
59 transaction.rollback()
60 raise Exception, str(er)
63 """fill up this tree by cloning from the given source tree
66 sourcetagTreeTableName =
'TAGTREE_TABLE_'+str.upper(sourcetreename)
67 sourcetagTreeIDs =
'TAGTREE_'+str.upper(sourcetreename)+
'_IDS'
69 transaction=self.__session.transaction()
70 transaction.start(
True)
71 schema = self.__session.nominalSchema()
72 r1=schema.existsTable(sourcetagTreeTableName)
73 r2=schema.existsTable(sourcetagTreeIDs)
77 if r1
and r2
is False:
78 raise "source tag tree doesn't exist "+str(sourcetreename)
80 transaction.start(
False)
86 transaction.start(
False)
91 transaction.start(
False)
92 insertwtQuery=schema.tableHandle(self.
__tagTreeTableName).dataEditor().insertWithQuery()
93 insertwtQuery.query().addToTableList(sourcetagTreeTableName)
94 nresult=insertwtQuery.execute()
98 transaction.rollback()
99 raise Exception, str(er)
103 transaction.start(
False)
104 insertwtQuery=schema.tableHandle(self.
__tagTreeIDs).dataEditor().insertWithQuery()
105 insertwtQuery.query().addToTableList(sourcetagTreeIDs)
106 nresult=insertwtQuery.execute()
109 except Exception, er:
110 transaction.rollback()
111 raise Exception, str(er)
115 """modify the tagid link in leafnodes
116 Input: {oldtagid:newtagid , oldtagid:newtagid}
117 This function does not check if the nodes are all really leafs. User has to check before passing the input argument
119 if len(leafnodelinks.keys())==0:
120 raise 'TagTree::replaceLeafLinks: empty input '
122 transaction=self.__session.transaction()
123 transaction.start(
False)
124 schema = self.__session.nominalSchema()
126 updateAction=
"tagid = :newtagid"
127 updateCondition=
"tagid = :oldtagid"
128 updateData=coral.AttributeList()
129 updateData.extend(
'newtagid',
'unsigned long')
130 updateData.extend(
'oldtagid',
'unsigned long')
131 mybulkOperation=schema.tableHandle(self.
__tagTreeTableName).dataEditor().bulkUpdateRows(
"tagid = :newtagid",
"tagid = :oldtagid",updateData,1000)
132 for oldtagid
in leafnodelinks.keys():
133 updateData[
'newtagid'].setData(leafnodelinks[oldtagid])
134 updateData[
'oldtagid'].setData(oldtagid)
135 mybulkOperation.processNextIteration()
136 mybulkOperation.flush()
139 except Exception, er:
140 transaction.rollback()
141 raise Exception, str(er)
144 """Append a new node to specified parent. \n
145 Silently ignore duplicate entry \n
147 Input: name of the parent node. \n
148 Output: result nodeid
151 nodelabel=node.nodelabel
156 globalsince=node.globalsince
157 globaltill=node.globaltill
159 transaction=self.__session.transaction()
161 if parentLabel !=
'ROOT':
162 parentNode=self.
getNode(parentLabel)
163 if parentNode.empty():
164 raise ValueError,
"non-existing parent node "+parentLabel
165 parentid=parentNode.nodeid
169 transaction.start(
False)
170 condition=
'nodelabel=:nodelabel'
171 conditionbindDict=coral.AttributeList()
172 conditionbindDict.extend(
'nodelabel',
'string')
173 conditionbindDict[
'nodelabel'].setData(nodelabel)
176 if duplicate
is False:
179 if duplicate
is False:
180 tabrowValueDict={
'nodeid':nodeid,
'nodelabel':nodelabel,
181 'lft':lft,
'rgt':rgt,
'parentid':parentid,
182 'tagid':tagid,
'globalsince':globalsince,
183 'globaltill':globaltill
185 if parentLabel !=
'ROOT':
193 except coral.Exception, er:
194 transaction.rollback()
195 raise Exception, str(er)
196 except Exception, er:
197 transaction.rollback()
198 raise Exception, str(er)
202 rename selected nodes \n
203 Input: {oldnodename:newnodename}
204 Output: [renamednodeid]
206 transaction=self.__session.transaction()
209 transaction.start(
True)
210 schema = self.__session.nominalSchema()
212 query.addToOutputList(
'nodelabel')
213 cursor = query.execute()
214 while ( cursor.next() ):
215 nodelabel=cursor.currentRow()[
'nodelabel'].
data()
216 if nodenamemap.has_key(nodelabel):
217 allnodes[nodelabel]=nodenamemap[nodelabel]
219 allnodes[nodelabel]=nodelabel
222 if len(allnodes.values())!=len(
set(allnodes.values())):
223 raise "new node labels are not unique in the tree"
224 transaction.start(
False)
226 inputData = coral.AttributeList()
227 inputData.extend(
'oldnodelabel',
'string')
228 inputData.extend(
'newnodelabel',
'string')
229 for nodelabelpair
in nodenamemap.items():
230 inputData[
'oldnodelabel'].setData(nodelabelpair[0])
231 inputData[
'newnodelabel'].setData(nodelabelpair[1])
232 editor.updateRows(
"nodelabel = :newnodelabel",
"nodelabel = :oldnodelabel", inputData )
234 except coral.Exception, er:
235 transaction.rollback()
237 raise Exception, str(er)
238 except Exception, er:
239 transaction.rollback()
241 raise Exception, str(er)
244 """return result of query "select * from treetable where nodeid=:nodeid" in Node structure \n
245 Input: id of the node to get.\n
246 Output: selected node
249 transaction=self.__session.transaction()
251 transaction.start(
True)
252 schema = self.__session.nominalSchema()
254 condition =
'nodeid =:nodeid'
255 conditionData = coral.AttributeList()
256 conditionData.extend(
'nodeid',
'unsigned int' )
257 conditionData[
'nodeid'].setData(nodeid)
258 query.setCondition( condition, conditionData)
259 cursor = query.execute()
260 while ( cursor.next() ):
261 result.tagid=cursor.currentRow()[
'tagid'].
data()
262 result.nodeid=cursor.currentRow()[
'nodeid'].
data()
263 result.nodelabel=cursor.currentRow()[
'nodelabel'].
data()
264 result.lft=cursor.currentRow()[
'lft'].
data()
265 result.rgt=cursor.currentRow()[
'rgt'].
data()
266 result.parentid=cursor.currentRow()[
'parentid'].
data()
267 result.globalsince=cursor.currentRow()[
'globalsince'].
data()
268 result.globaltill=cursor.currentRow()[
'globaltill'].
data()
272 except coral.Exception, er:
273 transaction.rollback()
274 raise Exception, str(er)
275 except Exception, er:
276 transaction.rollback()
277 raise Exception, str(er)
280 """return result of query "select * from treetable where nodelabel=label" in Node structure \n
281 Input: name of the node to get. Default to 'ROOT' \n
282 Output: selected node
287 transaction=self.__session.transaction()
289 transaction.start(
True)
291 condition =
'nodelabel =:nodelabel'
292 conditionData = coral.AttributeList()
293 conditionData.extend(
'nodelabel',
'string' )
294 query.setCondition( condition, conditionData)
295 conditionData[
'nodelabel'].setData(label)
296 cursor = query.execute()
297 while ( cursor.next() ):
298 result.tagid=cursor.currentRow()[
'tagid'].
data()
299 result.nodeid=cursor.currentRow()[
'nodeid'].
data()
300 result.nodelabel=cursor.currentRow()[
'nodelabel'].
data()
301 result.lft=cursor.currentRow()[
'lft'].
data()
302 result.rgt=cursor.currentRow()[
'rgt'].
data()
303 result.parentid=cursor.currentRow()[
'parentid'].
data()
304 result.globalsince=cursor.currentRow()[
'globalsince'].
data()
305 result.globaltill=cursor.currentRow()[
'globaltill'].
data()
309 except coral.Exception, er:
310 transaction.rollback()
311 raise Exception, str(er)
312 except Exception, er:
313 transaction.rollback()
314 raise Exception, str(er)
316 """Get the path to arrive from ROOT to the given node.\n
317 Input: labe of the node
318 Output: list of the labels of the nodes in the path
319 query "SELECT nodelabel FROM treetable WHERE lft<%s AND rgt>%s ORDER BY lft ASC"
328 transaction=self.__session.transaction()
329 transaction.start(
True)
330 schema = self.__session.nominalSchema()
332 query.addToOutputList(
'nodelabel')
333 condition =
'lft <:lft AND rgt>:rgt'
334 conditionData = coral.AttributeList()
335 conditionData.extend(
'lft',
'unsigned long' )
336 conditionData.extend(
'rgt',
'unsigned long' )
337 conditionData[
'lft'].setData(lft)
338 conditionData[
'rgt'].setData(rgt)
339 query.setCondition( condition, conditionData)
340 query.addToOrderList(
'lft' )
341 cursor = query.execute()
342 while ( cursor.next() ):
343 resultNodeLabel = cursor.currentRow()[
'nodelabel'].
data()
344 result.append( resultNodeLabel )
348 except coral.Exception, er:
349 transaction.rollback()
350 raise Exception, str(er)
351 except Exception, er:
352 transaction.rollback()
353 raise Exception, str(er)
355 """Get all leaf nodes.\n
356 Output: list of leaf nodes
357 Query "SELECT * FROM treetable WHERE lft=rgt-1"
361 transaction=self.__session.transaction()
362 transaction.start(
True)
363 schema = self.__session.nominalSchema()
365 condition =
'lft=rgt-1'
366 conditionData = coral.AttributeList()
367 query.setCondition( condition, conditionData)
368 cursor = query.execute()
369 while ( cursor.next() ):
371 resultNode.tagid=cursor.currentRow()[
'tagid'].
data()
372 resultNode.nodeid=cursor.currentRow()[
'nodeid'].
data()
373 resultNode.nodelabel=cursor.currentRow()[
'nodelabel'].
data()
374 resultNode.lft=cursor.currentRow()[
'lft'].
data()
375 resultNode.rgt=cursor.currentRow()[
'rgt'].
data()
376 resultNode.parentid=cursor.currentRow()[
'parentid'].
data()
377 resultNode.globalsince=cursor.currentRow()[
'globalsince'].
data()
378 resultNode.globaltill=cursor.currentRow()[
'globaltill'].
data()
379 result.append( resultNode )
383 except coral.Exception, er:
384 transaction.rollback()
386 raise Exception, str(er)
387 except Exception, er:
388 transaction.rollback()
390 raise Exception, str(er)
392 """Get the tree under node(included) with specified label.
394 Output: subtree in list of Node
395 Query "SELECT p1.* FROM treetable AS p1, treetable AS p2 WHERE p1.lft BETWEEN p2.lft AND p2.rgt AND p2.nodelabel=%s ORDER BY p1.lft ASC"
400 transaction=self.__session.transaction()
401 transaction.start(
True)
402 schema = self.__session.nominalSchema()
405 query.addToOutputList(columnName)
406 cursor = query.execute()
407 while ( cursor.next() ):
409 resultNode.tagid=cursor.currentRow()[
'tagid'].
data()
410 resultNode.nodeid=cursor.currentRow()[
'nodeid'].
data()
411 resultNode.nodelabel=cursor.currentRow()[
'nodelabel'].
data()
412 resultNode.lft=cursor.currentRow()[
'lft'].
data()
413 resultNode.rgt=cursor.currentRow()[
'rgt'].
data()
414 resultNode.parentid=cursor.currentRow()[
'parentid'].
data()
415 resultNode.globalsince=cursor.currentRow()[
'globalsince'].
data()
416 resultNode.globaltill=cursor.currentRow()[
'globaltill'].
data()
417 result.append(resultNode)
425 transaction=self.__session.transaction()
426 transaction.start(
True)
427 schema = self.__session.nominalSchema()
428 query = schema.newQuery()
431 for columnname
in self.__tagTreeTableColumns.keys():
432 query.addToOutputList(
'p1.'+columnname )
433 condition =
'p1.lft BETWEEN p2.lft AND p2.rgt AND p2.nodelabel = :nodelabel'
434 query.addToOrderList(
"p1.lft" );
435 conditionData = coral.AttributeList()
436 conditionData.extend(
'nodelabel',
'string' )
437 conditionData[
'nodelabel'].setData(label)
438 query.setCondition( condition, conditionData)
439 cursor = query.execute()
440 while ( cursor.next() ):
442 resultNode.tagid=cursor.currentRow()[
'p1.tagid'].
data()
443 resultNode.nodeid=cursor.currentRow()[
'p1.nodeid'].
data()
444 resultNode.nodelabel=cursor.currentRow()[
'p1.nodelabel'].
data()
445 resultNode.lft=cursor.currentRow()[
'p1.lft'].
data()
446 resultNode.rgt=cursor.currentRow()[
'p1.rgt'].
data()
447 resultNode.parentid=cursor.currentRow()[
'p1.parentid'].
data()
448 resultNode.globalsince=cursor.currentRow()[
'p1.globalsince'].
data()
449 resultNode.globaltill=cursor.currentRow()[
'p1.globaltill'].
data()
450 result.append(resultNode)
454 except coral.Exception, er:
455 transaction.rollback()
456 raise Exception, str(er)
457 except Exception, er:
458 transaction.rollback()
459 raise Exception, str(er)
461 """Number of children nodes of the given node
462 Input: label of the parent node
463 Output: number of children
468 transaction=self.__session.transaction()
469 transaction.start(
True)
470 schema = self.__session.nominalSchema()
472 query.addToOutputList(
'count(*)',
'ct')
473 mycounts=coral.AttributeList()
474 mycounts.extend(
'ct',
'unsigned long');
475 query.defineOutput( mycounts );
476 cursor = query.execute();
477 while ( cursor.next() ):
478 n= cursor.currentRow()[
'ct'].
data()
482 except coral.Exception, er:
483 transaction.rollback()
484 raise Exception, str(er)
485 except Exception, er:
486 transaction.rollback()
487 raise Exception, str(er)
490 return int((me.rgt-me.lft)/2)
492 """Delete the subtree under the specified node(included).\n
493 Input: label of the top node
494 query: DELETE FROM treetable WHERE lft >=%me.lft AND rgt<=%me.rgt
497 transaction=self.__session.transaction()
500 transaction.start(
False)
502 self.__session.nominalSchema().dropIfExistsTable(self.
__tagTreeIDs)
512 parentlft=myparent.lft
513 parentrgt=myparent.rgt
515 transaction.start(
False)
517 editor = tableHandle.dataEditor()
518 condition =
'lft >= :parentlft AND rgt <= :parentrgt'
519 conditionData = coral.AttributeList()
520 conditionData.extend(
'parentlft',
'unsigned long')
521 conditionData.extend(
'parentrgt',
'unsigned long')
522 conditionData[
'parentlft'].setData(parentlft)
523 conditionData[
'parentrgt'].setData(parentrgt)
524 editor.deleteRows( condition, conditionData )
525 self.
__closeGap(tableHandle,parentlft,parentrgt,n)
527 except coral.Exception, er:
528 transaction.rollback()
529 raise Exception, str(er)
530 except Exception, er:
531 transaction.rollback()
532 raise Exception, str(er)
535 DELETE FROM treetable WHERE nodename=label
537 assert (label !=
'ROOT')
538 transaction=self.__session.transaction()
541 parentlft=myparent.lft
542 parentrgt=myparent.rgt
543 transaction.start(
False)
545 editor = tableHandle.dataEditor()
546 condition =
'nodelabel = :nodelabel'
547 conditionData = coral.AttributeList()
548 conditionData.extend(
'nodelabel',
'string')
549 conditionData[
'nodelabel'].setData(label)
550 editor.deleteRows( condition, conditionData )
551 self.
__closeGap(tableHandle,parentlft,parentrgt,1)
553 except Exception, er:
555 transaction.rollback()
556 raise Exception, str(er)
558 """Update the parent node after inserting. Must be called inside update transaction.\n
559 Input: rootrgt is the rgt of the parent node. \n
560 Input: n is the number of positions to add
563 inputData = coral.AttributeList()
564 inputData.extend(
'parentrgt',
'unsigned long')
565 inputData[
'parentrgt'].setData(parentrgt)
566 editor = tableHandle.dataEditor()
567 setClause =
'lft=lft+'+str(delta)
568 condition =
'lft>:parentrgt'
569 editor.updateRows(setClause, condition, inputData)
570 setClause =
'rgt=rgt+'+str(delta)
571 condition =
'rgt>=:parentrgt'
572 editor.updateRows(setClause, condition, inputData)
574 """Update the node lft rgt values after removing. Must be called inside update transaction.\n
576 assert (parentlft!=0
and parentrgt!=0
and n!=0)
577 assert (parentrgt>parentlft)
579 editor = tableHandle.dataEditor()
580 setClause1 =
'lft=lft-'+str(delta)
581 condition1 =
'lft>'+str(parentrgt)
582 inputData =coral.AttributeList()
583 editor.updateRows(setClause1,condition1,inputData)
584 setClause2 =
'rgt=rgt-'+str(delta)
585 condition2 =
'rgt>'+str(parentrgt)
586 editor.updateRows(setClause2,condition2,inputData)
587 if __name__ ==
"__main__":
588 os.putenv(
"CORAL_AUTH_PATH",
"." )
589 svc = coral.ConnectionService()
590 session = svc.connect(
'sqlite_file:testTree.db',
591 accessMode = coral.access_Update )
597 mytree.createTagTreeTable()
602 mytree.insertNode(mynode,
'ROOT')
603 result=mytree.getNode(
'A')
606 mynode.nodelabel=
'AC1'
609 mytree.insertNode(mynode,
'A')
610 result=mytree.getNode(
'A')
612 result=mytree.getNode(
'AC1')
614 result=mytree.getPath(
'AC1')
616 result=mytree.getAllLeaves()
617 print 'all leafs',result
619 mynode.nodelabel=
'AB2'
622 mytree.insertNode(mynode,
'A')
623 result=mytree.getNode(
'A')
624 print 'Node A ',result
625 result=mytree.getNode(
'AB2')
626 print 'Node AB2 ',result
627 result=mytree.getPath(
'AB2')
628 print 'Path to AB2 ',result
629 allleafs=mytree.getAllLeaves()
630 print 'all leaves again',allleafs
631 print 'number of children ',mytree.nChildren(
'A')
632 print 'number of children ',mytree.nChildren(
'ROOT')
633 result=mytree.getSubtree(
'A')
634 print 'subtree of A ',result
636 newtree.importFromTree(
'mytest2')
639 newlinks[l.tagid]=1234
640 newtree.replaceLeafLinks(newlinks)
643 print "Failed in unit test"
__tagTreeTableUniqueColumns
char data[epos_bytes_allocation]
__tagTreeTableNotNullColumns
void set(const std::string &name, int value)
set the flag, with a run-time name