Further changes to reduce locking and switch to WAL journal mode for SQLite
[pithos-ms-client] / trunk / Pithos.Core / Agents / CloudTransferAction.cs
1 using System;
2 using System.Diagnostics.Contracts;
3 using System.IO;
4 using System.Threading;
5 using Pithos.Interfaces;
6 using Pithos.Network;
7
8 namespace Pithos.Core.Agents
9 {
10     public enum CloudActionType
11     {
12         MustSynch,
13         UploadUnconditional,
14         DownloadUnconditional,
15         DeleteLocal,
16         DeleteCloud,
17         RenameCloud
18     }
19
20     public class CloudAction
21     {
22         public AccountInfo AccountInfo { get; set; }
23         public CloudActionType Action { get; set; }
24         public FileSystemInfo LocalFile { get; set; }
25         public ObjectInfo CloudFile { get; set; }
26         public FileState FileState { get; set; }
27         public string Container { get; set; }
28
29         public readonly DateTime Created = DateTime.Now;
30
31
32         public Lazy<string> LocalHash { get; protected set; }
33         private Lazy<string> _topHash;
34         public Lazy<string> TopHash
35         {
36             get { return _topHash; }
37             set { _topHash = value; }
38         }
39
40
41         [ContractInvariantMethod]
42         private void Invariants()
43         {
44             Contract.Invariant(AccountInfo!=null);
45         }
46
47         protected CloudAction(AccountInfo accountInfo,CloudActionType action)
48         {
49             if (accountInfo==null)
50                 throw new ArgumentNullException("accountInfo");
51             Contract.EndContractBlock();
52
53             Action = action;
54             AccountInfo = accountInfo;
55         }
56
57         public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
58             : this(accountInfo,action)
59         {
60             LocalFile = localFile.WithProperCapitalization();
61             CloudFile = cloudFile;
62             FileState = state;
63             if (LocalFile != null)
64             {
65
66                 LocalHash = new Lazy<string>(() => LocalFile.CalculateHash(blockSize,algorithm),
67                                              LazyThreadSafetyMode.ExecutionAndPublication);
68             }
69         }
70
71         //Calculate the download path for the cloud file
72         public string GetDownloadPath()
73         {
74             if (CloudFile == null)
75                 return String.Empty;
76             var filePath = CloudFile.RelativeUrlToFilePath(AccountInfo.UserName);
77             return Path.Combine(AccountInfo.AccountPath, filePath);
78         }
79
80         public override string ToString()
81         {
82             return String.Format("{0}:{1}->{2}", this.Action, this.LocalFile.FullName, this.CloudFile.Name);
83         }
84     }    
85
86     public class CloudDownloadAction:CloudAction
87     {
88         public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
89             :base(accountInfo,CloudActionType.DownloadUnconditional)
90         {            
91             if (String.IsNullOrWhiteSpace(cloudFile.Container))
92                 throw new ArgumentException("CloudFile.Container","cloudFile");
93             Contract.EndContractBlock();
94
95             CloudFile = cloudFile;
96         }
97
98         [ContractInvariantMethod]
99         private void Invariants()
100         {
101             Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
102         }
103
104         public override string ToString()
105         {
106             return String.Format("{0}: _ <- {1}", this.Action, this.CloudFile.Name);
107         }
108         
109     }
110     public class CloudDeleteAction:CloudAction
111     {
112         public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
113             : this(accountInfo,fileInfo,new ObjectInfo(accountInfo.AccountPath,accountInfo.UserName,fileInfo),fileState)
114         {            
115         }
116
117         public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState) 
118             : base(accountInfo,CloudActionType.DeleteCloud)
119         {
120             CloudFile = cloudFile;
121             LocalFile = fileInfo;
122             FileState = fileState;
123         }
124
125         public CloudDeleteAction(CloudAction action)
126             : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
127         {}
128
129         [ContractInvariantMethod]
130         private void Invariants()
131         {
132             Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
133         }
134
135         public override string ToString()
136         {
137             return String.Format("{0}: _ ->{1}", this.Action, this.CloudFile.Name);
138         }
139
140     }
141
142     public class CloudUploadAction:CloudAction
143     {
144         public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
145             : base(accountInfo, CloudActionType.UploadUnconditional, fileInfo, 
146             new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName,fileInfo), state, blockSize, algorithm)
147         {
148         }
149
150         [ContractInvariantMethod]
151         private void Invariants()
152         {
153             Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
154         }
155
156     }
157
158     public class CloudMoveAction:CloudAction
159     {
160         public ObjectInfo OldCloudFile { get; set; }
161
162         public FileSystemInfo OldLocalFile { get; set; }
163
164         public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
165             :base(accountInfo,action)
166         {
167             LocalFile = newFile;
168             CloudFile = new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, newFile);
169             
170             OldLocalFile = oldFile;
171             OldCloudFile = new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, oldFile);
172
173             //This is a rename operation, a hash will not be used
174             LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
175         }
176
177         public override string ToString()
178         {
179             return String.Format("{0}:{1}->{2}", this.Action, OldCloudFile.Name, CloudFile.Name);
180         }
181
182     }
183
184 }