1/*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef FS_TRANSACTION_H
6#define FS_TRANSACTION_H
7
8
9#include <string>
10#include <vector>
11
12#include "FSUtils.h"
13
14
15class FSTransaction {
16public:
17			typedef FSUtils::Entry Entry;
18
19			class Operation;
20			class CreateOperation;
21			class RemoveOperation;
22			class MoveOperation;
23
24public:
25								FSTransaction();
26								~FSTransaction();
27
28			void				RollBack();
29
30			int32				CreateEntry(const Entry& entry,
31									int32 modifiedOperation = -1);
32			int32				RemoveEntry(const Entry& entry,
33									const Entry& backupEntry,
34									int32 modifiedOperation = -1);
35			int32				MoveEntry(const Entry& fromEntry,
36									const Entry& toEntry,
37									int32 modifiedOperation = -1);
38
39			void				RemoveOperationAt(int32 index);
40
41private:
42			struct OperationInfo;
43			typedef std::vector<OperationInfo> OperationList;
44
45private:
46	static	std::string			_GetPath(const Entry& entry);
47
48private:
49			OperationList		fOperations;
50};
51
52
53class FSTransaction::Operation {
54public:
55	Operation(FSTransaction* transaction, int32 operation)
56		:
57		fTransaction(transaction),
58		fOperation(operation),
59		fIsFinished(false)
60	{
61	}
62
63	~Operation()
64	{
65		if (fTransaction != NULL && fOperation >= 0 && !fIsFinished)
66			fTransaction->RemoveOperationAt(fOperation);
67	}
68
69	/*!	Arms the operation rollback, i.e. rolling back the transaction will
70		revert this operation.
71	*/
72	void Finished()
73	{
74		fIsFinished = true;
75	}
76
77	/*!	Unregisters the operation rollback, i.e. rolling back the transaction
78		will not revert this operation.
79	*/
80	void Unregister()
81	{
82		if (fTransaction != NULL && fOperation >= 0) {
83			fTransaction->RemoveOperationAt(fOperation);
84			fIsFinished = false;
85			fTransaction = NULL;
86			fOperation = -1;
87		}
88	}
89
90private:
91	FSTransaction*	fTransaction;
92	int32			fOperation;
93	bool			fIsFinished;
94};
95
96
97class FSTransaction::CreateOperation : public FSTransaction::Operation {
98public:
99	CreateOperation(FSTransaction* transaction, const Entry& entry,
100		int32 modifiedOperation = -1)
101		:
102		Operation(transaction,
103			transaction->CreateEntry(entry, modifiedOperation))
104	{
105	}
106};
107
108
109class FSTransaction::RemoveOperation : public FSTransaction::Operation {
110public:
111	RemoveOperation(FSTransaction* transaction, const Entry& entry,
112		const Entry& backupEntry, int32 modifiedOperation = -1)
113		:
114		Operation(transaction,
115			transaction->RemoveEntry(entry, backupEntry, modifiedOperation))
116	{
117	}
118};
119
120
121class FSTransaction::MoveOperation : public FSTransaction::Operation {
122public:
123	MoveOperation(FSTransaction* transaction, const Entry& fromEntry,
124		const Entry& toEntry, int32 modifiedOperation = -1)
125		:
126		Operation(transaction,
127			transaction->MoveEntry(fromEntry, toEntry, modifiedOperation))
128	{
129	}
130};
131
132
133#endif	// FS_TRANSACTION_H
134