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