1 // -----------------------------------------------------------------------
2 // <copyright file="FileState.cs" company="Microsoft">
3 // TODO: Update copyright text.
5 // -----------------------------------------------------------------------
7 using System.Diagnostics.Contracts;
9 using System.Threading.Tasks;
10 using Castle.ActiveRecord;
11 using Castle.ActiveRecord.Framework;
12 using Castle.ActiveRecord.Queries;
13 using NHibernate.Engine;
14 using Pithos.Core.Agents;
15 using Pithos.Interfaces;
21 using System.Collections.Generic;
26 /// TODO: Update summary.
29 public class FileState:ActiveRecordLinqBase<FileState>
31 private string _filePath;
32 private IList<FileTag> _tags=new List<FileTag>();
34 [PrimaryKey(PrimaryKeyType.Guid)]
35 public Guid Id { get; set; }
37 [Property(Unique=true,UniqueKey="IX_FileState_FilePath")]
38 public string FilePath
40 get { return _filePath; }
41 set { _filePath = value.ToLower(); }
45 public FileOverlayStatus OverlayStatus { get; set; }
48 public FileStatus FileStatus { get; set; }
51 public string Checksum { get; set; }
55 public string TopHash { get; set; }
59 public long? Version { get; set; }
62 public DateTime? VersionTimeStamp { get; set; }
66 public bool IsShared { get; set; }
69 public string SharedBy { get; set; }
72 public bool ShareWrite { get; set; }
75 [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true,Inverse=true)]
76 public IList<FileTag> Tags
82 // [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
83 // public IList<FileHash> Hashes { get; set; }
86 // public byte[] HashmapHash { get; set; }
88 public static FileState FindByFilePath(string absolutePath)
90 if (string.IsNullOrWhiteSpace(absolutePath))
91 throw new ArgumentNullException("absolutePath");
92 Contract.EndContractBlock();
93 return Queryable.FirstOrDefault(s => s.FilePath == absolutePath.ToLower());
96 public static void DeleteByFilePath(string absolutePath)
98 if(string.IsNullOrWhiteSpace(absolutePath))
99 throw new ArgumentNullException("absolutePath");
100 Contract.EndContractBlock();
102 FileState.Execute((session, instance) =>
104 const string hqlDelete = "delete FileState where FilePath = :path";
105 var deletedEntities = session.CreateQuery(hqlDelete)
106 .SetString("path", absolutePath.ToLower())
113 public static void ChangeRootPath(string oldPath,string newPath)
115 if (String.IsNullOrWhiteSpace(oldPath))
116 throw new ArgumentNullException("oldPath");
117 if (!Path.IsPathRooted(oldPath))
118 throw new ArgumentException("oldPath must be an absolute path", "oldPath");
119 if (string.IsNullOrWhiteSpace(newPath))
120 throw new ArgumentNullException("newPath");
121 if (!Path.IsPathRooted(newPath))
122 throw new ArgumentException("newPath must be an absolute path", "newPath");
123 Contract.EndContractBlock();
125 //Ensure the paths end with the same character
126 if (!oldPath.EndsWith("\\"))
127 oldPath = oldPath + "\\";
128 if (!newPath.EndsWith("\\"))
129 newPath = newPath + "\\";
131 using (new TransactionScope())
133 Execute((session, instance) =>
135 const string hqlUpdate =
136 "update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
137 var result=session.CreateQuery(hqlUpdate)
138 .SetString("oldPath", oldPath.ToLower())
139 .SetString("newPath", newPath.ToLower())
146 public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
149 throw new ArgumentOutOfRangeException("blockSize");
150 if (String.IsNullOrWhiteSpace(algorithm))
151 throw new ArgumentNullException("algorithm");
152 Contract.EndContractBlock();
155 var fileState = new FileState
158 OverlayStatus = FileOverlayStatus.Unversioned,
159 FileStatus = FileStatus.Created,
164 return fileState.UpdateHashesAsync(blockSize,algorithm);
167 public Task<FileState> UpdateHashesAsync(int blockSize,string algorithm)
170 throw new ArgumentOutOfRangeException("blockSize");
171 if (String.IsNullOrWhiteSpace(algorithm))
172 throw new ArgumentNullException("algorithm");
173 Contract.EndContractBlock();
175 //Skip updating the hash for folders
176 if (Directory.Exists(FilePath))
177 return Task.Factory.FromResult(this);
179 var results = Task.Factory.StartNew(() =>
181 var info = new FileInfo(FilePath);
182 return info.CalculateHash(blockSize, algorithm);
185 var state=results.Then(hash =>
188 return Task.Factory.FromResult(this);
195 [ActiveRecord("Tags")]
196 public class FileTag : ActiveRecordLinqBase<FileTag>
199 public int Id { get; set; }
202 public string Name { get; set; }
205 public string Value { get; set; }
207 [BelongsTo("FileStateId")]
208 public FileState FileState { get; set; }
212 /* [ActiveRecord("hashes")]
213 public class FileHash : ActiveRecordLinqBase<FileHash>
216 public int Id { get; set; }
219 public int Order { get; set; }
222 public byte[] Value { get; set; }
224 [BelongsTo("FileStateID")]
225 public FileState FileState { get; set; }