root / trunk / Pithos.Core / Agents / StatusAgent.cs @ cfed7823
History | View | Annotate | Download (21 kB)
1 | 0eea575a | Panagiotis Kanavos | using System; |
---|---|---|---|
2 | 0eea575a | Panagiotis Kanavos | using System.Collections.Generic; |
3 | 0eea575a | Panagiotis Kanavos | using System.ComponentModel.Composition; |
4 | 0eea575a | Panagiotis Kanavos | using System.Diagnostics; |
5 | 0eea575a | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
6 | 0eea575a | Panagiotis Kanavos | using System.IO; |
7 | 0eea575a | Panagiotis Kanavos | using System.Linq; |
8 | 0eea575a | Panagiotis Kanavos | using System.Threading; |
9 | 0eea575a | Panagiotis Kanavos | using System.Threading.Tasks; |
10 | 0eea575a | Panagiotis Kanavos | using Castle.ActiveRecord; |
11 | 0eea575a | Panagiotis Kanavos | using Castle.ActiveRecord.Framework.Config; |
12 | 0eea575a | Panagiotis Kanavos | using Pithos.Interfaces; |
13 | cfed7823 | Panagiotis Kanavos | using log4net; |
14 | cfed7823 | Panagiotis Kanavos | using log4net.Appender; |
15 | cfed7823 | Panagiotis Kanavos | using log4net.Config; |
16 | cfed7823 | Panagiotis Kanavos | using log4net.Layout; |
17 | 0eea575a | Panagiotis Kanavos | |
18 | cfed7823 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
19 | 0eea575a | Panagiotis Kanavos | { |
20 | 0eea575a | Panagiotis Kanavos | [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))] |
21 | cfed7823 | Panagiotis Kanavos | public class StatusAgent:IStatusChecker,IStatusKeeper |
22 | 0eea575a | Panagiotis Kanavos | { |
23 | 0eea575a | Panagiotis Kanavos | [System.ComponentModel.Composition.Import] |
24 | 0eea575a | Panagiotis Kanavos | public IPithosSettings Settings { get; set; } |
25 | 0eea575a | Panagiotis Kanavos | |
26 | 9c4346c9 | Panagiotis Kanavos | private Agent<Action> _persistenceAgent; |
27 | 0eea575a | Panagiotis Kanavos | |
28 | cfed7823 | Panagiotis Kanavos | |
29 | cfed7823 | Panagiotis Kanavos | private static readonly ILog log = LogManager.GetLogger(typeof(StatusAgent)); |
30 | cfed7823 | Panagiotis Kanavos | |
31 | cfed7823 | Panagiotis Kanavos | public StatusAgent() |
32 | 3c43ec9b | Panagiotis Kanavos | { |
33 | 3c43ec9b | Panagiotis Kanavos | var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); |
34 | 9c4346c9 | Panagiotis Kanavos | _pithosDataPath = Path.Combine(appDataPath , "Pithos"); |
35 | 3c43ec9b | Panagiotis Kanavos | |
36 | 9c4346c9 | Panagiotis Kanavos | if (!Directory.Exists(_pithosDataPath)) |
37 | 9c4346c9 | Panagiotis Kanavos | Directory.CreateDirectory(_pithosDataPath); |
38 | 9c4346c9 | Panagiotis Kanavos | |
39 | 0af3141d | Panagiotis Kanavos | //File.Delete(Path.Combine(_pithosDataPath, "pithos.db")); |
40 | cfed7823 | Panagiotis Kanavos | |
41 | 9c4346c9 | Panagiotis Kanavos | |
42 | 9c4346c9 | Panagiotis Kanavos | var source = GetConfiguration(_pithosDataPath); |
43 | 9c4346c9 | Panagiotis Kanavos | ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag)); |
44 | cfed7823 | Panagiotis Kanavos | ActiveRecordStarter.UpdateSchema(); |
45 | 9c4346c9 | Panagiotis Kanavos | |
46 | 9c4346c9 | Panagiotis Kanavos | ; |
47 | 9c4346c9 | Panagiotis Kanavos | if (!File.Exists(Path.Combine(_pithosDataPath ,"pithos.db"))) |
48 | 0eea575a | Panagiotis Kanavos | ActiveRecordStarter.CreateSchema(); |
49 | 5ce54458 | Panagiotis Kanavos | |
50 | cfed7823 | Panagiotis Kanavos | |
51 | cfed7823 | Panagiotis Kanavos | |
52 | 5ce54458 | Panagiotis Kanavos | CleanupStaleStates(); |
53 | 0eea575a | Panagiotis Kanavos | |
54 | cfed7823 | Panagiotis Kanavos | } |
55 | 9c4346c9 | Panagiotis Kanavos | |
56 | 5ce54458 | Panagiotis Kanavos | private void CleanupStaleStates() |
57 | 5ce54458 | Panagiotis Kanavos | { |
58 | 5ce54458 | Panagiotis Kanavos | /*var stales = from state in FileState.Queryable |
59 | 5ce54458 | Panagiotis Kanavos | where state.FilePath.StartsWith(@"e:\pithos\fragments") |
60 | 5ce54458 | Panagiotis Kanavos | select state.Id;*/ |
61 | 5ce54458 | Panagiotis Kanavos | FileState.DeleteAll(@"FilePath like 'e:\pithos\fragments%'"); |
62 | 5ce54458 | Panagiotis Kanavos | ; |
63 | 3c43ec9b | Panagiotis Kanavos | } |
64 | 3c43ec9b | Panagiotis Kanavos | |
65 | 3c43ec9b | Panagiotis Kanavos | private static InPlaceConfigurationSource GetConfiguration(string pithosDbPath) |
66 | 3c43ec9b | Panagiotis Kanavos | { |
67 | 9c4346c9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(pithosDbPath)) |
68 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("pithosDbPath"); |
69 | 9c4346c9 | Panagiotis Kanavos | if (!Path.IsPathRooted(pithosDbPath)) |
70 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentException("path must be a rooted path", "pithosDbPath"); |
71 | 9c4346c9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
72 | 9c4346c9 | Panagiotis Kanavos | |
73 | 3c43ec9b | Panagiotis Kanavos | var properties = new Dictionary<string, string> |
74 | 3c43ec9b | Panagiotis Kanavos | { |
75 | 3c43ec9b | Panagiotis Kanavos | {"connection.driver_class", "NHibernate.Driver.SQLite20Driver"}, |
76 | 3c43ec9b | Panagiotis Kanavos | {"dialect", "NHibernate.Dialect.SQLiteDialect"}, |
77 | 3c43ec9b | Panagiotis Kanavos | {"connection.provider", "NHibernate.Connection.DriverConnectionProvider"}, |
78 | 3c43ec9b | Panagiotis Kanavos | { |
79 | 3c43ec9b | Panagiotis Kanavos | "proxyfactory.factory_class", |
80 | 3c43ec9b | Panagiotis Kanavos | "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" |
81 | 3c43ec9b | Panagiotis Kanavos | }, |
82 | 3c43ec9b | Panagiotis Kanavos | }; |
83 | 3c43ec9b | Panagiotis Kanavos | |
84 | 3c43ec9b | Panagiotis Kanavos | var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3", pithosDbPath); |
85 | 3c43ec9b | Panagiotis Kanavos | properties.Add("connection.connection_string", connectionString); |
86 | 3c43ec9b | Panagiotis Kanavos | |
87 | 3c43ec9b | Panagiotis Kanavos | var source = new InPlaceConfigurationSource(); |
88 | 3c43ec9b | Panagiotis Kanavos | |
89 | 3c43ec9b | Panagiotis Kanavos | source.Add(typeof (ActiveRecordBase), properties); |
90 | 3c43ec9b | Panagiotis Kanavos | return source; |
91 | 3c43ec9b | Panagiotis Kanavos | } |
92 | 3c43ec9b | Panagiotis Kanavos | |
93 | 3c43ec9b | Panagiotis Kanavos | public void StartProcessing(CancellationToken token) |
94 | 3c43ec9b | Panagiotis Kanavos | { |
95 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent = Agent<Action>.Start(queue => |
96 | 9c4346c9 | Panagiotis Kanavos | { |
97 | 9c4346c9 | Panagiotis Kanavos | Action loop = null; |
98 | 9c4346c9 | Panagiotis Kanavos | loop = () => |
99 | 9c4346c9 | Panagiotis Kanavos | { |
100 | 9c4346c9 | Panagiotis Kanavos | var job = queue.Receive(); |
101 | 9c4346c9 | Panagiotis Kanavos | job.ContinueWith(t => |
102 | 9c4346c9 | Panagiotis Kanavos | { |
103 | 9c4346c9 | Panagiotis Kanavos | var action = job.Result; |
104 | 5ce54458 | Panagiotis Kanavos | try |
105 | 5ce54458 | Panagiotis Kanavos | { |
106 | 5ce54458 | Panagiotis Kanavos | action(); |
107 | 5ce54458 | Panagiotis Kanavos | } |
108 | 5ce54458 | Panagiotis Kanavos | catch (Exception ex) |
109 | 5ce54458 | Panagiotis Kanavos | { |
110 | 5ce54458 | Panagiotis Kanavos | Trace.TraceError("[ERROR] STATE \n{0}",ex); |
111 | 5ce54458 | Panagiotis Kanavos | } |
112 | 9c4346c9 | Panagiotis Kanavos | queue.DoAsync(loop); |
113 | 9c4346c9 | Panagiotis Kanavos | }); |
114 | 9c4346c9 | Panagiotis Kanavos | }; |
115 | 9c4346c9 | Panagiotis Kanavos | loop(); |
116 | 9c4346c9 | Panagiotis Kanavos | }); |
117 | d15e99b4 | Panagiotis Kanavos | |
118 | 0eea575a | Panagiotis Kanavos | } |
119 | 0eea575a | Panagiotis Kanavos | |
120 | d15e99b4 | Panagiotis Kanavos | |
121 | 0eea575a | Panagiotis Kanavos | |
122 | 0eea575a | Panagiotis Kanavos | public void Stop() |
123 | 0eea575a | Panagiotis Kanavos | { |
124 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent.Stop(); |
125 | 0eea575a | Panagiotis Kanavos | } |
126 | 283809f3 | Panagiotis Kanavos | |
127 | 0eea575a | Panagiotis Kanavos | |
128 | 0af3141d | Panagiotis Kanavos | public void ProcessExistingFiles(IEnumerable<FileInfo> existingFiles) |
129 | 9c4346c9 | Panagiotis Kanavos | { |
130 | 0af3141d | Panagiotis Kanavos | if(existingFiles ==null) |
131 | 0af3141d | Panagiotis Kanavos | throw new ArgumentNullException("existingFiles"); |
132 | 0af3141d | Panagiotis Kanavos | Contract.EndContractBlock(); |
133 | 9c4346c9 | Panagiotis Kanavos | |
134 | 0af3141d | Panagiotis Kanavos | //Find new or matching files with a left join to the stored states |
135 | 0af3141d | Panagiotis Kanavos | var fileStates = FileState.Queryable; |
136 | 0af3141d | Panagiotis Kanavos | var currentFiles=from file in existingFiles |
137 | 0af3141d | Panagiotis Kanavos | join state in fileStates on file.FullName.ToLower() equals state.FilePath.ToLower() into gs |
138 | 0af3141d | Panagiotis Kanavos | from substate in gs.DefaultIfEmpty() |
139 | 0af3141d | Panagiotis Kanavos | select new {File = file, State = substate}; |
140 | 0af3141d | Panagiotis Kanavos | |
141 | 0af3141d | Panagiotis Kanavos | //To get the deleted files we must get the states that have no corresponding |
142 | 0af3141d | Panagiotis Kanavos | //files. |
143 | 0af3141d | Panagiotis Kanavos | //We can't use the File.Exists method inside a query, so we get all file paths from the states |
144 | 0af3141d | Panagiotis Kanavos | var statePaths = (from state in fileStates |
145 | 0af3141d | Panagiotis Kanavos | select new {state.Id, state.FilePath}).ToList(); |
146 | 0af3141d | Panagiotis Kanavos | //and check each one |
147 | 0af3141d | Panagiotis Kanavos | var missingStates= (from path in statePaths |
148 | 0af3141d | Panagiotis Kanavos | where !File.Exists(path.FilePath) |
149 | 0af3141d | Panagiotis Kanavos | select path.Id).ToList(); |
150 | 0af3141d | Panagiotis Kanavos | //Finally, retrieve the states that correspond to the deleted files |
151 | 0af3141d | Panagiotis Kanavos | var deletedFiles = from state in fileStates |
152 | 0af3141d | Panagiotis Kanavos | where missingStates.Contains(state.Id) |
153 | 0af3141d | Panagiotis Kanavos | select new { File = default(FileInfo), State = state }; |
154 | 0af3141d | Panagiotis Kanavos | |
155 | 0af3141d | Panagiotis Kanavos | var pairs = currentFiles.Union(deletedFiles); |
156 | 0af3141d | Panagiotis Kanavos | |
157 | 0af3141d | Panagiotis Kanavos | Parallel.ForEach(pairs, pair => |
158 | 0eea575a | Panagiotis Kanavos | { |
159 | 0af3141d | Panagiotis Kanavos | var fileState = pair.State; |
160 | 0af3141d | Panagiotis Kanavos | var file = pair.File; |
161 | 0af3141d | Panagiotis Kanavos | if (fileState == null) |
162 | 0af3141d | Panagiotis Kanavos | { |
163 | 0af3141d | Panagiotis Kanavos | //This is a new file |
164 | 0af3141d | Panagiotis Kanavos | var fullPath = pair.File.FullName.ToLower(); |
165 | 0af3141d | Panagiotis Kanavos | var createState = FileState.CreateForAsync(fullPath, this.BlockSize, this.BlockHash); |
166 | 0af3141d | Panagiotis Kanavos | createState.ContinueWith(state => _persistenceAgent.Post(state.Result.Create)); |
167 | 0af3141d | Panagiotis Kanavos | } |
168 | 0af3141d | Panagiotis Kanavos | else if (file == null) |
169 | 0af3141d | Panagiotis Kanavos | { |
170 | 0af3141d | Panagiotis Kanavos | //This file was deleted while we were down. We should mark it as deleted |
171 | 0af3141d | Panagiotis Kanavos | //We have to go through UpdateStatus here because the state object we are using |
172 | 0af3141d | Panagiotis Kanavos | //was created by a different ORM session. |
173 | 0af3141d | Panagiotis Kanavos | UpdateStatus(fileState.Id,state=> state.FileStatus = FileStatus.Deleted); |
174 | 0af3141d | Panagiotis Kanavos | } |
175 | 0af3141d | Panagiotis Kanavos | else |
176 | 0af3141d | Panagiotis Kanavos | { |
177 | 0af3141d | Panagiotis Kanavos | //This file has a matching state. Need to check for possible changes |
178 | 0af3141d | Panagiotis Kanavos | var hashString = file.CalculateHash(BlockSize,BlockHash); |
179 | 0af3141d | Panagiotis Kanavos | //If the hashes don't match the file was changed |
180 | 0af3141d | Panagiotis Kanavos | if (fileState.Checksum != hashString) |
181 | 9c4346c9 | Panagiotis Kanavos | { |
182 | 0af3141d | Panagiotis Kanavos | UpdateStatus(fileState.Id, state => state.FileStatus = FileStatus.Modified); |
183 | 0af3141d | Panagiotis Kanavos | } |
184 | 0af3141d | Panagiotis Kanavos | } |
185 | 0af3141d | Panagiotis Kanavos | }); |
186 | 0af3141d | Panagiotis Kanavos | |
187 | 0eea575a | Panagiotis Kanavos | } |
188 | 0eea575a | Panagiotis Kanavos | |
189 | 0af3141d | Panagiotis Kanavos | |
190 | 0af3141d | Panagiotis Kanavos | |
191 | 0eea575a | Panagiotis Kanavos | |
192 | 9c4346c9 | Panagiotis Kanavos | public string BlockHash { get; set; } |
193 | 9c4346c9 | Panagiotis Kanavos | |
194 | 9c4346c9 | Panagiotis Kanavos | public int BlockSize { get; set; } |
195 | 9c4346c9 | Panagiotis Kanavos | |
196 | 0eea575a | Panagiotis Kanavos | private PithosStatus _pithosStatus=PithosStatus.InSynch; |
197 | 0eea575a | Panagiotis Kanavos | |
198 | 0eea575a | Panagiotis Kanavos | public void SetPithosStatus(PithosStatus status) |
199 | 0eea575a | Panagiotis Kanavos | { |
200 | 0eea575a | Panagiotis Kanavos | _pithosStatus = status; |
201 | 0eea575a | Panagiotis Kanavos | } |
202 | 0eea575a | Panagiotis Kanavos | |
203 | 0eea575a | Panagiotis Kanavos | public PithosStatus GetPithosStatus() |
204 | 0eea575a | Panagiotis Kanavos | { |
205 | 0eea575a | Panagiotis Kanavos | return _pithosStatus; |
206 | 0eea575a | Panagiotis Kanavos | } |
207 | 0eea575a | Panagiotis Kanavos | |
208 | 283809f3 | Panagiotis Kanavos | |
209 | 9c4346c9 | Panagiotis Kanavos | private string _pithosDataPath; |
210 | 283809f3 | Panagiotis Kanavos | |
211 | 283809f3 | Panagiotis Kanavos | public T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue ) |
212 | 283809f3 | Panagiotis Kanavos | { |
213 | 9c4346c9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
214 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
215 | 9c4346c9 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
216 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentException("path must be a rooted path", "path"); |
217 | cfed7823 | Panagiotis Kanavos | if (getter == null) |
218 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("getter"); |
219 | 9c4346c9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
220 | 283809f3 | Panagiotis Kanavos | |
221 | 283809f3 | Panagiotis Kanavos | |
222 | 283809f3 | Panagiotis Kanavos | try |
223 | 9c4346c9 | Panagiotis Kanavos | { |
224 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(path); |
225 | 283809f3 | Panagiotis Kanavos | return state == null ? defaultValue : getter(state); |
226 | 283809f3 | Panagiotis Kanavos | } |
227 | 283809f3 | Panagiotis Kanavos | catch (Exception exc) |
228 | 283809f3 | Panagiotis Kanavos | { |
229 | 283809f3 | Panagiotis Kanavos | Trace.TraceError(exc.ToString()); |
230 | 283809f3 | Panagiotis Kanavos | return defaultValue; |
231 | 283809f3 | Panagiotis Kanavos | } |
232 | 283809f3 | Panagiotis Kanavos | } |
233 | 283809f3 | Panagiotis Kanavos | |
234 | 283809f3 | Panagiotis Kanavos | /// <summary> |
235 | 283809f3 | Panagiotis Kanavos | /// Sets the status of a file, creating a new FileState entry if one doesn't already exist. |
236 | 283809f3 | Panagiotis Kanavos | /// </summary> |
237 | 283809f3 | Panagiotis Kanavos | /// <param name="path"></param> |
238 | 283809f3 | Panagiotis Kanavos | /// <param name="setter"></param> |
239 | 283809f3 | Panagiotis Kanavos | public void SetStatus(string path,Action<FileState> setter) |
240 | 283809f3 | Panagiotis Kanavos | { |
241 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
242 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("path", "path can't be empty"); |
243 | 283809f3 | Panagiotis Kanavos | if (setter==null) |
244 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("setter", "setter can't be empty"); |
245 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
246 | 283809f3 | Panagiotis Kanavos | |
247 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
248 | 283809f3 | Panagiotis Kanavos | { |
249 | 5ce54458 | Panagiotis Kanavos | using (new SessionScope()) |
250 | 283809f3 | Panagiotis Kanavos | { |
251 | 5ce54458 | Panagiotis Kanavos | var filePath = path.ToLower(); |
252 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(filePath); |
253 | 5ce54458 | Panagiotis Kanavos | if (state != null) |
254 | 5ce54458 | Panagiotis Kanavos | { |
255 | 5ce54458 | Panagiotis Kanavos | setter(state); |
256 | 5ce54458 | Panagiotis Kanavos | state.Save(); |
257 | 5ce54458 | Panagiotis Kanavos | } |
258 | 5ce54458 | Panagiotis Kanavos | else |
259 | 5ce54458 | Panagiotis Kanavos | { |
260 | 5ce54458 | Panagiotis Kanavos | state = new FileState {FilePath = filePath}; |
261 | 5ce54458 | Panagiotis Kanavos | setter(state); |
262 | 5ce54458 | Panagiotis Kanavos | state.Save(); |
263 | 5ce54458 | Panagiotis Kanavos | } |
264 | 283809f3 | Panagiotis Kanavos | } |
265 | 283809f3 | Panagiotis Kanavos | }); |
266 | 283809f3 | Panagiotis Kanavos | } |
267 | 283809f3 | Panagiotis Kanavos | |
268 | 283809f3 | Panagiotis Kanavos | /// <summary> |
269 | 283809f3 | Panagiotis Kanavos | /// Sets the status of a file only if the file already exists |
270 | 283809f3 | Panagiotis Kanavos | /// </summary> |
271 | 283809f3 | Panagiotis Kanavos | /// <param name="path"></param> |
272 | 283809f3 | Panagiotis Kanavos | /// <param name="setter"></param> |
273 | 283809f3 | Panagiotis Kanavos | private void UpdateStatus(string path, Action<FileState> setter) |
274 | 283809f3 | Panagiotis Kanavos | { |
275 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
276 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
277 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
278 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
279 | cfed7823 | Panagiotis Kanavos | if (setter == null) |
280 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("setter"); |
281 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
282 | cfed7823 | Panagiotis Kanavos | |
283 | 5ce54458 | Panagiotis Kanavos | Debug.Assert(!path.Contains("fragments")); |
284 | 5ce54458 | Panagiotis Kanavos | Debug.Assert(!path.EndsWith(".ignore")); |
285 | 5ce54458 | Panagiotis Kanavos | |
286 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
287 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("path", "path can't be empty"); |
288 | 283809f3 | Panagiotis Kanavos | |
289 | 283809f3 | Panagiotis Kanavos | if (setter == null) |
290 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("setter", "setter can't be empty"); |
291 | 283809f3 | Panagiotis Kanavos | |
292 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
293 | 283809f3 | Panagiotis Kanavos | { |
294 | 5ce54458 | Panagiotis Kanavos | using (new SessionScope()) |
295 | 283809f3 | Panagiotis Kanavos | { |
296 | 5ce54458 | Panagiotis Kanavos | var filePath = path.ToLower(); |
297 | 5ce54458 | Panagiotis Kanavos | |
298 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(filePath); |
299 | 5ce54458 | Panagiotis Kanavos | if (state == null) |
300 | 5ce54458 | Panagiotis Kanavos | { |
301 | 5ce54458 | Panagiotis Kanavos | Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", filePath); |
302 | 5ce54458 | Panagiotis Kanavos | return; |
303 | 5ce54458 | Panagiotis Kanavos | } |
304 | 5ce54458 | Panagiotis Kanavos | setter(state); |
305 | 5ce54458 | Panagiotis Kanavos | state.Save(); |
306 | 283809f3 | Panagiotis Kanavos | } |
307 | 5ce54458 | Panagiotis Kanavos | |
308 | 283809f3 | Panagiotis Kanavos | }); |
309 | 283809f3 | Panagiotis Kanavos | } |
310 | 0af3141d | Panagiotis Kanavos | |
311 | 0af3141d | Panagiotis Kanavos | /// <summary> |
312 | 0af3141d | Panagiotis Kanavos | /// Sets the status of a specific state |
313 | 0af3141d | Panagiotis Kanavos | /// </summary> |
314 | 0af3141d | Panagiotis Kanavos | /// <param name="path"></param> |
315 | 0af3141d | Panagiotis Kanavos | /// <param name="setter"></param> |
316 | 0af3141d | Panagiotis Kanavos | private void UpdateStatus(Guid stateID, Action<FileState> setter) |
317 | 0af3141d | Panagiotis Kanavos | { |
318 | cfed7823 | Panagiotis Kanavos | if (setter == null) |
319 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("setter"); |
320 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
321 | cfed7823 | Panagiotis Kanavos | |
322 | cfed7823 | Panagiotis Kanavos | |
323 | 0af3141d | Panagiotis Kanavos | _persistenceAgent.Post(() => |
324 | 0af3141d | Panagiotis Kanavos | { |
325 | 0af3141d | Panagiotis Kanavos | using (new SessionScope()) |
326 | 0af3141d | Panagiotis Kanavos | { |
327 | 0af3141d | Panagiotis Kanavos | var state = FileState.Find(stateID); |
328 | 0af3141d | Panagiotis Kanavos | if (state == null) |
329 | 0af3141d | Panagiotis Kanavos | { |
330 | 0af3141d | Panagiotis Kanavos | Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", stateID); |
331 | 0af3141d | Panagiotis Kanavos | return; |
332 | 0af3141d | Panagiotis Kanavos | } |
333 | 0af3141d | Panagiotis Kanavos | setter(state); |
334 | 0af3141d | Panagiotis Kanavos | state.Save(); |
335 | 0af3141d | Panagiotis Kanavos | } |
336 | 0af3141d | Panagiotis Kanavos | |
337 | 0af3141d | Panagiotis Kanavos | }); |
338 | 0af3141d | Panagiotis Kanavos | } |
339 | 283809f3 | Panagiotis Kanavos | |
340 | 283809f3 | Panagiotis Kanavos | public FileOverlayStatus GetFileOverlayStatus(string path) |
341 | 283809f3 | Panagiotis Kanavos | { |
342 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
343 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
344 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
345 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
346 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
347 | cfed7823 | Panagiotis Kanavos | |
348 | 283809f3 | Panagiotis Kanavos | try |
349 | 283809f3 | Panagiotis Kanavos | { |
350 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(path); |
351 | 283809f3 | Panagiotis Kanavos | return state == null ? FileOverlayStatus.Unversioned : state.OverlayStatus; |
352 | 283809f3 | Panagiotis Kanavos | } |
353 | 283809f3 | Panagiotis Kanavos | catch (Exception exc) |
354 | 283809f3 | Panagiotis Kanavos | { |
355 | 283809f3 | Panagiotis Kanavos | Trace.TraceError(exc.ToString()); |
356 | 283809f3 | Panagiotis Kanavos | return FileOverlayStatus.Unversioned; |
357 | 283809f3 | Panagiotis Kanavos | } |
358 | 283809f3 | Panagiotis Kanavos | } |
359 | 283809f3 | Panagiotis Kanavos | |
360 | 0eea575a | Panagiotis Kanavos | public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus) |
361 | 0eea575a | Panagiotis Kanavos | { |
362 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
363 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
364 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
365 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted","path"); |
366 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
367 | cfed7823 | Panagiotis Kanavos | |
368 | cfed7823 | Panagiotis Kanavos | SetStatus(path.ToLower(),s=>s.OverlayStatus=overlayStatus); |
369 | 0eea575a | Panagiotis Kanavos | } |
370 | 0eea575a | Panagiotis Kanavos | |
371 | cfed7823 | Panagiotis Kanavos | /*public void RemoveFileOverlayStatus(string path) |
372 | 0eea575a | Panagiotis Kanavos | { |
373 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
374 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
375 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
376 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
377 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
378 | cfed7823 | Panagiotis Kanavos | |
379 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
380 | 0eea575a | Panagiotis Kanavos | InnerRemoveFileOverlayStatus(path)); |
381 | 0eea575a | Panagiotis Kanavos | } |
382 | 0eea575a | Panagiotis Kanavos | |
383 | 0eea575a | Panagiotis Kanavos | private static void InnerRemoveFileOverlayStatus(string path) |
384 | 0eea575a | Panagiotis Kanavos | { |
385 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
386 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
387 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
388 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
389 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
390 | cfed7823 | Panagiotis Kanavos | |
391 | cfed7823 | Panagiotis Kanavos | FileState.DeleteByFilePath(path); |
392 | cfed7823 | Panagiotis Kanavos | }*/ |
393 | 0eea575a | Panagiotis Kanavos | |
394 | 0eea575a | Panagiotis Kanavos | public void RenameFileOverlayStatus(string oldPath, string newPath) |
395 | 0eea575a | Panagiotis Kanavos | { |
396 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(oldPath)) |
397 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("oldPath"); |
398 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(oldPath)) |
399 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The oldPath must be rooted", "oldPath"); |
400 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(newPath)) |
401 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("newPath"); |
402 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(newPath)) |
403 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The newPath must be rooted", "newPath"); |
404 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
405 | cfed7823 | Panagiotis Kanavos | |
406 | 9c4346c9 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
407 | 0eea575a | Panagiotis Kanavos | InnerRenameFileOverlayStatus(oldPath, newPath)); |
408 | 0eea575a | Panagiotis Kanavos | } |
409 | 0eea575a | Panagiotis Kanavos | |
410 | 0eea575a | Panagiotis Kanavos | private static void InnerRenameFileOverlayStatus(string oldPath, string newPath) |
411 | bfc13ed8 | Panagiotis Kanavos | { |
412 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(oldPath)) |
413 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("oldPath"); |
414 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(oldPath)) |
415 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The oldPath must be rooted", "oldPath"); |
416 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(newPath)) |
417 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("newPath"); |
418 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(newPath)) |
419 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The newPath must be rooted", "newPath"); |
420 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
421 | cfed7823 | Panagiotis Kanavos | |
422 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(oldPath); |
423 | 9c4346c9 | Panagiotis Kanavos | |
424 | 0050438e | Panagiotis Kanavos | if (state == null) |
425 | 0050438e | Panagiotis Kanavos | { |
426 | 0050438e | Panagiotis Kanavos | Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", oldPath); |
427 | 0050438e | Panagiotis Kanavos | return; |
428 | 0050438e | Panagiotis Kanavos | } |
429 | 0eea575a | Panagiotis Kanavos | //NOTE: This will cause problems if path is used as a key in relationships |
430 | 0eea575a | Panagiotis Kanavos | state.FilePath = newPath; |
431 | 0eea575a | Panagiotis Kanavos | state.Update(); |
432 | 0eea575a | Panagiotis Kanavos | } |
433 | 0eea575a | Panagiotis Kanavos | |
434 | 283809f3 | Panagiotis Kanavos | public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus) |
435 | 0eea575a | Panagiotis Kanavos | { |
436 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
437 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
438 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
439 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
440 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
441 | bfc13ed8 | Panagiotis Kanavos | |
442 | cfed7823 | Panagiotis Kanavos | UpdateStatus(path.ToLower(),state=> |
443 | 283809f3 | Panagiotis Kanavos | { |
444 | 283809f3 | Panagiotis Kanavos | state.FileStatus = fileStatus; |
445 | 283809f3 | Panagiotis Kanavos | state.OverlayStatus = overlayStatus; |
446 | 283809f3 | Panagiotis Kanavos | }); |
447 | 0eea575a | Panagiotis Kanavos | } |
448 | 0eea575a | Panagiotis Kanavos | |
449 | 283809f3 | Panagiotis Kanavos | public void StoreInfo(string path,ObjectInfo objectInfo) |
450 | 0eea575a | Panagiotis Kanavos | { |
451 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
452 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
453 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
454 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
455 | cfed7823 | Panagiotis Kanavos | if (objectInfo == null) |
456 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("objectInfo", "objectInfo can't be empty"); |
457 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
458 | 5ce54458 | Panagiotis Kanavos | |
459 | 5ce54458 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
460 | 3c43ec9b | Panagiotis Kanavos | { |
461 | 5ce54458 | Panagiotis Kanavos | var filePath = path.ToLower(); |
462 | 5ce54458 | Panagiotis Kanavos | //Load the existing files state and set its properties in one session |
463 | 5ce54458 | Panagiotis Kanavos | using (new SessionScope()) |
464 | 5ce54458 | Panagiotis Kanavos | { |
465 | 5ce54458 | Panagiotis Kanavos | //Forgetting to use a sessionscope results in two sessions being created, one by |
466 | 5ce54458 | Panagiotis Kanavos | //FirstOrDefault and one by Save() |
467 | bfc13ed8 | Panagiotis Kanavos | var state =FileState.FindByFilePath(filePath); |
468 | 5ce54458 | Panagiotis Kanavos | //Create a new empty state object if this is a new file |
469 | 5ce54458 | Panagiotis Kanavos | state = state ?? new FileState(); |
470 | 5ce54458 | Panagiotis Kanavos | |
471 | 5ce54458 | Panagiotis Kanavos | state.FilePath = filePath; |
472 | 5ce54458 | Panagiotis Kanavos | state.Checksum = objectInfo.Hash; |
473 | bfc13ed8 | Panagiotis Kanavos | state.Version = objectInfo.Version; |
474 | bfc13ed8 | Panagiotis Kanavos | state.VersionTimeStamp = objectInfo.VersionTimestamp; |
475 | bfc13ed8 | Panagiotis Kanavos | |
476 | 5ce54458 | Panagiotis Kanavos | state.FileStatus = FileStatus.Unchanged; |
477 | 5ce54458 | Panagiotis Kanavos | state.OverlayStatus = FileOverlayStatus.Normal; |
478 | bfc13ed8 | Panagiotis Kanavos | |
479 | 5ce54458 | Panagiotis Kanavos | //Create a list of tags from the ObjectInfo's tag dictionary |
480 | 5ce54458 | Panagiotis Kanavos | //Make sure to bind each tag to its parent state so we don't have to save each tag separately |
481 | 5ce54458 | Panagiotis Kanavos | //state.Tags = (from pair in objectInfo.Tags |
482 | 5ce54458 | Panagiotis Kanavos | // select |
483 | 5ce54458 | Panagiotis Kanavos | // new FileTag |
484 | 5ce54458 | Panagiotis Kanavos | // { |
485 | 5ce54458 | Panagiotis Kanavos | // FileState = state, |
486 | 5ce54458 | Panagiotis Kanavos | // Name = pair.Key, |
487 | 5ce54458 | Panagiotis Kanavos | // Value = pair.Value |
488 | 5ce54458 | Panagiotis Kanavos | // } |
489 | 5ce54458 | Panagiotis Kanavos | // ).ToList(); |
490 | 5ce54458 | Panagiotis Kanavos | |
491 | 5ce54458 | Panagiotis Kanavos | //Do the save |
492 | 5ce54458 | Panagiotis Kanavos | state.Save(); |
493 | 5ce54458 | Panagiotis Kanavos | } |
494 | 5ce54458 | Panagiotis Kanavos | }); |
495 | 5ce54458 | Panagiotis Kanavos | |
496 | 283809f3 | Panagiotis Kanavos | } |
497 | 283809f3 | Panagiotis Kanavos | |
498 | 283809f3 | Panagiotis Kanavos | |
499 | 283809f3 | Panagiotis Kanavos | public void SetFileStatus(string path, FileStatus status) |
500 | 283809f3 | Panagiotis Kanavos | { |
501 | cfed7823 | Panagiotis Kanavos | UpdateStatus(path.ToLower(), state=>state.FileStatus = status); |
502 | 283809f3 | Panagiotis Kanavos | } |
503 | 283809f3 | Panagiotis Kanavos | |
504 | 0eea575a | Panagiotis Kanavos | public FileStatus GetFileStatus(string path) |
505 | bfc13ed8 | Panagiotis Kanavos | { |
506 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
507 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
508 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
509 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
510 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
511 | cfed7823 | Panagiotis Kanavos | |
512 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(path); |
513 | 0eea575a | Panagiotis Kanavos | return (state==null)?FileStatus.Missing:state.FileStatus ; |
514 | 0eea575a | Panagiotis Kanavos | } |
515 | 0eea575a | Panagiotis Kanavos | |
516 | 0eea575a | Panagiotis Kanavos | public void ClearFileStatus(string path) |
517 | 0eea575a | Panagiotis Kanavos | { |
518 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
519 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
520 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
521 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
522 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
523 | cfed7823 | Panagiotis Kanavos | |
524 | 0eea575a | Panagiotis Kanavos | //TODO:SHOULDN'T need both clear file status and remove overlay status |
525 | cfed7823 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
526 | cfed7823 | Panagiotis Kanavos | { |
527 | cfed7823 | Panagiotis Kanavos | using (new SessionScope()) |
528 | cfed7823 | Panagiotis Kanavos | { |
529 | cfed7823 | Panagiotis Kanavos | FileState.DeleteByFilePath(path); |
530 | cfed7823 | Panagiotis Kanavos | } |
531 | cfed7823 | Panagiotis Kanavos | }); |
532 | 0eea575a | Panagiotis Kanavos | } |
533 | 0eea575a | Panagiotis Kanavos | |
534 | 0eea575a | Panagiotis Kanavos | public void UpdateFileChecksum(string path, string checksum) |
535 | cfed7823 | Panagiotis Kanavos | { |
536 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
537 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
538 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
539 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
540 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
541 | cfed7823 | Panagiotis Kanavos | |
542 | cfed7823 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
543 | 0050438e | Panagiotis Kanavos | { |
544 | 5ce54458 | Panagiotis Kanavos | using (new SessionScope()) |
545 | 5ce54458 | Panagiotis Kanavos | { |
546 | bfc13ed8 | Panagiotis Kanavos | var state = FileState.FindByFilePath(path); |
547 | 5ce54458 | Panagiotis Kanavos | if (state == null) |
548 | 5ce54458 | Panagiotis Kanavos | { |
549 | 5ce54458 | Panagiotis Kanavos | Trace.TraceWarning("[NOFILE] Unable to set checkesum for {0}.", path); |
550 | 5ce54458 | Panagiotis Kanavos | return; |
551 | 5ce54458 | Panagiotis Kanavos | } |
552 | 5ce54458 | Panagiotis Kanavos | state.Checksum = checksum; |
553 | 5ce54458 | Panagiotis Kanavos | state.Update(); |
554 | 5ce54458 | Panagiotis Kanavos | } |
555 | 5ce54458 | Panagiotis Kanavos | }); |
556 | 0eea575a | Panagiotis Kanavos | } |
557 | 283809f3 | Panagiotis Kanavos | |
558 | 283809f3 | Panagiotis Kanavos | } |
559 | 5ce54458 | Panagiotis Kanavos | |
560 | 5ce54458 | Panagiotis Kanavos | |
561 | 0eea575a | Panagiotis Kanavos | } |