1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (C) 2005-2007 Carabos Coop. V. All rights reserved 5# Copyright (C) 2008-2019 Vicent Mas. All rights reserved 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20# Author: Vicent Mas - vmas@vitables.org 21 22""" 23This module provides editing capabilities for PyTables soft and external links. 24 25The module defines methods for deleting, cutting, copying, pasting and 26moving links. 27""" 28 29__docformat__ = 'restructuredtext' 30 31import os 32 33import tables 34 35import vitables.utils 36 37 38 39class TLinkEditor(object): 40 """ 41 An editor for `tables.Link` instances. 42 """ 43 44 def __init__(self, dbdoc): 45 """ 46 Initialises the tables.Link editor. 47 48 :Parameter h5file: the tables.File instance being operated 49 """ 50 51 if not dbdoc.hidden_group: 52 dbdoc.createHiddenGroup() 53 54 self.h5file = dbdoc.h5file 55 self.hidden_group = dbdoc.hidden_group 56 57 58 def delete(self, nodepath): 59 """Delete a link. 60 61 :Parameters: 62 63 - `nodepath`: the full path of the node/link being deleted 64 """ 65 66 try: 67 link = self.h5file.get_node(nodepath) 68 link.remove() 69 self.h5file.flush() 70 except (tables.NodeError, OSError): 71 vitables.utils.formatExceptionInfo() 72 73 74 def cut(self, nodepath): 75 """Moves a link to a hidden group of its database. 76 77 The cut node must be stored somewhere or it will no be possible 78 to paste it later. Storing it in the same database is extremely 79 fast independently of the node size. Storing it in other database 80 (i.e. in the temporary database) would have a cost which depends 81 on the size of the cut node. 82 83 :Parameters: 84 85 - `nodepath`: the path of the node being cut 86 """ 87 88 nodename = os.path.basename(nodepath) 89 try: 90 # The hidden group should contain at most 1 node 91 for node in self.h5file.list_nodes(self.hidden_group): 92 self.h5file.deleteNode(node._v_pathname) 93 94 link = self.h5file.get_node(nodepath) 95 link.move(newparent=self.hidden_group, newname=nodename) 96 self.h5file.flush() 97 except(tables.NodeError, OSError): 98 vitables.utils.formatExceptionInfo() 99 100 101 def paste(self, link, parent, childname): 102 """Copy a link to a different location. 103 104 :Parameters: 105 106 - `link`: the tables.link instance being pasted 107 - `parent`: the new parent of the node being pasted 108 - `childname`: the new name of the node being pasted 109 """ 110 111 try: 112 link.copy(newparent=parent, newname=childname, 113 overwrite=True, createparents=False) 114 self.h5file.flush() 115 except (tables.NodeError, OSError): 116 vitables.utils.formatExceptionInfo() 117 118 119 def rename(self, nodepath, new_name): 120 """ 121 Rename the selected link from the object tree. 122 123 :Parameters: 124 125 - `nodepath`: the full path of the node being renamed 126 - `new_name`: the node new name 127 """ 128 129 try: 130 link = self.h5file.get_node(nodepath) 131 link.rename(new_name) 132 self.h5file.flush() 133 except (tables.NodeError, OSError): 134 vitables.utils.formatExceptionInfo() 135 136 137 def move(self, childpath, dst_dbdoc, parentpath, childname): 138 """Move a ink to a different location. 139 140 :Parameters: 141 142 - `childpath`: the full path of the node being moved 143 - `dst_dbdoc`: the destination database (a :meth:`DBDoc` instance) 144 - `parentpath`: the full path of the new parent node 145 - `childname`: the name of the node in its final location 146 """ 147 148 try: 149 dst_h5file = dst_dbdoc.h5file 150 parent_node = dst_h5file.get_node(parentpath) 151 link = self.h5file.get_node(childpath) 152 if self.h5file is dst_h5file: 153 link.move(newparent=parentpath, newname=childname) 154 else: 155 link.copy(newparent=parent_node, newname=childname) 156 dst_h5file.flush() 157 src_where, src_nodename = os.path.split(childpath) 158 self.h5file.remove_node(src_where, src_nodename, recursive=1) 159 self.h5file.flush() 160 return childname 161 except (tables.NodeError, OSError): 162 vitables.utils.formatExceptionInfo() 163 return None 164