| 276 | } |
| 277 | |
| 278 | func (node *Node) Delete() (err error) { |
| 279 | // lock node |
| 280 | err = locker.NodeLockMgr.LockNode(node.Id) |
| 281 | if err != nil { |
| 282 | return |
| 283 | } |
| 284 | defer locker.NodeLockMgr.Remove(node.Id) |
| 285 | |
| 286 | // check to make sure this node isn't referenced by a vnode |
| 287 | virtualNodes := Nodes{} |
| 288 | if _, err = dbFind(bson.M{"file.virtual_parts": node.Id}, &virtualNodes, "", nil); err != nil { |
| 289 | return err |
| 290 | } |
| 291 | if len(virtualNodes) != 0 { |
| 292 | return errors.New(e.NodeReferenced) |
| 293 | } |
| 294 | |
| 295 | // Check to see if this node has a data file and if it's referenced by another node. |
| 296 | // If it is, we will move the data file to the first node we find, and point all other nodes to that node's path |
| 297 | dataFilePath := fmt.Sprintf("%s/%s.data", getPath(node.Id), node.Id) |
| 298 | dataFileExists := true |
| 299 | if _, ferr := os.Stat(dataFilePath); os.IsNotExist(ferr) { |
| 300 | dataFileExists = false |
| 301 | } |
| 302 | newDataFilePath := "" |
| 303 | copiedNodes := Nodes{} |
| 304 | if _, err = dbFind(bson.M{"file.path": dataFilePath}, &copiedNodes, "", nil); err != nil { |
| 305 | return err |
| 306 | } |
| 307 | if len(copiedNodes) != 0 && dataFileExists { |
| 308 | for index, copiedNode := range copiedNodes { |
| 309 | // lock copynode for save |
| 310 | err = locker.NodeLockMgr.LockNode(copiedNode.Id) |
| 311 | if err != nil { |
| 312 | err = errors.New("This node has a data file linked to another node which could not be locked during data file copy: " + err.Error()) |
| 313 | return |
| 314 | } |
| 315 | defer locker.NodeLockMgr.UnlockNode(copiedNode.Id) |
| 316 | |
| 317 | if index == 0 { |
| 318 | newDataFilePath = fmt.Sprintf("%s/%s.data", getPath(copiedNode.Id), copiedNode.Id) |
| 319 | if rerr := os.Rename(dataFilePath, newDataFilePath); rerr != nil { |
| 320 | if _, cerr := util.CopyFile(dataFilePath, newDataFilePath); cerr != nil { |
| 321 | err = errors.New("This node has a data file linked to another node and the data file could not be copied elsewhere to allow for node deletion.") |
| 322 | return |
| 323 | } |
| 324 | } |
| 325 | copiedNode.File.Path = "" |
| 326 | copiedNode.Save() |
| 327 | } else { |
| 328 | copiedNode.File.Path = newDataFilePath |
| 329 | copiedNode.Save() |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | err = dbDelete(bson.M{"id": node.Id}) |
| 335 | if err != nil { |