root / trunk / Pithos.Core / Agents / StatusAgent.cs @ dccd340f
History | View | Annotate | Download (33.6 kB)
1 | 255f5f86 | Panagiotis Kanavos | #region |
---|---|---|---|
2 | 255f5f86 | Panagiotis Kanavos | /* ----------------------------------------------------------------------- |
3 | 255f5f86 | Panagiotis Kanavos | * <copyright file="StatusAgent.cs" company="GRNet"> |
4 | 255f5f86 | Panagiotis Kanavos | * |
5 | 255f5f86 | Panagiotis Kanavos | * Copyright 2011-2012 GRNET S.A. All rights reserved. |
6 | 255f5f86 | Panagiotis Kanavos | * |
7 | 255f5f86 | Panagiotis Kanavos | * Redistribution and use in source and binary forms, with or |
8 | 255f5f86 | Panagiotis Kanavos | * without modification, are permitted provided that the following |
9 | 255f5f86 | Panagiotis Kanavos | * conditions are met: |
10 | 255f5f86 | Panagiotis Kanavos | * |
11 | 255f5f86 | Panagiotis Kanavos | * 1. Redistributions of source code must retain the above |
12 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
13 | 255f5f86 | Panagiotis Kanavos | * disclaimer. |
14 | 255f5f86 | Panagiotis Kanavos | * |
15 | 255f5f86 | Panagiotis Kanavos | * 2. Redistributions in binary form must reproduce the above |
16 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
17 | 255f5f86 | Panagiotis Kanavos | * disclaimer in the documentation and/or other materials |
18 | 255f5f86 | Panagiotis Kanavos | * provided with the distribution. |
19 | 255f5f86 | Panagiotis Kanavos | * |
20 | 255f5f86 | Panagiotis Kanavos | * |
21 | 255f5f86 | Panagiotis Kanavos | * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
22 | 255f5f86 | Panagiotis Kanavos | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 | 255f5f86 | Panagiotis Kanavos | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 | 255f5f86 | Panagiotis Kanavos | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
25 | 255f5f86 | Panagiotis Kanavos | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | 255f5f86 | Panagiotis Kanavos | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | 255f5f86 | Panagiotis Kanavos | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 | 255f5f86 | Panagiotis Kanavos | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
29 | 255f5f86 | Panagiotis Kanavos | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | 255f5f86 | Panagiotis Kanavos | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
31 | 255f5f86 | Panagiotis Kanavos | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | 255f5f86 | Panagiotis Kanavos | * POSSIBILITY OF SUCH DAMAGE. |
33 | 255f5f86 | Panagiotis Kanavos | * |
34 | 255f5f86 | Panagiotis Kanavos | * The views and conclusions contained in the software and |
35 | 255f5f86 | Panagiotis Kanavos | * documentation are those of the authors and should not be |
36 | 255f5f86 | Panagiotis Kanavos | * interpreted as representing official policies, either expressed |
37 | 255f5f86 | Panagiotis Kanavos | * or implied, of GRNET S.A. |
38 | 255f5f86 | Panagiotis Kanavos | * </copyright> |
39 | 255f5f86 | Panagiotis Kanavos | * ----------------------------------------------------------------------- |
40 | 255f5f86 | Panagiotis Kanavos | */ |
41 | 255f5f86 | Panagiotis Kanavos | #endregion |
42 | 0eea575a | Panagiotis Kanavos | using System; |
43 | 0eea575a | Panagiotis Kanavos | using System.Collections.Generic; |
44 | 0eea575a | Panagiotis Kanavos | using System.ComponentModel.Composition; |
45 | a0dcfcc9 | Panagiotis Kanavos | using System.Data.SQLite; |
46 | 0eea575a | Panagiotis Kanavos | using System.Diagnostics; |
47 | 0eea575a | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
48 | 0eea575a | Panagiotis Kanavos | using System.IO; |
49 | 0eea575a | Panagiotis Kanavos | using System.Linq; |
50 | db8a9589 | Panagiotis Kanavos | using System.Reflection; |
51 | 174bbb6e | Panagiotis Kanavos | using System.Security.Cryptography; |
52 | 540b8cf8 | Panagiotis Kanavos | using System.Text; |
53 | 0eea575a | Panagiotis Kanavos | using System.Threading; |
54 | 0eea575a | Panagiotis Kanavos | using System.Threading.Tasks; |
55 | 0eea575a | Panagiotis Kanavos | using Castle.ActiveRecord; |
56 | 174bbb6e | Panagiotis Kanavos | using Castle.ActiveRecord.Framework; |
57 | 0eea575a | Panagiotis Kanavos | using Castle.ActiveRecord.Framework.Config; |
58 | 6f03d6e1 | Panagiotis Kanavos | using NHibernate.ByteCode.Castle; |
59 | 6f03d6e1 | Panagiotis Kanavos | using NHibernate.Cfg; |
60 | 6f03d6e1 | Panagiotis Kanavos | using NHibernate.Cfg.Loquacious; |
61 | 6f03d6e1 | Panagiotis Kanavos | using NHibernate.Dialect; |
62 | 0eea575a | Panagiotis Kanavos | using Pithos.Interfaces; |
63 | 77e10b4f | Panagiotis Kanavos | using Pithos.Network; |
64 | cfed7823 | Panagiotis Kanavos | using log4net; |
65 | 6f03d6e1 | Panagiotis Kanavos | using Environment = System.Environment; |
66 | 0eea575a | Panagiotis Kanavos | |
67 | cfed7823 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
68 | 0eea575a | Panagiotis Kanavos | { |
69 | 0eea575a | Panagiotis Kanavos | [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))] |
70 | cfed7823 | Panagiotis Kanavos | public class StatusAgent:IStatusChecker,IStatusKeeper |
71 | 0eea575a | Panagiotis Kanavos | { |
72 | db8a9589 | Panagiotis Kanavos | private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
73 | db8a9589 | Panagiotis Kanavos | |
74 | 0eea575a | Panagiotis Kanavos | [System.ComponentModel.Composition.Import] |
75 | 0eea575a | Panagiotis Kanavos | public IPithosSettings Settings { get; set; } |
76 | 0eea575a | Panagiotis Kanavos | |
77 | 4ec636f6 | Panagiotis Kanavos | private Agent<Action> _persistenceAgent; |
78 | 0eea575a | Panagiotis Kanavos | |
79 | cfed7823 | Panagiotis Kanavos | |
80 | cfed7823 | Panagiotis Kanavos | |
81 | cfed7823 | Panagiotis Kanavos | public StatusAgent() |
82 | 3c43ec9b | Panagiotis Kanavos | { |
83 | 3c43ec9b | Panagiotis Kanavos | var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); |
84 | 3c43ec9b | Panagiotis Kanavos | |
85 | 618015f4 | Panagiotis Kanavos | _pithosDataPath = Path.Combine(appDataPath , "GRNET"); |
86 | 9c4346c9 | Panagiotis Kanavos | if (!Directory.Exists(_pithosDataPath)) |
87 | 9c4346c9 | Panagiotis Kanavos | Directory.CreateDirectory(_pithosDataPath); |
88 | 618015f4 | Panagiotis Kanavos | |
89 | 618015f4 | Panagiotis Kanavos | var dbPath = Path.Combine(_pithosDataPath, "pithos.db"); |
90 | 618015f4 | Panagiotis Kanavos | |
91 | 618015f4 | Panagiotis Kanavos | MigrateOldDb(dbPath, appDataPath); |
92 | 618015f4 | Panagiotis Kanavos | |
93 | 6f03d6e1 | Panagiotis Kanavos | |
94 | 9c4346c9 | Panagiotis Kanavos | var source = GetConfiguration(_pithosDataPath); |
95 | 9c4346c9 | Panagiotis Kanavos | ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag)); |
96 | 6f03d6e1 | Panagiotis Kanavos | |
97 | cfed7823 | Panagiotis Kanavos | ActiveRecordStarter.UpdateSchema(); |
98 | 9c4346c9 | Panagiotis Kanavos | |
99 | 618015f4 | Panagiotis Kanavos | |
100 | 618015f4 | Panagiotis Kanavos | if (!File.Exists(dbPath)) |
101 | 0eea575a | Panagiotis Kanavos | ActiveRecordStarter.CreateSchema(); |
102 | 9c4346c9 | Panagiotis Kanavos | |
103 | 540b8cf8 | Panagiotis Kanavos | CreateTrigger(); |
104 | 025046f1 | Panagiotis Kanavos | |
105 | 540b8cf8 | Panagiotis Kanavos | } |
106 | 540b8cf8 | Panagiotis Kanavos | |
107 | 618015f4 | Panagiotis Kanavos | |
108 | 618015f4 | Panagiotis Kanavos | private static void MigrateOldDb(string dbPath, string appDataPath) |
109 | 618015f4 | Panagiotis Kanavos | { |
110 | 618015f4 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(dbPath)); |
111 | 618015f4 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(appDataPath)); |
112 | 618015f4 | Panagiotis Kanavos | |
113 | 618015f4 | Panagiotis Kanavos | var oldDbPath = Path.Combine(appDataPath, "Pithos", "pithos.db"); |
114 | 618015f4 | Panagiotis Kanavos | var oldDbInfo = new FileInfo(oldDbPath); |
115 | 618015f4 | Panagiotis Kanavos | if (oldDbInfo.Exists && !File.Exists(dbPath)) |
116 | 618015f4 | Panagiotis Kanavos | { |
117 | 618015f4 | Panagiotis Kanavos | var oldDirectory = oldDbInfo.Directory; |
118 | 618015f4 | Panagiotis Kanavos | oldDbInfo.MoveTo(dbPath); |
119 | 618015f4 | Panagiotis Kanavos | oldDirectory.Delete(true); |
120 | 618015f4 | Panagiotis Kanavos | } |
121 | 618015f4 | Panagiotis Kanavos | } |
122 | 618015f4 | Panagiotis Kanavos | |
123 | 540b8cf8 | Panagiotis Kanavos | private void CreateTrigger() |
124 | 540b8cf8 | Panagiotis Kanavos | { |
125 | 540b8cf8 | Panagiotis Kanavos | using (var connection = GetConnection()) |
126 | 540b8cf8 | Panagiotis Kanavos | using (var triggerCommand = connection.CreateCommand()) |
127 | 540b8cf8 | Panagiotis Kanavos | { |
128 | 540b8cf8 | Panagiotis Kanavos | var cmdText = new StringBuilder() |
129 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("CREATE TRIGGER IF NOT EXISTS update_last_modified UPDATE ON FileState FOR EACH ROW") |
130 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("BEGIN") |
131 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("UPDATE FileState SET Modified=datetime('now') WHERE Id=old.Id;") |
132 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("END;") |
133 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("CREATE TRIGGER IF NOT EXISTS insert_last_modified INSERT ON FileState FOR EACH ROW") |
134 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("BEGIN") |
135 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("UPDATE FileState SET Modified=datetime('now') WHERE Id=new.Id;") |
136 | 540b8cf8 | Panagiotis Kanavos | .AppendLine("END;") |
137 | 540b8cf8 | Panagiotis Kanavos | .ToString(); |
138 | 540b8cf8 | Panagiotis Kanavos | triggerCommand.CommandText = cmdText; |
139 | 540b8cf8 | Panagiotis Kanavos | triggerCommand.ExecuteNonQuery(); |
140 | 540b8cf8 | Panagiotis Kanavos | } |
141 | 540b8cf8 | Panagiotis Kanavos | } |
142 | 039a89e5 | Panagiotis Kanavos | |
143 | 039a89e5 | Panagiotis Kanavos | |
144 | 3c43ec9b | Panagiotis Kanavos | private static InPlaceConfigurationSource GetConfiguration(string pithosDbPath) |
145 | 3c43ec9b | Panagiotis Kanavos | { |
146 | 9c4346c9 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(pithosDbPath)) |
147 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentNullException("pithosDbPath"); |
148 | 9c4346c9 | Panagiotis Kanavos | if (!Path.IsPathRooted(pithosDbPath)) |
149 | 9c4346c9 | Panagiotis Kanavos | throw new ArgumentException("path must be a rooted path", "pithosDbPath"); |
150 | 9c4346c9 | Panagiotis Kanavos | Contract.EndContractBlock(); |
151 | 9c4346c9 | Panagiotis Kanavos | |
152 | 3c43ec9b | Panagiotis Kanavos | var properties = new Dictionary<string, string> |
153 | 3c43ec9b | Panagiotis Kanavos | { |
154 | 3c43ec9b | Panagiotis Kanavos | {"connection.driver_class", "NHibernate.Driver.SQLite20Driver"}, |
155 | 3c43ec9b | Panagiotis Kanavos | {"dialect", "NHibernate.Dialect.SQLiteDialect"}, |
156 | 3c43ec9b | Panagiotis Kanavos | {"connection.provider", "NHibernate.Connection.DriverConnectionProvider"}, |
157 | 3c43ec9b | Panagiotis Kanavos | { |
158 | 3c43ec9b | Panagiotis Kanavos | "proxyfactory.factory_class", |
159 | 3c43ec9b | Panagiotis Kanavos | "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" |
160 | 3c43ec9b | Panagiotis Kanavos | }, |
161 | 3c43ec9b | Panagiotis Kanavos | }; |
162 | 3c43ec9b | Panagiotis Kanavos | |
163 | e81dd1f6 | Panagiotis Kanavos | var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3;Enlist=N", pithosDbPath); |
164 | 3c43ec9b | Panagiotis Kanavos | properties.Add("connection.connection_string", connectionString); |
165 | 3c43ec9b | Panagiotis Kanavos | |
166 | 5120f3cb | Panagiotis Kanavos | var source = new InPlaceConfigurationSource(); |
167 | 3c43ec9b | Panagiotis Kanavos | source.Add(typeof (ActiveRecordBase), properties); |
168 | 5120f3cb | Panagiotis Kanavos | source.SetDebugFlag(false); |
169 | 3c43ec9b | Panagiotis Kanavos | return source; |
170 | 3c43ec9b | Panagiotis Kanavos | } |
171 | 3c43ec9b | Panagiotis Kanavos | |
172 | 3c43ec9b | Panagiotis Kanavos | public void StartProcessing(CancellationToken token) |
173 | 3c43ec9b | Panagiotis Kanavos | { |
174 | 4ec636f6 | Panagiotis Kanavos | _persistenceAgent = Agent<Action>.Start(queue => |
175 | 9c4346c9 | Panagiotis Kanavos | { |
176 | 4ec636f6 | Panagiotis Kanavos | Action loop = null; |
177 | 4ec636f6 | Panagiotis Kanavos | loop = () => |
178 | 4ec636f6 | Panagiotis Kanavos | { |
179 | 4ec636f6 | Panagiotis Kanavos | var job = queue.Receive(); |
180 | 4ec636f6 | Panagiotis Kanavos | job.ContinueWith(t => |
181 | 5e31048f | Panagiotis Kanavos | { |
182 | 4ec636f6 | Panagiotis Kanavos | var action = job.Result; |
183 | 4ec636f6 | Panagiotis Kanavos | try |
184 | 4ec636f6 | Panagiotis Kanavos | { |
185 | 4ec636f6 | Panagiotis Kanavos | action(); |
186 | 4ec636f6 | Panagiotis Kanavos | } |
187 | a0dcfcc9 | Panagiotis Kanavos | catch (SQLiteException ex) |
188 | a0dcfcc9 | Panagiotis Kanavos | { |
189 | a0dcfcc9 | Panagiotis Kanavos | Log.ErrorFormat("[ERROR] SQL \n{0}", ex); |
190 | a0dcfcc9 | Panagiotis Kanavos | } |
191 | 4ec636f6 | Panagiotis Kanavos | catch (Exception ex) |
192 | 4ec636f6 | Panagiotis Kanavos | { |
193 | a0dcfcc9 | Panagiotis Kanavos | Log.ErrorFormat("[ERROR] STATE \n{0}", ex); |
194 | 4ec636f6 | Panagiotis Kanavos | } |
195 | 174bbb6e | Panagiotis Kanavos | queue.NotifyComplete(action); |
196 | a0dcfcc9 | Panagiotis Kanavos | // ReSharper disable AccessToModifiedClosure |
197 | 4ec636f6 | Panagiotis Kanavos | queue.DoAsync(loop); |
198 | a0dcfcc9 | Panagiotis Kanavos | // ReSharper restore AccessToModifiedClosure |
199 | 4ec636f6 | Panagiotis Kanavos | }); |
200 | 4ec636f6 | Panagiotis Kanavos | }; |
201 | 4ec636f6 | Panagiotis Kanavos | loop(); |
202 | 9c4346c9 | Panagiotis Kanavos | }); |
203 | d15e99b4 | Panagiotis Kanavos | |
204 | 0eea575a | Panagiotis Kanavos | } |
205 | 0eea575a | Panagiotis Kanavos | |
206 | d15e99b4 | Panagiotis Kanavos | |
207 | 0eea575a | Panagiotis Kanavos | |
208 | 0eea575a | Panagiotis Kanavos | public void Stop() |
209 | 0eea575a | Panagiotis Kanavos | { |
210 | 4ec636f6 | Panagiotis Kanavos | _persistenceAgent.Stop(); |
211 | 0eea575a | Panagiotis Kanavos | } |
212 | 174bbb6e | Panagiotis Kanavos | |
213 | 0eea575a | Panagiotis Kanavos | |
214 | 0af3141d | Panagiotis Kanavos | public void ProcessExistingFiles(IEnumerable<FileInfo> existingFiles) |
215 | 9c4346c9 | Panagiotis Kanavos | { |
216 | 0af3141d | Panagiotis Kanavos | if(existingFiles ==null) |
217 | 0af3141d | Panagiotis Kanavos | throw new ArgumentNullException("existingFiles"); |
218 | 0af3141d | Panagiotis Kanavos | Contract.EndContractBlock(); |
219 | 9c4346c9 | Panagiotis Kanavos | |
220 | 0af3141d | Panagiotis Kanavos | //Find new or matching files with a left join to the stored states |
221 | 0af3141d | Panagiotis Kanavos | var fileStates = FileState.Queryable; |
222 | 0af3141d | Panagiotis Kanavos | var currentFiles=from file in existingFiles |
223 | 0af3141d | Panagiotis Kanavos | join state in fileStates on file.FullName.ToLower() equals state.FilePath.ToLower() into gs |
224 | 0af3141d | Panagiotis Kanavos | from substate in gs.DefaultIfEmpty() |
225 | 0af3141d | Panagiotis Kanavos | select new {File = file, State = substate}; |
226 | 0af3141d | Panagiotis Kanavos | |
227 | 0af3141d | Panagiotis Kanavos | //To get the deleted files we must get the states that have no corresponding |
228 | 0af3141d | Panagiotis Kanavos | //files. |
229 | 0af3141d | Panagiotis Kanavos | //We can't use the File.Exists method inside a query, so we get all file paths from the states |
230 | 0af3141d | Panagiotis Kanavos | var statePaths = (from state in fileStates |
231 | 0af3141d | Panagiotis Kanavos | select new {state.Id, state.FilePath}).ToList(); |
232 | 0af3141d | Panagiotis Kanavos | //and check each one |
233 | 0af3141d | Panagiotis Kanavos | var missingStates= (from path in statePaths |
234 | 4ec636f6 | Panagiotis Kanavos | where !File.Exists(path.FilePath) && !Directory.Exists(path.FilePath) |
235 | 0af3141d | Panagiotis Kanavos | select path.Id).ToList(); |
236 | 0af3141d | Panagiotis Kanavos | //Finally, retrieve the states that correspond to the deleted files |
237 | 0af3141d | Panagiotis Kanavos | var deletedFiles = from state in fileStates |
238 | 0af3141d | Panagiotis Kanavos | where missingStates.Contains(state.Id) |
239 | 0af3141d | Panagiotis Kanavos | select new { File = default(FileInfo), State = state }; |
240 | 0af3141d | Panagiotis Kanavos | |
241 | 174bbb6e | Panagiotis Kanavos | var pairs = currentFiles.Union(deletedFiles).ToList(); |
242 | 0af3141d | Panagiotis Kanavos | |
243 | 174bbb6e | Panagiotis Kanavos | using (var shortHasher = HashAlgorithm.Create("sha1")) |
244 | 0eea575a | Panagiotis Kanavos | { |
245 | 174bbb6e | Panagiotis Kanavos | foreach (var pair in pairs) |
246 | 0af3141d | Panagiotis Kanavos | { |
247 | 174bbb6e | Panagiotis Kanavos | var fileState = pair.State; |
248 | 174bbb6e | Panagiotis Kanavos | var file = pair.File; |
249 | 174bbb6e | Panagiotis Kanavos | if (fileState == null) |
250 | 9c4346c9 | Panagiotis Kanavos | { |
251 | 174bbb6e | Panagiotis Kanavos | //This is a new file |
252 | 174bbb6e | Panagiotis Kanavos | var createState = FileState.CreateFor(file); |
253 | 174bbb6e | Panagiotis Kanavos | _persistenceAgent.Post(createState.Create); |
254 | 174bbb6e | Panagiotis Kanavos | } |
255 | 174bbb6e | Panagiotis Kanavos | else if (file == null) |
256 | 174bbb6e | Panagiotis Kanavos | { |
257 | 174bbb6e | Panagiotis Kanavos | //This file was deleted while we were down. We should mark it as deleted |
258 | 174bbb6e | Panagiotis Kanavos | //We have to go through UpdateStatus here because the state object we are using |
259 | 174bbb6e | Panagiotis Kanavos | //was created by a different ORM session. |
260 | 174bbb6e | Panagiotis Kanavos | _persistenceAgent.Post(() => UpdateStatusDirect(fileState.Id, FileStatus.Deleted)); |
261 | 174bbb6e | Panagiotis Kanavos | } |
262 | 174bbb6e | Panagiotis Kanavos | else |
263 | 174bbb6e | Panagiotis Kanavos | { |
264 | 174bbb6e | Panagiotis Kanavos | //This file has a matching state. Need to check for possible changes |
265 | 174bbb6e | Panagiotis Kanavos | //To check for changes, we use the cheap (in CPU terms) SHA1 algorithm |
266 | 174bbb6e | Panagiotis Kanavos | //on the entire file. |
267 | 174bbb6e | Panagiotis Kanavos | |
268 | 174bbb6e | Panagiotis Kanavos | var hashString = file.ComputeShortHash(shortHasher); |
269 | 174bbb6e | Panagiotis Kanavos | //TODO: Need a way to attach the hashes to the filestate so we don't |
270 | 174bbb6e | Panagiotis Kanavos | //recalculate them each time a call to calculate has is made |
271 | 174bbb6e | Panagiotis Kanavos | //We can either store them to the filestate or add them to a |
272 | 174bbb6e | Panagiotis Kanavos | //dictionary |
273 | 174bbb6e | Panagiotis Kanavos | |
274 | 174bbb6e | Panagiotis Kanavos | //If the hashes don't match the file was changed |
275 | 174bbb6e | Panagiotis Kanavos | if (fileState.ShortHash != hashString) |
276 | 174bbb6e | Panagiotis Kanavos | { |
277 | 174bbb6e | Panagiotis Kanavos | _persistenceAgent.Post(() => UpdateStatusDirect(fileState.Id, FileStatus.Modified)); |
278 | 174bbb6e | Panagiotis Kanavos | } |
279 | 174bbb6e | Panagiotis Kanavos | } |
280 | 0af3141d | Panagiotis Kanavos | } |
281 | 174bbb6e | Panagiotis Kanavos | } |
282 | 174bbb6e | Panagiotis Kanavos | |
283 | 0af3141d | Panagiotis Kanavos | |
284 | 0eea575a | Panagiotis Kanavos | } |
285 | 174bbb6e | Panagiotis Kanavos | |
286 | 174bbb6e | Panagiotis Kanavos | |
287 | 0eea575a | Panagiotis Kanavos | |
288 | e81dd1f6 | Panagiotis Kanavos | private int UpdateStatusDirect(Guid id, FileStatus status) |
289 | e81dd1f6 | Panagiotis Kanavos | { |
290 | 039a89e5 | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect")) |
291 | e81dd1f6 | Panagiotis Kanavos | { |
292 | e81dd1f6 | Panagiotis Kanavos | |
293 | 039a89e5 | Panagiotis Kanavos | try |
294 | e81dd1f6 | Panagiotis Kanavos | { |
295 | 1b4a7550 | Panagiotis Kanavos | |
296 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
297 | 039a89e5 | Panagiotis Kanavos | using ( |
298 | 039a89e5 | Panagiotis Kanavos | var command = new SQLiteCommand("update FileState set FileStatus= :fileStatus where Id = :id ", |
299 | 039a89e5 | Panagiotis Kanavos | connection)) |
300 | 039a89e5 | Panagiotis Kanavos | { |
301 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("fileStatus", status); |
302 | 039a89e5 | Panagiotis Kanavos | |
303 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("id", id); |
304 | 039a89e5 | Panagiotis Kanavos | |
305 | 039a89e5 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
306 | 039a89e5 | Panagiotis Kanavos | |
307 | 039a89e5 | Panagiotis Kanavos | return affected; |
308 | 039a89e5 | Panagiotis Kanavos | } |
309 | e81dd1f6 | Panagiotis Kanavos | |
310 | 039a89e5 | Panagiotis Kanavos | } |
311 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
312 | 039a89e5 | Panagiotis Kanavos | { |
313 | 039a89e5 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
314 | 039a89e5 | Panagiotis Kanavos | throw; |
315 | e81dd1f6 | Panagiotis Kanavos | } |
316 | e81dd1f6 | Panagiotis Kanavos | } |
317 | e81dd1f6 | Panagiotis Kanavos | } |
318 | e81dd1f6 | Panagiotis Kanavos | |
319 | e81dd1f6 | Panagiotis Kanavos | private int UpdateStatusDirect(string path, FileStatus status) |
320 | e81dd1f6 | Panagiotis Kanavos | { |
321 | 039a89e5 | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect")) |
322 | e81dd1f6 | Panagiotis Kanavos | { |
323 | e81dd1f6 | Panagiotis Kanavos | |
324 | 039a89e5 | Panagiotis Kanavos | try |
325 | e81dd1f6 | Panagiotis Kanavos | { |
326 | 039a89e5 | Panagiotis Kanavos | |
327 | 1b4a7550 | Panagiotis Kanavos | |
328 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
329 | 039a89e5 | Panagiotis Kanavos | using ( |
330 | 039a89e5 | Panagiotis Kanavos | var command = |
331 | 3c76f045 | Panagiotis Kanavos | new SQLiteCommand("update FileState set FileStatus= :fileStatus where FilePath = :path COLLATE NOCASE", |
332 | 039a89e5 | Panagiotis Kanavos | connection)) |
333 | 039a89e5 | Panagiotis Kanavos | { |
334 | e81dd1f6 | Panagiotis Kanavos | |
335 | e81dd1f6 | Panagiotis Kanavos | |
336 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("fileStatus", status); |
337 | 039a89e5 | Panagiotis Kanavos | |
338 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", path); |
339 | 039a89e5 | Panagiotis Kanavos | |
340 | 039a89e5 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
341 | 039a89e5 | Panagiotis Kanavos | return affected; |
342 | 039a89e5 | Panagiotis Kanavos | } |
343 | 039a89e5 | Panagiotis Kanavos | } |
344 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
345 | 039a89e5 | Panagiotis Kanavos | { |
346 | 039a89e5 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
347 | 039a89e5 | Panagiotis Kanavos | throw; |
348 | e81dd1f6 | Panagiotis Kanavos | } |
349 | e81dd1f6 | Panagiotis Kanavos | } |
350 | e81dd1f6 | Panagiotis Kanavos | } |
351 | e81dd1f6 | Panagiotis Kanavos | |
352 | e81dd1f6 | Panagiotis Kanavos | private int UpdateStatusDirect(string absolutePath, FileStatus fileStatus, FileOverlayStatus overlayStatus) |
353 | e81dd1f6 | Panagiotis Kanavos | { |
354 | 039a89e5 | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect")) |
355 | e81dd1f6 | Panagiotis Kanavos | { |
356 | e81dd1f6 | Panagiotis Kanavos | |
357 | 039a89e5 | Panagiotis Kanavos | try |
358 | e81dd1f6 | Panagiotis Kanavos | { |
359 | 039a89e5 | Panagiotis Kanavos | |
360 | 1b4a7550 | Panagiotis Kanavos | |
361 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
362 | 039a89e5 | Panagiotis Kanavos | using ( |
363 | 039a89e5 | Panagiotis Kanavos | var command = |
364 | 039a89e5 | Panagiotis Kanavos | new SQLiteCommand( |
365 | 3c76f045 | Panagiotis Kanavos | "update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path COLLATE NOCASE ", |
366 | 039a89e5 | Panagiotis Kanavos | connection)) |
367 | 039a89e5 | Panagiotis Kanavos | { |
368 | 039a89e5 | Panagiotis Kanavos | |
369 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", absolutePath); |
370 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("fileStatus", fileStatus); |
371 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("overlayStatus", overlayStatus); |
372 | 039a89e5 | Panagiotis Kanavos | |
373 | 039a89e5 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
374 | 039a89e5 | Panagiotis Kanavos | return affected; |
375 | 039a89e5 | Panagiotis Kanavos | } |
376 | 039a89e5 | Panagiotis Kanavos | } |
377 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
378 | 039a89e5 | Panagiotis Kanavos | { |
379 | 039a89e5 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
380 | 039a89e5 | Panagiotis Kanavos | throw; |
381 | e81dd1f6 | Panagiotis Kanavos | } |
382 | e81dd1f6 | Panagiotis Kanavos | } |
383 | e81dd1f6 | Panagiotis Kanavos | } |
384 | e81dd1f6 | Panagiotis Kanavos | |
385 | 0af3141d | Panagiotis Kanavos | |
386 | 0eea575a | Panagiotis Kanavos | |
387 | 9c4346c9 | Panagiotis Kanavos | public string BlockHash { get; set; } |
388 | 9c4346c9 | Panagiotis Kanavos | |
389 | 9c4346c9 | Panagiotis Kanavos | public int BlockSize { get; set; } |
390 | 5120f3cb | Panagiotis Kanavos | public void ChangeRoots(string oldPath, string newPath) |
391 | 5120f3cb | Panagiotis Kanavos | { |
392 | 5120f3cb | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(oldPath)) |
393 | 5120f3cb | Panagiotis Kanavos | throw new ArgumentNullException("oldPath"); |
394 | 5120f3cb | Panagiotis Kanavos | if (!Path.IsPathRooted(oldPath)) |
395 | 5120f3cb | Panagiotis Kanavos | throw new ArgumentException("oldPath must be an absolute path", "oldPath"); |
396 | 5120f3cb | Panagiotis Kanavos | if (string.IsNullOrWhiteSpace(newPath)) |
397 | 5120f3cb | Panagiotis Kanavos | throw new ArgumentNullException("newPath"); |
398 | 5120f3cb | Panagiotis Kanavos | if (!Path.IsPathRooted(newPath)) |
399 | 5120f3cb | Panagiotis Kanavos | throw new ArgumentException("newPath must be an absolute path", "newPath"); |
400 | 5120f3cb | Panagiotis Kanavos | Contract.EndContractBlock(); |
401 | 5120f3cb | Panagiotis Kanavos | |
402 | 5120f3cb | Panagiotis Kanavos | FileState.ChangeRootPath(oldPath,newPath); |
403 | 5120f3cb | Panagiotis Kanavos | |
404 | 5120f3cb | Panagiotis Kanavos | } |
405 | 9c4346c9 | Panagiotis Kanavos | |
406 | 0eea575a | Panagiotis Kanavos | |
407 | 283809f3 | Panagiotis Kanavos | |
408 | a0dcfcc9 | Panagiotis Kanavos | private readonly string _pithosDataPath; |
409 | 283809f3 | Panagiotis Kanavos | |
410 | 283809f3 | Panagiotis Kanavos | |
411 | 039a89e5 | Panagiotis Kanavos | public FileState GetStateByFilePath(string path) |
412 | 039a89e5 | Panagiotis Kanavos | { |
413 | 039a89e5 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
414 | 039a89e5 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
415 | 039a89e5 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
416 | 039a89e5 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
417 | 039a89e5 | Panagiotis Kanavos | Contract.EndContractBlock(); |
418 | 039a89e5 | Panagiotis Kanavos | |
419 | 039a89e5 | Panagiotis Kanavos | try |
420 | 039a89e5 | Panagiotis Kanavos | { |
421 | 039a89e5 | Panagiotis Kanavos | |
422 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
423 | 174bbb6e | Panagiotis Kanavos | using (var command = new SQLiteCommand("select Id, FilePath, OverlayStatus,FileStatus ,Checksum ,ShortHash,Version ,VersionTimeStamp,IsShared ,SharedBy ,ShareWrite from FileState where FilePath=:path COLLATE NOCASE", connection)) |
424 | 039a89e5 | Panagiotis Kanavos | { |
425 | 039a89e5 | Panagiotis Kanavos | |
426 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", path); |
427 | 039a89e5 | Panagiotis Kanavos | |
428 | 039a89e5 | Panagiotis Kanavos | using (var reader = command.ExecuteReader()) |
429 | 039a89e5 | Panagiotis Kanavos | { |
430 | 039a89e5 | Panagiotis Kanavos | if (reader.Read()) |
431 | 039a89e5 | Panagiotis Kanavos | { |
432 | 039a89e5 | Panagiotis Kanavos | //var values = new object[reader.FieldCount]; |
433 | 039a89e5 | Panagiotis Kanavos | //reader.GetValues(values); |
434 | 039a89e5 | Panagiotis Kanavos | var state = new FileState |
435 | 039a89e5 | Panagiotis Kanavos | { |
436 | 039a89e5 | Panagiotis Kanavos | Id = reader.GetGuid(0), |
437 | 039a89e5 | Panagiotis Kanavos | FilePath = reader.IsDBNull(1)?"":reader.GetString(1), |
438 | 039a89e5 | Panagiotis Kanavos | OverlayStatus =reader.IsDBNull(2)?FileOverlayStatus.Unversioned: (FileOverlayStatus) reader.GetInt64(2), |
439 | 039a89e5 | Panagiotis Kanavos | FileStatus = reader.IsDBNull(3)?FileStatus.Missing:(FileStatus) reader.GetInt64(3), |
440 | 039a89e5 | Panagiotis Kanavos | Checksum = reader.IsDBNull(4)?"":reader.GetString(4), |
441 | 174bbb6e | Panagiotis Kanavos | ShortHash= reader.IsDBNull(5)?"":reader.GetString(5), |
442 | 174bbb6e | Panagiotis Kanavos | Version = reader.IsDBNull(6)?default(long):reader.GetInt64(6), |
443 | 174bbb6e | Panagiotis Kanavos | VersionTimeStamp = reader.IsDBNull(7)?default(DateTime):reader.GetDateTime(7), |
444 | 174bbb6e | Panagiotis Kanavos | IsShared = !reader.IsDBNull(8) && reader.GetBoolean(8), |
445 | 174bbb6e | Panagiotis Kanavos | SharedBy = reader.IsDBNull(9)?"":reader.GetString(9), |
446 | 174bbb6e | Panagiotis Kanavos | ShareWrite = !reader.IsDBNull(10) && reader.GetBoolean(10) |
447 | 039a89e5 | Panagiotis Kanavos | }; |
448 | 039a89e5 | Panagiotis Kanavos | /* |
449 | 039a89e5 | Panagiotis Kanavos | var state = new FileState |
450 | 039a89e5 | Panagiotis Kanavos | { |
451 | 039a89e5 | Panagiotis Kanavos | Id = (Guid) values[0], |
452 | 039a89e5 | Panagiotis Kanavos | FilePath = (string) values[1], |
453 | 039a89e5 | Panagiotis Kanavos | OverlayStatus = (FileOverlayStatus) (long)values[2], |
454 | 039a89e5 | Panagiotis Kanavos | FileStatus = (FileStatus) (long)values[3], |
455 | 039a89e5 | Panagiotis Kanavos | Checksum = (string) values[4], |
456 | 039a89e5 | Panagiotis Kanavos | Version = (long?) values[5], |
457 | 039a89e5 | Panagiotis Kanavos | VersionTimeStamp = (DateTime?) values[6], |
458 | 039a89e5 | Panagiotis Kanavos | IsShared = (long)values[7] == 1, |
459 | 039a89e5 | Panagiotis Kanavos | SharedBy = (string) values[8], |
460 | 039a89e5 | Panagiotis Kanavos | ShareWrite = (long)values[9] == 1 |
461 | 039a89e5 | Panagiotis Kanavos | }; |
462 | 039a89e5 | Panagiotis Kanavos | */ |
463 | 039a89e5 | Panagiotis Kanavos | return state; |
464 | 039a89e5 | Panagiotis Kanavos | } |
465 | 039a89e5 | Panagiotis Kanavos | else |
466 | 039a89e5 | Panagiotis Kanavos | { |
467 | 039a89e5 | Panagiotis Kanavos | return null; |
468 | 039a89e5 | Panagiotis Kanavos | } |
469 | 039a89e5 | Panagiotis Kanavos | |
470 | 039a89e5 | Panagiotis Kanavos | } |
471 | 039a89e5 | Panagiotis Kanavos | } |
472 | 039a89e5 | Panagiotis Kanavos | } |
473 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
474 | 039a89e5 | Panagiotis Kanavos | { |
475 | 039a89e5 | Panagiotis Kanavos | Log.ErrorFormat(exc.ToString()); |
476 | 039a89e5 | Panagiotis Kanavos | throw; |
477 | 039a89e5 | Panagiotis Kanavos | } |
478 | 039a89e5 | Panagiotis Kanavos | } |
479 | 039a89e5 | Panagiotis Kanavos | |
480 | 283809f3 | Panagiotis Kanavos | public FileOverlayStatus GetFileOverlayStatus(string path) |
481 | 283809f3 | Panagiotis Kanavos | { |
482 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
483 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
484 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
485 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
486 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
487 | cfed7823 | Panagiotis Kanavos | |
488 | 283809f3 | Panagiotis Kanavos | try |
489 | 283809f3 | Panagiotis Kanavos | { |
490 | 039a89e5 | Panagiotis Kanavos | |
491 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
492 | 3c76f045 | Panagiotis Kanavos | using (var command = new SQLiteCommand("select OverlayStatus from FileState where FilePath=:path COLLATE NOCASE", connection)) |
493 | e81dd1f6 | Panagiotis Kanavos | { |
494 | 1b4a7550 | Panagiotis Kanavos | |
495 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", path); |
496 | 039a89e5 | Panagiotis Kanavos | |
497 | e81dd1f6 | Panagiotis Kanavos | var s = command.ExecuteScalar(); |
498 | e81dd1f6 | Panagiotis Kanavos | return (FileOverlayStatus) Convert.ToInt32(s); |
499 | e81dd1f6 | Panagiotis Kanavos | } |
500 | 283809f3 | Panagiotis Kanavos | } |
501 | 283809f3 | Panagiotis Kanavos | catch (Exception exc) |
502 | 283809f3 | Panagiotis Kanavos | { |
503 | 5120f3cb | Panagiotis Kanavos | Log.ErrorFormat(exc.ToString()); |
504 | 283809f3 | Panagiotis Kanavos | return FileOverlayStatus.Unversioned; |
505 | 283809f3 | Panagiotis Kanavos | } |
506 | 283809f3 | Panagiotis Kanavos | } |
507 | 283809f3 | Panagiotis Kanavos | |
508 | e81dd1f6 | Panagiotis Kanavos | private string GetConnectionString() |
509 | e81dd1f6 | Panagiotis Kanavos | { |
510 | 14ecd267 | Panagiotis Kanavos | var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3;Enlist=N;Pooling=True", _pithosDataPath); |
511 | e81dd1f6 | Panagiotis Kanavos | return connectionString; |
512 | e81dd1f6 | Panagiotis Kanavos | } |
513 | e81dd1f6 | Panagiotis Kanavos | |
514 | 039a89e5 | Panagiotis Kanavos | private SQLiteConnection GetConnection() |
515 | 039a89e5 | Panagiotis Kanavos | { |
516 | 039a89e5 | Panagiotis Kanavos | var connectionString = GetConnectionString(); |
517 | 039a89e5 | Panagiotis Kanavos | var connection = new SQLiteConnection(connectionString); |
518 | 039a89e5 | Panagiotis Kanavos | connection.Open(); |
519 | 039a89e5 | Panagiotis Kanavos | using(var cmd =connection.CreateCommand()) |
520 | 039a89e5 | Panagiotis Kanavos | { |
521 | 039a89e5 | Panagiotis Kanavos | cmd.CommandText = "PRAGMA journal_mode=WAL"; |
522 | 039a89e5 | Panagiotis Kanavos | cmd.ExecuteNonQuery(); |
523 | 039a89e5 | Panagiotis Kanavos | } |
524 | 039a89e5 | Panagiotis Kanavos | return connection; |
525 | 039a89e5 | Panagiotis Kanavos | } |
526 | 039a89e5 | Panagiotis Kanavos | |
527 | 174bbb6e | Panagiotis Kanavos | /* public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus) |
528 | 0eea575a | Panagiotis Kanavos | { |
529 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
530 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
531 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
532 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted","path"); |
533 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
534 | cfed7823 | Panagiotis Kanavos | |
535 | 3c76f045 | Panagiotis Kanavos | _persistenceAgent.Post(() => FileState.StoreOverlayStatus(path,overlayStatus)); |
536 | 174bbb6e | Panagiotis Kanavos | }*/ |
537 | 174bbb6e | Panagiotis Kanavos | |
538 | 174bbb6e | Panagiotis Kanavos | public Task SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus, string shortHash = null) |
539 | 174bbb6e | Panagiotis Kanavos | { |
540 | 174bbb6e | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
541 | 174bbb6e | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
542 | 174bbb6e | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
543 | 174bbb6e | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted","path"); |
544 | 174bbb6e | Panagiotis Kanavos | Contract.EndContractBlock(); |
545 | 174bbb6e | Panagiotis Kanavos | |
546 | 174bbb6e | Panagiotis Kanavos | return _persistenceAgent.PostAndAwait(() => FileState.StoreOverlayStatus(path,overlayStatus,shortHash)); |
547 | 0eea575a | Panagiotis Kanavos | } |
548 | 0eea575a | Panagiotis Kanavos | |
549 | a0dcfcc9 | Panagiotis Kanavos | /* public void RenameFileOverlayStatus(string oldPath, string newPath) |
550 | bfc13ed8 | Panagiotis Kanavos | { |
551 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(oldPath)) |
552 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("oldPath"); |
553 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(oldPath)) |
554 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The oldPath must be rooted", "oldPath"); |
555 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(newPath)) |
556 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("newPath"); |
557 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(newPath)) |
558 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The newPath must be rooted", "newPath"); |
559 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
560 | cfed7823 | Panagiotis Kanavos | |
561 | ab2f6f79 | Panagiotis Kanavos | _persistenceAgent.Post(() =>FileState.RenameState(oldPath, newPath)); |
562 | a0dcfcc9 | Panagiotis Kanavos | }*/ |
563 | 0eea575a | Panagiotis Kanavos | |
564 | 283809f3 | Panagiotis Kanavos | public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus) |
565 | 0eea575a | Panagiotis Kanavos | { |
566 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
567 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
568 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
569 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
570 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
571 | bfc13ed8 | Panagiotis Kanavos | |
572 | ab2f6f79 | Panagiotis Kanavos | Debug.Assert(!path.Contains(FolderConstants.CacheFolder)); |
573 | ab2f6f79 | Panagiotis Kanavos | Debug.Assert(!path.EndsWith(".ignore")); |
574 | 4ec636f6 | Panagiotis Kanavos | |
575 | 3c76f045 | Panagiotis Kanavos | _persistenceAgent.Post(() => UpdateStatusDirect(path, fileStatus, overlayStatus)); |
576 | 0eea575a | Panagiotis Kanavos | } |
577 | 0eea575a | Panagiotis Kanavos | |
578 | 039a89e5 | Panagiotis Kanavos | /* |
579 | 283809f3 | Panagiotis Kanavos | public void StoreInfo(string path,ObjectInfo objectInfo) |
580 | 0eea575a | Panagiotis Kanavos | { |
581 | 283809f3 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
582 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
583 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
584 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
585 | cfed7823 | Panagiotis Kanavos | if (objectInfo == null) |
586 | 283809f3 | Panagiotis Kanavos | throw new ArgumentNullException("objectInfo", "objectInfo can't be empty"); |
587 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
588 | 5ce54458 | Panagiotis Kanavos | |
589 | 5ce54458 | Panagiotis Kanavos | _persistenceAgent.Post(() => |
590 | 3c43ec9b | Panagiotis Kanavos | { |
591 | 5ce54458 | Panagiotis Kanavos | var filePath = path.ToLower(); |
592 | 5ce54458 | Panagiotis Kanavos | //Load the existing files state and set its properties in one session |
593 | 5ce54458 | Panagiotis Kanavos | using (new SessionScope()) |
594 | 5ce54458 | Panagiotis Kanavos | { |
595 | 5ce54458 | Panagiotis Kanavos | //Forgetting to use a sessionscope results in two sessions being created, one by |
596 | 5ce54458 | Panagiotis Kanavos | //FirstOrDefault and one by Save() |
597 | bfc13ed8 | Panagiotis Kanavos | var state =FileState.FindByFilePath(filePath); |
598 | ab2f6f79 | Panagiotis Kanavos | |
599 | 5ce54458 | Panagiotis Kanavos | //Create a new empty state object if this is a new file |
600 | 5ce54458 | Panagiotis Kanavos | state = state ?? new FileState(); |
601 | 5ce54458 | Panagiotis Kanavos | |
602 | 5ce54458 | Panagiotis Kanavos | state.FilePath = filePath; |
603 | 5ce54458 | Panagiotis Kanavos | state.Checksum = objectInfo.Hash; |
604 | bfc13ed8 | Panagiotis Kanavos | state.Version = objectInfo.Version; |
605 | bfc13ed8 | Panagiotis Kanavos | state.VersionTimeStamp = objectInfo.VersionTimestamp; |
606 | bfc13ed8 | Panagiotis Kanavos | |
607 | 5ce54458 | Panagiotis Kanavos | state.FileStatus = FileStatus.Unchanged; |
608 | 5ce54458 | Panagiotis Kanavos | state.OverlayStatus = FileOverlayStatus.Normal; |
609 | bfc13ed8 | Panagiotis Kanavos | |
610 | a0dcfcc9 | Panagiotis Kanavos | |
611 | 5ce54458 | Panagiotis Kanavos | //Do the save |
612 | 5ce54458 | Panagiotis Kanavos | state.Save(); |
613 | 5ce54458 | Panagiotis Kanavos | } |
614 | 5ce54458 | Panagiotis Kanavos | }); |
615 | 5ce54458 | Panagiotis Kanavos | |
616 | 283809f3 | Panagiotis Kanavos | } |
617 | 039a89e5 | Panagiotis Kanavos | */ |
618 | 039a89e5 | Panagiotis Kanavos | |
619 | 039a89e5 | Panagiotis Kanavos | public void StoreInfo(string path, ObjectInfo objectInfo) |
620 | 1b4a7550 | Panagiotis Kanavos | { |
621 | 1b4a7550 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
622 | 1b4a7550 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
623 | 1b4a7550 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
624 | 1b4a7550 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
625 | 1b4a7550 | Panagiotis Kanavos | if (objectInfo == null) |
626 | 1b4a7550 | Panagiotis Kanavos | throw new ArgumentNullException("objectInfo", "objectInfo can't be empty"); |
627 | 1b4a7550 | Panagiotis Kanavos | Contract.EndContractBlock(); |
628 | 1b4a7550 | Panagiotis Kanavos | |
629 | 039a89e5 | Panagiotis Kanavos | _persistenceAgent.Post(() => StoreInfoDirect(path, objectInfo)); |
630 | 1b4a7550 | Panagiotis Kanavos | |
631 | 1b4a7550 | Panagiotis Kanavos | } |
632 | 1b4a7550 | Panagiotis Kanavos | |
633 | 039a89e5 | Panagiotis Kanavos | private void StoreInfoDirect(string path, ObjectInfo objectInfo) |
634 | 039a89e5 | Panagiotis Kanavos | { |
635 | 039a89e5 | Panagiotis Kanavos | try |
636 | 039a89e5 | Panagiotis Kanavos | { |
637 | 039a89e5 | Panagiotis Kanavos | |
638 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
639 | 039a89e5 | Panagiotis Kanavos | using (var command = new SQLiteCommand(connection)) |
640 | 039a89e5 | Panagiotis Kanavos | { |
641 | 039a89e5 | Panagiotis Kanavos | if (StateExists(path, connection)) |
642 | 039a89e5 | Panagiotis Kanavos | command.CommandText = |
643 | 3c76f045 | Panagiotis Kanavos | "update FileState set FileStatus= :fileStatus where FilePath = :path COLLATE NOCASE "; |
644 | 039a89e5 | Panagiotis Kanavos | else |
645 | 039a89e5 | Panagiotis Kanavos | { |
646 | 039a89e5 | Panagiotis Kanavos | command.CommandText = |
647 | 174bbb6e | Panagiotis Kanavos | "INSERT INTO FileState (Id,FilePath,Checksum,Version,VersionTimeStamp,ShortHash,FileStatus,OverlayStatus) VALUES (:id,:path,:checksum,:version,:versionTimeStamp,:shortHash,:fileStatus,:overlayStatus)"; |
648 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("id", Guid.NewGuid()); |
649 | 039a89e5 | Panagiotis Kanavos | } |
650 | 039a89e5 | Panagiotis Kanavos | |
651 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", path); |
652 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("checksum", objectInfo.Hash); |
653 | 174bbb6e | Panagiotis Kanavos | command.Parameters.AddWithValue("shortHash", ""); |
654 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("version", objectInfo.Version); |
655 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("versionTimeStamp", |
656 | 039a89e5 | Panagiotis Kanavos | objectInfo.VersionTimestamp); |
657 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("fileStatus", FileStatus.Unchanged); |
658 | 039a89e5 | Panagiotis Kanavos | command.Parameters.AddWithValue("overlayStatus", |
659 | 039a89e5 | Panagiotis Kanavos | FileOverlayStatus.Normal); |
660 | 039a89e5 | Panagiotis Kanavos | |
661 | 039a89e5 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
662 | 039a89e5 | Panagiotis Kanavos | return; |
663 | 039a89e5 | Panagiotis Kanavos | } |
664 | 039a89e5 | Panagiotis Kanavos | } |
665 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
666 | 039a89e5 | Panagiotis Kanavos | { |
667 | 039a89e5 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
668 | 039a89e5 | Panagiotis Kanavos | throw; |
669 | 039a89e5 | Panagiotis Kanavos | } |
670 | 039a89e5 | Panagiotis Kanavos | } |
671 | 039a89e5 | Panagiotis Kanavos | |
672 | 1b4a7550 | Panagiotis Kanavos | private bool StateExists(string filePath,SQLiteConnection connection) |
673 | 1b4a7550 | Panagiotis Kanavos | { |
674 | 3c76f045 | Panagiotis Kanavos | using (var command = new SQLiteCommand("Select count(*) from FileState where FilePath=:path COLLATE NOCASE", connection)) |
675 | 1b4a7550 | Panagiotis Kanavos | { |
676 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", filePath); |
677 | 039a89e5 | Panagiotis Kanavos | var result = command.ExecuteScalar(); |
678 | 039a89e5 | Panagiotis Kanavos | return ((long)result >= 1); |
679 | 039a89e5 | Panagiotis Kanavos | } |
680 | 1b4a7550 | Panagiotis Kanavos | |
681 | 1b4a7550 | Panagiotis Kanavos | } |
682 | 283809f3 | Panagiotis Kanavos | |
683 | 283809f3 | Panagiotis Kanavos | public void SetFileStatus(string path, FileStatus status) |
684 | ab2f6f79 | Panagiotis Kanavos | { |
685 | ab2f6f79 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
686 | ab2f6f79 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
687 | ab2f6f79 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
688 | ab2f6f79 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
689 | ab2f6f79 | Panagiotis Kanavos | Contract.EndContractBlock(); |
690 | e81dd1f6 | Panagiotis Kanavos | |
691 | 3c76f045 | Panagiotis Kanavos | _persistenceAgent.Post(() => UpdateStatusDirect(path, status)); |
692 | 283809f3 | Panagiotis Kanavos | } |
693 | 283809f3 | Panagiotis Kanavos | |
694 | 0eea575a | Panagiotis Kanavos | public FileStatus GetFileStatus(string path) |
695 | bfc13ed8 | Panagiotis Kanavos | { |
696 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
697 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
698 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
699 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
700 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
701 | cfed7823 | Panagiotis Kanavos | |
702 | 039a89e5 | Panagiotis Kanavos | |
703 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
704 | e81dd1f6 | Panagiotis Kanavos | { |
705 | 3c76f045 | Panagiotis Kanavos | var command = new SQLiteCommand("select FileStatus from FileState where FilePath=:path COLLATE NOCASE", connection); |
706 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", path); |
707 | 039a89e5 | Panagiotis Kanavos | |
708 | 025046f1 | Panagiotis Kanavos | var statusValue = command.ExecuteScalar(); |
709 | 025046f1 | Panagiotis Kanavos | if (statusValue==null) |
710 | 025046f1 | Panagiotis Kanavos | return FileStatus.Missing; |
711 | 025046f1 | Panagiotis Kanavos | return (FileStatus)Convert.ToInt32(statusValue); |
712 | e81dd1f6 | Panagiotis Kanavos | } |
713 | 0eea575a | Panagiotis Kanavos | } |
714 | 0eea575a | Panagiotis Kanavos | |
715 | 3c76f045 | Panagiotis Kanavos | /// <summary> |
716 | 3c76f045 | Panagiotis Kanavos | /// Deletes the status of the specified file |
717 | 3c76f045 | Panagiotis Kanavos | /// </summary> |
718 | 3c76f045 | Panagiotis Kanavos | /// <param name="path"></param> |
719 | 0eea575a | Panagiotis Kanavos | public void ClearFileStatus(string path) |
720 | 0eea575a | Panagiotis Kanavos | { |
721 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
722 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
723 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
724 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
725 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
726 | e81dd1f6 | Panagiotis Kanavos | |
727 | e81dd1f6 | Panagiotis Kanavos | _persistenceAgent.Post(() => DeleteDirect(path)); |
728 | e81dd1f6 | Panagiotis Kanavos | } |
729 | e81dd1f6 | Panagiotis Kanavos | |
730 | 3c76f045 | Panagiotis Kanavos | /// <summary> |
731 | 3c76f045 | Panagiotis Kanavos | /// Deletes the status of the specified folder and all its contents |
732 | 3c76f045 | Panagiotis Kanavos | /// </summary> |
733 | 3c76f045 | Panagiotis Kanavos | /// <param name="path"></param> |
734 | 3c76f045 | Panagiotis Kanavos | public void ClearFolderStatus(string path) |
735 | 3c76f045 | Panagiotis Kanavos | { |
736 | 3c76f045 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
737 | 3c76f045 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
738 | 3c76f045 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
739 | 3c76f045 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
740 | 3c76f045 | Panagiotis Kanavos | Contract.EndContractBlock(); |
741 | 3c76f045 | Panagiotis Kanavos | |
742 | 3c76f045 | Panagiotis Kanavos | _persistenceAgent.Post(() => DeleteFolderDirect(path)); |
743 | 3c76f045 | Panagiotis Kanavos | } |
744 | 3c76f045 | Panagiotis Kanavos | |
745 | 3c76f045 | Panagiotis Kanavos | public IEnumerable<FileState> GetChildren(FileState fileState) |
746 | 3c76f045 | Panagiotis Kanavos | { |
747 | 3c76f045 | Panagiotis Kanavos | if (fileState == null) |
748 | 3c76f045 | Panagiotis Kanavos | throw new ArgumentNullException("fileState"); |
749 | 3c76f045 | Panagiotis Kanavos | Contract.EndContractBlock(); |
750 | 3c76f045 | Panagiotis Kanavos | |
751 | 3c76f045 | Panagiotis Kanavos | var children = from state in FileState.Queryable |
752 | 3c76f045 | Panagiotis Kanavos | where state.FilePath.StartsWith(fileState.FilePath + "\\") |
753 | 3c76f045 | Panagiotis Kanavos | select state; |
754 | 3c76f045 | Panagiotis Kanavos | return children; |
755 | 3c76f045 | Panagiotis Kanavos | } |
756 | 3c76f045 | Panagiotis Kanavos | |
757 | 174bbb6e | Panagiotis Kanavos | public void EnsureFileState(string path) |
758 | 174bbb6e | Panagiotis Kanavos | { |
759 | 174bbb6e | Panagiotis Kanavos | var existingState = GetStateByFilePath(path); |
760 | 174bbb6e | Panagiotis Kanavos | if (existingState != null) |
761 | 174bbb6e | Panagiotis Kanavos | return; |
762 | 174bbb6e | Panagiotis Kanavos | var fileInfo = FileInfoExtensions.FromPath(path); |
763 | 174bbb6e | Panagiotis Kanavos | using (new SessionScope()) |
764 | 174bbb6e | Panagiotis Kanavos | { |
765 | 174bbb6e | Panagiotis Kanavos | var newState = FileState.CreateFor(fileInfo); |
766 | 174bbb6e | Panagiotis Kanavos | newState.FileStatus=FileStatus.Missing; |
767 | 174bbb6e | Panagiotis Kanavos | _persistenceAgent.PostAndAwait(newState.CreateAndFlush).Wait(); |
768 | 174bbb6e | Panagiotis Kanavos | } |
769 | 174bbb6e | Panagiotis Kanavos | |
770 | 174bbb6e | Panagiotis Kanavos | } |
771 | 174bbb6e | Panagiotis Kanavos | |
772 | e81dd1f6 | Panagiotis Kanavos | private int DeleteDirect(string filePath) |
773 | e81dd1f6 | Panagiotis Kanavos | { |
774 | 039a89e5 | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["StatusAgent"].Push("DeleteDirect")) |
775 | e81dd1f6 | Panagiotis Kanavos | { |
776 | e81dd1f6 | Panagiotis Kanavos | |
777 | 039a89e5 | Panagiotis Kanavos | try |
778 | e81dd1f6 | Panagiotis Kanavos | { |
779 | e81dd1f6 | Panagiotis Kanavos | |
780 | 039a89e5 | Panagiotis Kanavos | |
781 | 039a89e5 | Panagiotis Kanavos | using (var connection = GetConnection()) |
782 | 039a89e5 | Panagiotis Kanavos | { |
783 | 3c76f045 | Panagiotis Kanavos | var command = new SQLiteCommand("delete from FileState where FilePath = :path COLLATE NOCASE", |
784 | 3c76f045 | Panagiotis Kanavos | connection); |
785 | 3c76f045 | Panagiotis Kanavos | |
786 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", filePath); |
787 | 3c76f045 | Panagiotis Kanavos | |
788 | 3c76f045 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
789 | 3c76f045 | Panagiotis Kanavos | return affected; |
790 | 3c76f045 | Panagiotis Kanavos | } |
791 | 3c76f045 | Panagiotis Kanavos | } |
792 | 3c76f045 | Panagiotis Kanavos | catch (Exception exc) |
793 | 3c76f045 | Panagiotis Kanavos | { |
794 | 3c76f045 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
795 | 3c76f045 | Panagiotis Kanavos | throw; |
796 | 3c76f045 | Panagiotis Kanavos | } |
797 | 3c76f045 | Panagiotis Kanavos | } |
798 | 3c76f045 | Panagiotis Kanavos | } |
799 | 3c76f045 | Panagiotis Kanavos | |
800 | 3c76f045 | Panagiotis Kanavos | private int DeleteFolderDirect(string filePath) |
801 | 3c76f045 | Panagiotis Kanavos | { |
802 | 3c76f045 | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["StatusAgent"].Push("DeleteDirect")) |
803 | 3c76f045 | Panagiotis Kanavos | { |
804 | 3c76f045 | Panagiotis Kanavos | |
805 | 3c76f045 | Panagiotis Kanavos | try |
806 | 3c76f045 | Panagiotis Kanavos | { |
807 | 3c76f045 | Panagiotis Kanavos | |
808 | 3c76f045 | Panagiotis Kanavos | |
809 | 3c76f045 | Panagiotis Kanavos | using (var connection = GetConnection()) |
810 | 3c76f045 | Panagiotis Kanavos | { |
811 | fe62b7f4 | Panagiotis Kanavos | var command = new SQLiteCommand(@"delete from FileState where FilePath = :path or FilePath like :path || '\%' COLLATE NOCASE", |
812 | 039a89e5 | Panagiotis Kanavos | connection); |
813 | 039a89e5 | Panagiotis Kanavos | |
814 | 3c76f045 | Panagiotis Kanavos | command.Parameters.AddWithValue("path", filePath); |
815 | 039a89e5 | Panagiotis Kanavos | |
816 | 039a89e5 | Panagiotis Kanavos | var affected = command.ExecuteNonQuery(); |
817 | 039a89e5 | Panagiotis Kanavos | return affected; |
818 | 039a89e5 | Panagiotis Kanavos | } |
819 | 039a89e5 | Panagiotis Kanavos | } |
820 | 039a89e5 | Panagiotis Kanavos | catch (Exception exc) |
821 | 039a89e5 | Panagiotis Kanavos | { |
822 | 039a89e5 | Panagiotis Kanavos | Log.Error(exc.ToString()); |
823 | 039a89e5 | Panagiotis Kanavos | throw; |
824 | e81dd1f6 | Panagiotis Kanavos | } |
825 | e81dd1f6 | Panagiotis Kanavos | } |
826 | 0eea575a | Panagiotis Kanavos | } |
827 | 0eea575a | Panagiotis Kanavos | |
828 | 174bbb6e | Panagiotis Kanavos | public void UpdateFileChecksum(string path, string shortHash, string checksum) |
829 | cfed7823 | Panagiotis Kanavos | { |
830 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(path)) |
831 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("path"); |
832 | cfed7823 | Panagiotis Kanavos | if (!Path.IsPathRooted(path)) |
833 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The path must be rooted", "path"); |
834 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
835 | cfed7823 | Panagiotis Kanavos | |
836 | 174bbb6e | Panagiotis Kanavos | _persistenceAgent.Post(() => FileState.UpdateChecksum(path, shortHash,checksum)); |
837 | 0eea575a | Panagiotis Kanavos | } |
838 | 283809f3 | Panagiotis Kanavos | |
839 | 283809f3 | Panagiotis Kanavos | } |
840 | 5ce54458 | Panagiotis Kanavos | |
841 | 5ce54458 | Panagiotis Kanavos | |
842 | 0eea575a | Panagiotis Kanavos | } |