Revision e81dd1f6 trunk/Pithos.Core/FileState.cs
b/trunk/Pithos.Core/FileState.cs | ||
---|---|---|
35 | 35 |
// </copyright> |
36 | 36 |
// ----------------------------------------------------------------------- |
37 | 37 |
|
38 |
using System.Data.SQLite; |
|
38 | 39 |
using System.Diagnostics.Contracts; |
39 | 40 |
using System.IO; |
40 | 41 |
using System.Threading.Tasks; |
... | ... | |
54 | 55 |
/// TODO: Update summary. |
55 | 56 |
/// </summary> |
56 | 57 |
[ActiveRecord] |
57 |
public class FileState:ActiveRecordLinqBase<FileState>
|
|
58 |
public class FileState : ActiveRecordLinqBase<FileState>
|
|
58 | 59 |
{ |
59 | 60 |
private static readonly ILog Log = LogManager.GetLogger("FileState"); |
60 |
|
|
61 |
|
|
61 | 62 |
private string _filePath; |
62 |
private IList<FileTag> _tags=new List<FileTag>();
|
|
63 |
private IList<FileTag> _tags = new List<FileTag>();
|
|
63 | 64 |
|
64 | 65 |
[PrimaryKey(PrimaryKeyType.Guid)] |
65 | 66 |
public Guid Id { get; set; } |
66 | 67 |
|
67 |
[Property(Unique=true,UniqueKey="IX_FileState_FilePath")]
|
|
68 |
[Property(Unique = true, UniqueKey = "IX_FileState_FilePath")]
|
|
68 | 69 |
public string FilePath |
69 | 70 |
{ |
70 | 71 |
get { return _filePath; } |
... | ... | |
98 | 99 |
public bool ShareWrite { get; set; } |
99 | 100 |
|
100 | 101 |
|
101 |
[HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true,Inverse=true)]
|
|
102 |
[HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true, Inverse = true)]
|
|
102 | 103 |
public IList<FileTag> Tags |
103 | 104 |
{ |
104 |
get { return _tags; }
|
|
105 |
set { _tags=value;}
|
|
105 |
get { return _tags; } |
|
106 |
set { _tags = value; }
|
|
106 | 107 |
} |
107 | 108 |
|
108 |
|
|
109 |
|
|
109 | 110 |
public static FileState FindByFilePath(string absolutePath) |
110 | 111 |
{ |
111 | 112 |
if (string.IsNullOrWhiteSpace(absolutePath)) |
... | ... | |
113 | 114 |
Contract.EndContractBlock(); |
114 | 115 |
try |
115 | 116 |
{ |
117 |
|
|
118 |
|
|
119 |
|
|
116 | 120 |
return Queryable.FirstOrDefault(s => s.FilePath == absolutePath.ToLower()); |
117 | 121 |
} |
118 | 122 |
catch (Exception ex) |
... | ... | |
120 | 124 |
Log.Error(ex.ToString()); |
121 | 125 |
throw; |
122 | 126 |
} |
123 |
|
|
127 |
|
|
124 | 128 |
|
125 | 129 |
} |
126 | 130 |
|
127 |
public static void DeleteByFilePath(string absolutePath) |
|
131 |
/* public static void DeleteByFilePath(string absolutePath)
|
|
128 | 132 |
{ |
129 |
if(string.IsNullOrWhiteSpace(absolutePath)) |
|
133 |
if (string.IsNullOrWhiteSpace(absolutePath))
|
|
130 | 134 |
throw new ArgumentNullException("absolutePath"); |
131 | 135 |
Contract.EndContractBlock(); |
132 |
|
|
133 |
Execute((session, instance) => |
|
134 |
{
|
|
135 |
const string hqlDelete = "delete FileState where FilePath = :path";
|
|
136 |
var deletedEntities = session.CreateQuery(hqlDelete)
|
|
137 |
.SetString("path", absolutePath.ToLower())
|
|
138 |
.ExecuteUpdate();
|
|
139 |
return deletedEntities;
|
|
140 |
},null);
|
|
141 |
|
|
142 |
} |
|
136 |
|
|
137 |
ExecuteWithRetry((session, instance) =>
|
|
138 |
{ |
|
139 |
const string hqlDelete = "delete FileState where FilePath = :path";
|
|
140 |
var deletedEntities = session.CreateQuery(hqlDelete) |
|
141 |
.SetString("path", absolutePath.ToLower()) |
|
142 |
.ExecuteUpdate(); |
|
143 |
return deletedEntities; |
|
144 |
}, null);
|
|
145 |
|
|
146 |
}*/
|
|
143 | 147 |
|
144 | 148 |
public static void StoreFileStatus(string absolutePath, FileStatus newStatus) |
145 | 149 |
{ |
... | ... | |
147 | 151 |
throw new ArgumentNullException("absolutePath"); |
148 | 152 |
Contract.EndContractBlock(); |
149 | 153 |
|
150 |
Execute((session, instance) => |
|
151 |
{ |
|
152 |
const string hqlUpdate = "update FileState set FileStatus= :status where FilePath = :path "; |
|
153 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
154 |
.SetString("path", absolutePath.ToLower()) |
|
155 |
.SetEnum("status", newStatus) |
|
156 |
.ExecuteUpdate(); |
|
157 |
if (updatedEntities == 0) |
|
158 |
{ |
|
159 |
var newState = new FileState { FilePath = absolutePath.ToLower(), Id = Guid.NewGuid(), FileStatus = newStatus }; |
|
160 |
newState.CreateAndFlush(); |
|
161 |
} |
|
162 |
return null; |
|
163 |
}, null); |
|
154 |
ExecuteWithRetry((session, instance) => |
|
155 |
{ |
|
156 |
const string hqlUpdate = "update FileState set FileStatus= :status where FilePath = :path "; |
|
157 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
158 |
.SetString("path", absolutePath.ToLower()) |
|
159 |
.SetEnum("status", newStatus) |
|
160 |
.ExecuteUpdate(); |
|
161 |
if (updatedEntities == 0) |
|
162 |
{ |
|
163 |
var newState = new FileState |
|
164 |
{ |
|
165 |
FilePath = absolutePath.ToLower(), |
|
166 |
Id = Guid.NewGuid(), |
|
167 |
FileStatus = newStatus |
|
168 |
}; |
|
169 |
newState.CreateAndFlush(); |
|
170 |
} |
|
171 |
return null; |
|
172 |
}, null); |
|
164 | 173 |
|
165 | 174 |
} |
166 | 175 |
|
... | ... | |
170 | 179 |
throw new ArgumentNullException("absolutePath"); |
171 | 180 |
Contract.EndContractBlock(); |
172 | 181 |
|
173 |
Execute((session, instance) => |
|
174 |
{ |
|
175 |
const string hqlUpdate = "update FileState set OverlayStatus= :status where FilePath = :path "; |
|
176 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
177 |
.SetString("path", absolutePath.ToLower()) |
|
178 |
.SetEnum("status", newStatus) |
|
179 |
.ExecuteUpdate(); |
|
180 |
if (updatedEntities == 0) |
|
181 |
{ |
|
182 |
var newState = new FileState { FilePath = absolutePath, Id = Guid.NewGuid(), OverlayStatus = newStatus }; |
|
183 |
newState.CreateAndFlush(); |
|
184 |
} |
|
185 |
return null; |
|
186 |
}, null); |
|
182 |
ExecuteWithRetry((session, instance) => |
|
183 |
{ |
|
184 |
const string hqlUpdate = |
|
185 |
"update FileState set OverlayStatus= :status where FilePath = :path "; |
|
186 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
187 |
.SetString("path", absolutePath.ToLower()) |
|
188 |
.SetEnum("status", newStatus) |
|
189 |
.ExecuteUpdate(); |
|
190 |
if (updatedEntities == 0) |
|
191 |
{ |
|
192 |
var newState = new FileState |
|
193 |
{ |
|
194 |
FilePath = absolutePath, |
|
195 |
Id = Guid.NewGuid(), |
|
196 |
OverlayStatus = newStatus |
|
197 |
}; |
|
198 |
newState.CreateAndFlush(); |
|
199 |
} |
|
200 |
return null; |
|
201 |
}, null); |
|
187 | 202 |
|
188 | 203 |
} |
189 | 204 |
|
205 |
/* |
|
190 | 206 |
public static void UpdateStatus(string absolutePath, FileStatus fileStatus, FileOverlayStatus overlayStatus) |
191 | 207 |
{ |
192 | 208 |
if (string.IsNullOrWhiteSpace(absolutePath)) |
193 | 209 |
throw new ArgumentNullException("absolutePath"); |
194 | 210 |
Contract.EndContractBlock(); |
195 | 211 |
|
196 |
Execute((session, instance) => |
|
197 |
{ |
|
198 |
const string hqlUpdate = "update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path "; |
|
199 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
200 |
.SetString("path", absolutePath.ToLower()) |
|
201 |
.SetEnum("fileStatus", fileStatus) |
|
202 |
.SetEnum("overlayStatus", overlayStatus) |
|
203 |
.ExecuteUpdate(); |
|
204 |
return updatedEntities; |
|
205 |
}, null); |
|
212 |
ExecuteWithRetry((session, instance) => |
|
213 |
{ |
|
214 |
const string hqlUpdate = |
|
215 |
"update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path "; |
|
216 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
217 |
.SetString("path", absolutePath.ToLower()) |
|
218 |
.SetEnum("fileStatus", fileStatus) |
|
219 |
.SetEnum("overlayStatus", overlayStatus) |
|
220 |
.ExecuteUpdate(); |
|
221 |
return updatedEntities; |
|
222 |
}, null); |
|
206 | 223 |
|
207 | 224 |
} |
225 |
*/ |
|
226 |
|
|
227 |
/* |
|
208 | 228 |
public static void UpdateStatus(string absolutePath, FileStatus fileStatus) |
209 | 229 |
{ |
210 | 230 |
if (string.IsNullOrWhiteSpace(absolutePath)) |
211 | 231 |
throw new ArgumentNullException("absolutePath"); |
212 | 232 |
Contract.EndContractBlock(); |
213 | 233 |
|
214 |
Execute((session, instance) => |
|
215 |
{ |
|
216 |
const string hqlUpdate = "update FileState set FileStatus= :fileStatus where FilePath = :path "; |
|
217 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
218 |
.SetString("path", absolutePath.ToLower()) |
|
219 |
.SetEnum("fileStatus", fileStatus) |
|
220 |
.ExecuteUpdate(); |
|
221 |
return updatedEntities; |
|
222 |
}, null); |
|
234 |
ExecuteWithRetry((session, instance) => |
|
235 |
{ |
|
236 |
const string hqlUpdate = |
|
237 |
"update FileState set FileStatus= :fileStatus where FilePath = :path "; |
|
238 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
239 |
.SetString("path", absolutePath.ToLower()) |
|
240 |
.SetEnum("fileStatus", fileStatus) |
|
241 |
.ExecuteUpdate(); |
|
242 |
return updatedEntities; |
|
243 |
}, null); |
|
223 | 244 |
|
224 | 245 |
} |
225 | 246 |
|
247 |
*/ |
|
226 | 248 |
public static void RenameState(string oldPath, string newPath) |
227 | 249 |
{ |
228 | 250 |
if (string.IsNullOrWhiteSpace(oldPath)) |
229 | 251 |
throw new ArgumentNullException("oldPath"); |
230 | 252 |
Contract.EndContractBlock(); |
231 | 253 |
|
232 |
Execute((session, instance) => |
|
233 |
{ |
|
234 |
const string hqlUpdate = "update FileState set FilePath= :newPath where FilePath = :oldPath "; |
|
235 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
236 |
.SetString("oldPath", oldPath.ToLower()) |
|
237 |
.SetString("newPath", newPath.ToLower()) |
|
238 |
.ExecuteUpdate(); |
|
239 |
return updatedEntities; |
|
240 |
}, null); |
|
254 |
ExecuteWithRetry((session, instance) => |
|
255 |
{ |
|
256 |
const string hqlUpdate = |
|
257 |
"update FileState set FilePath= :newPath where FilePath = :oldPath "; |
|
258 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
259 |
.SetString("oldPath", oldPath.ToLower()) |
|
260 |
.SetString("newPath", newPath.ToLower()) |
|
261 |
.ExecuteUpdate(); |
|
262 |
return updatedEntities; |
|
263 |
}, null); |
|
241 | 264 |
|
242 | 265 |
} |
243 | 266 |
|
244 |
public static void UpdateStatus(Guid id, FileStatus fileStatus) |
|
267 |
/* public static void UpdateStatus(Guid id, FileStatus fileStatus)
|
|
245 | 268 |
{ |
246 |
Contract.EndContractBlock(); |
|
247 | 269 |
|
248 |
Execute((session, instance) => |
|
270 |
ExecuteWithRetry((session, instance) =>
|
|
249 | 271 |
{ |
250 |
const string hqlUpdate = "update FileState set FileStatus= :fileStatus where Id = :id "; |
|
272 |
const string hqlUpdate = |
|
273 |
"update FileState set FileStatus= :fileStatus where Id = :id "; |
|
251 | 274 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
252 |
.SetGuid("id", id)
|
|
253 |
.SetEnum("fileStatus", fileStatus)
|
|
254 |
.ExecuteUpdate();
|
|
275 |
.SetGuid("id", id) |
|
276 |
.SetEnum("fileStatus", fileStatus)
|
|
277 |
.ExecuteUpdate(); |
|
255 | 278 |
return updatedEntities; |
256 | 279 |
}, null); |
257 |
|
|
258 |
} |
|
280 |
}*/ |
|
259 | 281 |
|
260 | 282 |
public static void UpdateChecksum(string absolutePath, string checksum) |
261 | 283 |
{ |
... | ... | |
263 | 285 |
throw new ArgumentNullException("absolutePath"); |
264 | 286 |
Contract.EndContractBlock(); |
265 | 287 |
|
266 |
Execute((session, instance) => |
|
267 |
{ |
|
268 |
const string hqlUpdate = "update FileState set Checksum= :checksum where FilePath = :path "; |
|
269 |
var updatedEntities = session.CreateQuery(hqlUpdate) |
|
270 |
.SetString("path", absolutePath.ToLower()) |
|
271 |
.SetString("checksum", checksum)
|
|
272 |
.ExecuteUpdate(); |
|
273 |
return updatedEntities; |
|
274 |
}, null); |
|
288 |
ExecuteWithRetry((session, instance) =>
|
|
289 |
{
|
|
290 |
const string hqlUpdate = "update FileState set Checksum= :checksum where FilePath = :path ";
|
|
291 |
var updatedEntities = session.CreateQuery(hqlUpdate)
|
|
292 |
.SetString("path", absolutePath.ToLower())
|
|
293 |
.SetString("checksum", checksum)
|
|
294 |
.ExecuteUpdate();
|
|
295 |
return updatedEntities;
|
|
296 |
}, null);
|
|
275 | 297 |
|
276 | 298 |
} |
277 | 299 |
|
278 |
public static void ChangeRootPath(string oldPath,string newPath) |
|
300 |
public static void ChangeRootPath(string oldPath, string newPath)
|
|
279 | 301 |
{ |
280 | 302 |
if (String.IsNullOrWhiteSpace(oldPath)) |
281 | 303 |
throw new ArgumentNullException("oldPath"); |
... | ... | |
293 | 315 |
if (!newPath.EndsWith("\\")) |
294 | 316 |
newPath = newPath + "\\"; |
295 | 317 |
|
296 |
using (new TransactionScope()) |
|
297 |
{ |
|
298 |
Execute((session, instance) => |
|
318 |
ExecuteWithRetry((session, instance) => |
|
299 | 319 |
{ |
300 | 320 |
const string hqlUpdate = |
301 | 321 |
"update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' "; |
302 |
var renames=session.CreateQuery(hqlUpdate)
|
|
322 |
var renames = session.CreateQuery(hqlUpdate)
|
|
303 | 323 |
.SetString("oldPath", oldPath.ToLower()) |
304 | 324 |
.SetString("newPath", newPath.ToLower()) |
305 | 325 |
.ExecuteUpdate(); |
306 | 326 |
return renames; |
307 | 327 |
}, null); |
308 |
} |
|
309 | 328 |
} |
310 | 329 |
|
311 |
public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
|
|
330 |
public static Task<FileState> CreateForAsync(string filePath, int blockSize, string algorithm)
|
|
312 | 331 |
{ |
313 | 332 |
if (blockSize <= 0) |
314 | 333 |
throw new ArgumentOutOfRangeException("blockSize"); |
... | ... | |
319 | 338 |
|
320 | 339 |
var fileState = new FileState |
321 | 340 |
{ |
322 |
FilePath = filePath.ToLower(),
|
|
323 |
OverlayStatus = FileOverlayStatus.Unversioned,
|
|
341 |
FilePath = filePath.ToLower(), |
|
342 |
OverlayStatus = FileOverlayStatus.Unversioned, |
|
324 | 343 |
FileStatus = FileStatus.Created, |
325 |
Id=Guid.NewGuid()
|
|
344 |
Id = Guid.NewGuid()
|
|
326 | 345 |
}; |
327 | 346 |
|
328 | 347 |
|
329 |
return fileState.UpdateHashesAsync(blockSize,algorithm);
|
|
348 |
return fileState.UpdateHashesAsync(blockSize, algorithm);
|
|
330 | 349 |
} |
331 | 350 |
|
332 |
public async Task<FileState> UpdateHashesAsync(int blockSize,string algorithm) |
|
351 |
public async Task<FileState> UpdateHashesAsync(int blockSize, string algorithm)
|
|
333 | 352 |
{ |
334 |
if (blockSize<=0)
|
|
353 |
if (blockSize <= 0)
|
|
335 | 354 |
throw new ArgumentOutOfRangeException("blockSize"); |
336 | 355 |
if (String.IsNullOrWhiteSpace(algorithm)) |
337 | 356 |
throw new ArgumentNullException("algorithm"); |
338 | 357 |
Contract.EndContractBlock(); |
339 |
|
|
358 |
|
|
340 | 359 |
//Skip updating the hash for folders |
341 | 360 |
if (Directory.Exists(FilePath)) |
342 | 361 |
return this; |
343 | 362 |
|
344 | 363 |
var hash = await TaskEx.Run(() => |
345 |
{ |
|
346 |
var info = new FileInfo(FilePath); |
|
347 |
return info.CalculateHash(blockSize, algorithm); |
|
348 |
}); |
|
364 |
{
|
|
365 |
var info = new FileInfo(FilePath);
|
|
366 |
return info.CalculateHash(blockSize, algorithm);
|
|
367 |
});
|
|
349 | 368 |
|
350 | 369 |
Checksum = hash; |
351 |
|
|
370 |
|
|
352 | 371 |
return this; |
353 | 372 |
} |
373 |
|
|
374 |
private static void ExecuteWithRetry(NHibernateDelegate call, object state) |
|
375 |
{ |
|
376 |
int retries = 3; |
|
377 |
while (retries > 0) |
|
378 |
try |
|
379 |
{ |
|
380 |
using (new SessionScope()) |
|
381 |
{ |
|
382 |
Execute(call, state); |
|
383 |
} |
|
384 |
} |
|
385 |
catch (ActiveRecordException exc) |
|
386 |
{ |
|
387 |
retries--; |
|
388 |
if (retries <= 0) |
|
389 |
throw; |
|
390 |
} |
|
391 |
catch (Exception exc) |
|
392 |
{ |
|
393 |
throw; |
|
394 |
} |
|
395 |
|
|
396 |
} |
|
354 | 397 |
} |
355 | 398 |
|
356 | 399 |
[ActiveRecord("Tags")] |
Also available in: Unified diff