Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / StatusAgent.cs @ 025046f1

History | View | Annotate | Download (29.3 kB)

1 0eea575a Panagiotis Kanavos
using System;
2 0eea575a Panagiotis Kanavos
using System.Collections.Generic;
3 0eea575a Panagiotis Kanavos
using System.ComponentModel.Composition;
4 a0dcfcc9 Panagiotis Kanavos
using System.Data.SQLite;
5 0eea575a Panagiotis Kanavos
using System.Diagnostics;
6 0eea575a Panagiotis Kanavos
using System.Diagnostics.Contracts;
7 0eea575a Panagiotis Kanavos
using System.IO;
8 0eea575a Panagiotis Kanavos
using System.Linq;
9 540b8cf8 Panagiotis Kanavos
using System.Text;
10 0eea575a Panagiotis Kanavos
using System.Threading;
11 0eea575a Panagiotis Kanavos
using System.Threading.Tasks;
12 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord;
13 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord.Framework.Config;
14 0eea575a Panagiotis Kanavos
using Pithos.Interfaces;
15 77e10b4f Panagiotis Kanavos
using Pithos.Network;
16 cfed7823 Panagiotis Kanavos
using log4net;
17 0eea575a Panagiotis Kanavos
18 cfed7823 Panagiotis Kanavos
namespace Pithos.Core.Agents
19 0eea575a Panagiotis Kanavos
{
20 0eea575a Panagiotis Kanavos
    [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
21 cfed7823 Panagiotis Kanavos
    public class StatusAgent:IStatusChecker,IStatusKeeper
22 0eea575a Panagiotis Kanavos
    {
23 0eea575a Panagiotis Kanavos
        [System.ComponentModel.Composition.Import]
24 0eea575a Panagiotis Kanavos
        public IPithosSettings Settings { get; set; }
25 0eea575a Panagiotis Kanavos
26 4ec636f6 Panagiotis Kanavos
        private Agent<Action> _persistenceAgent;
27 0eea575a Panagiotis Kanavos
28 cfed7823 Panagiotis Kanavos
29 5120f3cb Panagiotis Kanavos
        private static readonly ILog Log = LogManager.GetLogger("StatusAgent");
30 cfed7823 Panagiotis Kanavos
31 cfed7823 Panagiotis Kanavos
        public StatusAgent()
32 3c43ec9b Panagiotis Kanavos
        {            
33 3c43ec9b Panagiotis Kanavos
            var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
34 9c4346c9 Panagiotis Kanavos
            _pithosDataPath = Path.Combine(appDataPath , "Pithos");
35 3c43ec9b Panagiotis Kanavos
36 9c4346c9 Panagiotis Kanavos
            if (!Directory.Exists(_pithosDataPath))
37 9c4346c9 Panagiotis Kanavos
                Directory.CreateDirectory(_pithosDataPath);
38 9c4346c9 Panagiotis Kanavos
            var source = GetConfiguration(_pithosDataPath);
39 9c4346c9 Panagiotis Kanavos
            ActiveRecordStarter.Initialize(source,typeof(FileState),typeof(FileTag));
40 cfed7823 Panagiotis Kanavos
            ActiveRecordStarter.UpdateSchema();
41 9c4346c9 Panagiotis Kanavos
42 9c4346c9 Panagiotis Kanavos
            if (!File.Exists(Path.Combine(_pithosDataPath ,"pithos.db")))
43 0eea575a Panagiotis Kanavos
                ActiveRecordStarter.CreateSchema();
44 9c4346c9 Panagiotis Kanavos
45 540b8cf8 Panagiotis Kanavos
            CreateTrigger();
46 025046f1 Panagiotis Kanavos
            
47 540b8cf8 Panagiotis Kanavos
        }
48 540b8cf8 Panagiotis Kanavos
49 540b8cf8 Panagiotis Kanavos
        private void CreateTrigger()
50 540b8cf8 Panagiotis Kanavos
        {
51 540b8cf8 Panagiotis Kanavos
            using (var connection = GetConnection())
52 540b8cf8 Panagiotis Kanavos
            using (var triggerCommand = connection.CreateCommand())
53 540b8cf8 Panagiotis Kanavos
            {
54 540b8cf8 Panagiotis Kanavos
                var cmdText = new StringBuilder()
55 540b8cf8 Panagiotis Kanavos
                    .AppendLine("CREATE TRIGGER IF NOT EXISTS update_last_modified UPDATE ON FileState FOR EACH ROW")
56 540b8cf8 Panagiotis Kanavos
                    .AppendLine("BEGIN")
57 540b8cf8 Panagiotis Kanavos
                    .AppendLine("UPDATE FileState SET Modified=datetime('now')  WHERE Id=old.Id;")
58 540b8cf8 Panagiotis Kanavos
                    .AppendLine("END;")
59 540b8cf8 Panagiotis Kanavos
                    .AppendLine("CREATE TRIGGER IF NOT EXISTS insert_last_modified INSERT ON FileState FOR EACH ROW")
60 540b8cf8 Panagiotis Kanavos
                    .AppendLine("BEGIN")
61 540b8cf8 Panagiotis Kanavos
                    .AppendLine("UPDATE FileState SET Modified=datetime('now')  WHERE Id=new.Id;")
62 540b8cf8 Panagiotis Kanavos
                    .AppendLine("END;")
63 540b8cf8 Panagiotis Kanavos
                    .ToString();
64 540b8cf8 Panagiotis Kanavos
                triggerCommand.CommandText = cmdText;                
65 540b8cf8 Panagiotis Kanavos
                triggerCommand.ExecuteNonQuery();
66 540b8cf8 Panagiotis Kanavos
            }
67 540b8cf8 Panagiotis Kanavos
        }
68 039a89e5 Panagiotis Kanavos
69 039a89e5 Panagiotis Kanavos
70 3c43ec9b Panagiotis Kanavos
        private static InPlaceConfigurationSource GetConfiguration(string pithosDbPath)
71 3c43ec9b Panagiotis Kanavos
        {
72 9c4346c9 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(pithosDbPath))
73 9c4346c9 Panagiotis Kanavos
                throw new ArgumentNullException("pithosDbPath");
74 9c4346c9 Panagiotis Kanavos
            if (!Path.IsPathRooted(pithosDbPath))
75 9c4346c9 Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "pithosDbPath");
76 9c4346c9 Panagiotis Kanavos
            Contract.EndContractBlock();
77 9c4346c9 Panagiotis Kanavos
78 3c43ec9b Panagiotis Kanavos
            var properties = new Dictionary<string, string>
79 3c43ec9b Panagiotis Kanavos
                                 {
80 3c43ec9b Panagiotis Kanavos
                                     {"connection.driver_class", "NHibernate.Driver.SQLite20Driver"},
81 3c43ec9b Panagiotis Kanavos
                                     {"dialect", "NHibernate.Dialect.SQLiteDialect"},
82 3c43ec9b Panagiotis Kanavos
                                     {"connection.provider", "NHibernate.Connection.DriverConnectionProvider"},
83 3c43ec9b Panagiotis Kanavos
                                     {
84 3c43ec9b Panagiotis Kanavos
                                         "proxyfactory.factory_class",
85 3c43ec9b Panagiotis Kanavos
                                         "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"
86 3c43ec9b Panagiotis Kanavos
                                         },
87 3c43ec9b Panagiotis Kanavos
                                 };
88 3c43ec9b Panagiotis Kanavos
89 e81dd1f6 Panagiotis Kanavos
            var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3;Enlist=N", pithosDbPath);
90 3c43ec9b Panagiotis Kanavos
            properties.Add("connection.connection_string", connectionString);
91 3c43ec9b Panagiotis Kanavos
92 5120f3cb Panagiotis Kanavos
            var source = new InPlaceConfigurationSource();                        
93 3c43ec9b Panagiotis Kanavos
            source.Add(typeof (ActiveRecordBase), properties);
94 5120f3cb Panagiotis Kanavos
            source.SetDebugFlag(false);            
95 3c43ec9b Panagiotis Kanavos
            return source;
96 3c43ec9b Panagiotis Kanavos
        }
97 3c43ec9b Panagiotis Kanavos
98 3c43ec9b Panagiotis Kanavos
        public void StartProcessing(CancellationToken token)
99 3c43ec9b Panagiotis Kanavos
        {
100 4ec636f6 Panagiotis Kanavos
            _persistenceAgent = Agent<Action>.Start(queue =>
101 9c4346c9 Panagiotis Kanavos
            {
102 4ec636f6 Panagiotis Kanavos
                Action loop = null;
103 4ec636f6 Panagiotis Kanavos
                loop = () =>
104 4ec636f6 Panagiotis Kanavos
                {
105 4ec636f6 Panagiotis Kanavos
                    var job = queue.Receive();
106 4ec636f6 Panagiotis Kanavos
                    job.ContinueWith(t =>
107 5e31048f Panagiotis Kanavos
                    {
108 4ec636f6 Panagiotis Kanavos
                        var action = job.Result;
109 4ec636f6 Panagiotis Kanavos
                        try
110 4ec636f6 Panagiotis Kanavos
                        {
111 4ec636f6 Panagiotis Kanavos
                            action();
112 4ec636f6 Panagiotis Kanavos
                        }
113 a0dcfcc9 Panagiotis Kanavos
                        catch (SQLiteException ex)
114 a0dcfcc9 Panagiotis Kanavos
                        {
115 a0dcfcc9 Panagiotis Kanavos
                            Log.ErrorFormat("[ERROR] SQL \n{0}", ex);
116 a0dcfcc9 Panagiotis Kanavos
                        }
117 4ec636f6 Panagiotis Kanavos
                        catch (Exception ex)
118 4ec636f6 Panagiotis Kanavos
                        {
119 a0dcfcc9 Panagiotis Kanavos
                            Log.ErrorFormat("[ERROR] STATE \n{0}", ex);
120 4ec636f6 Panagiotis Kanavos
                        }
121 a0dcfcc9 Panagiotis Kanavos
// ReSharper disable AccessToModifiedClosure
122 4ec636f6 Panagiotis Kanavos
                        queue.DoAsync(loop);
123 a0dcfcc9 Panagiotis Kanavos
// ReSharper restore AccessToModifiedClosure
124 4ec636f6 Panagiotis Kanavos
                    });
125 4ec636f6 Panagiotis Kanavos
                };
126 4ec636f6 Panagiotis Kanavos
                loop();
127 9c4346c9 Panagiotis Kanavos
            });
128 d15e99b4 Panagiotis Kanavos
            
129 0eea575a Panagiotis Kanavos
        }
130 0eea575a Panagiotis Kanavos
131 d15e99b4 Panagiotis Kanavos
       
132 0eea575a Panagiotis Kanavos
133 0eea575a Panagiotis Kanavos
        public void Stop()
134 0eea575a Panagiotis Kanavos
        {
135 4ec636f6 Panagiotis Kanavos
            _persistenceAgent.Stop();            
136 0eea575a Panagiotis Kanavos
        }
137 283809f3 Panagiotis Kanavos
       
138 0eea575a Panagiotis Kanavos
139 0af3141d Panagiotis Kanavos
        public void ProcessExistingFiles(IEnumerable<FileInfo> existingFiles)
140 9c4346c9 Panagiotis Kanavos
        {
141 0af3141d Panagiotis Kanavos
            if(existingFiles  ==null)
142 0af3141d Panagiotis Kanavos
                throw new ArgumentNullException("existingFiles");
143 0af3141d Panagiotis Kanavos
            Contract.EndContractBlock();
144 9c4346c9 Panagiotis Kanavos
            
145 0af3141d Panagiotis Kanavos
            //Find new or matching files with a left join to the stored states
146 0af3141d Panagiotis Kanavos
            var fileStates = FileState.Queryable;
147 0af3141d Panagiotis Kanavos
            var currentFiles=from file in existingFiles
148 0af3141d Panagiotis Kanavos
                      join state in fileStates on file.FullName.ToLower() equals state.FilePath.ToLower() into gs
149 0af3141d Panagiotis Kanavos
                      from substate in gs.DefaultIfEmpty()
150 0af3141d Panagiotis Kanavos
                               select new {File = file, State = substate};
151 0af3141d Panagiotis Kanavos
152 0af3141d Panagiotis Kanavos
            //To get the deleted files we must get the states that have no corresponding
153 0af3141d Panagiotis Kanavos
            //files. 
154 0af3141d Panagiotis Kanavos
            //We can't use the File.Exists method inside a query, so we get all file paths from the states
155 0af3141d Panagiotis Kanavos
            var statePaths = (from state in fileStates
156 0af3141d Panagiotis Kanavos
                             select new {state.Id, state.FilePath}).ToList();
157 0af3141d Panagiotis Kanavos
            //and check each one
158 0af3141d Panagiotis Kanavos
            var missingStates= (from path in statePaths
159 4ec636f6 Panagiotis Kanavos
                                where !File.Exists(path.FilePath) && !Directory.Exists(path.FilePath)
160 0af3141d Panagiotis Kanavos
                               select path.Id).ToList();
161 0af3141d Panagiotis Kanavos
            //Finally, retrieve the states that correspond to the deleted files            
162 0af3141d Panagiotis Kanavos
            var deletedFiles = from state in fileStates 
163 0af3141d Panagiotis Kanavos
                        where missingStates.Contains(state.Id)
164 0af3141d Panagiotis Kanavos
                        select new { File = default(FileInfo), State = state };
165 0af3141d Panagiotis Kanavos
166 0af3141d Panagiotis Kanavos
            var pairs = currentFiles.Union(deletedFiles);
167 0af3141d Panagiotis Kanavos
168 e81dd1f6 Panagiotis Kanavos
            foreach(var pair in pairs)
169 0eea575a Panagiotis Kanavos
            {
170 0af3141d Panagiotis Kanavos
                var fileState = pair.State;
171 0af3141d Panagiotis Kanavos
                var file = pair.File;
172 0af3141d Panagiotis Kanavos
                if (fileState == null)
173 0af3141d Panagiotis Kanavos
                {
174 0af3141d Panagiotis Kanavos
                    //This is a new file
175 3c76f045 Panagiotis Kanavos
                    var fullPath = pair.File.FullName;
176 a0dcfcc9 Panagiotis Kanavos
                    var createState = FileState.CreateForAsync(fullPath, BlockSize, BlockHash);
177 0af3141d Panagiotis Kanavos
                    createState.ContinueWith(state => _persistenceAgent.Post(state.Result.Create));
178 0af3141d Panagiotis Kanavos
                }                
179 0af3141d Panagiotis Kanavos
                else if (file == null)
180 0af3141d Panagiotis Kanavos
                {
181 0af3141d Panagiotis Kanavos
                    //This file was deleted while we were down. We should mark it as deleted
182 0af3141d Panagiotis Kanavos
                    //We have to go through UpdateStatus here because the state object we are using
183 0af3141d Panagiotis Kanavos
                    //was created by a different ORM session.
184 e81dd1f6 Panagiotis Kanavos
                    _persistenceAgent.Post(()=> UpdateStatusDirect(fileState.Id, FileStatus.Deleted));                    
185 0af3141d Panagiotis Kanavos
                }
186 0af3141d Panagiotis Kanavos
                else
187 0af3141d Panagiotis Kanavos
                {
188 0af3141d Panagiotis Kanavos
                    //This file has a matching state. Need to check for possible changes
189 0af3141d Panagiotis Kanavos
                    var hashString = file.CalculateHash(BlockSize,BlockHash);
190 0af3141d Panagiotis Kanavos
                    //If the hashes don't match the file was changed
191 0af3141d Panagiotis Kanavos
                    if (fileState.Checksum != hashString)
192 9c4346c9 Panagiotis Kanavos
                    {
193 e81dd1f6 Panagiotis Kanavos
                        _persistenceAgent.Post(() => UpdateStatusDirect(fileState.Id, FileStatus.Modified));
194 0af3141d Panagiotis Kanavos
                    }                    
195 0af3141d Panagiotis Kanavos
                }
196 e81dd1f6 Panagiotis Kanavos
            };            
197 0af3141d Panagiotis Kanavos
         
198 0eea575a Panagiotis Kanavos
        }
199 0eea575a Panagiotis Kanavos
200 e81dd1f6 Panagiotis Kanavos
        private int UpdateStatusDirect(Guid id, FileStatus status)
201 e81dd1f6 Panagiotis Kanavos
        {
202 039a89e5 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect"))
203 e81dd1f6 Panagiotis Kanavos
            {
204 e81dd1f6 Panagiotis Kanavos
205 039a89e5 Panagiotis Kanavos
                try
206 e81dd1f6 Panagiotis Kanavos
                {
207 1b4a7550 Panagiotis Kanavos
                    
208 039a89e5 Panagiotis Kanavos
                    using (var connection = GetConnection())
209 039a89e5 Panagiotis Kanavos
                    using (
210 039a89e5 Panagiotis Kanavos
                        var command = new SQLiteCommand("update FileState set FileStatus= :fileStatus where Id = :id  ",
211 039a89e5 Panagiotis Kanavos
                                                        connection))
212 039a89e5 Panagiotis Kanavos
                    {                                                
213 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("fileStatus", status);
214 039a89e5 Panagiotis Kanavos
215 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("id", id);
216 039a89e5 Panagiotis Kanavos
                        
217 039a89e5 Panagiotis Kanavos
                        var affected = command.ExecuteNonQuery();
218 039a89e5 Panagiotis Kanavos
                        
219 039a89e5 Panagiotis Kanavos
                        return affected;
220 039a89e5 Panagiotis Kanavos
                    }
221 e81dd1f6 Panagiotis Kanavos
222 039a89e5 Panagiotis Kanavos
                }
223 039a89e5 Panagiotis Kanavos
                catch (Exception exc)
224 039a89e5 Panagiotis Kanavos
                {
225 039a89e5 Panagiotis Kanavos
                    Log.Error(exc.ToString());
226 039a89e5 Panagiotis Kanavos
                    throw;
227 e81dd1f6 Panagiotis Kanavos
                }
228 e81dd1f6 Panagiotis Kanavos
            }
229 e81dd1f6 Panagiotis Kanavos
        }
230 e81dd1f6 Panagiotis Kanavos
        
231 e81dd1f6 Panagiotis Kanavos
        private int UpdateStatusDirect(string path, FileStatus status)
232 e81dd1f6 Panagiotis Kanavos
        {
233 039a89e5 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect"))
234 e81dd1f6 Panagiotis Kanavos
            {
235 e81dd1f6 Panagiotis Kanavos
236 039a89e5 Panagiotis Kanavos
                try
237 e81dd1f6 Panagiotis Kanavos
                {
238 039a89e5 Panagiotis Kanavos
239 1b4a7550 Panagiotis Kanavos
                    
240 039a89e5 Panagiotis Kanavos
                    using (var connection = GetConnection())
241 039a89e5 Panagiotis Kanavos
                    using (
242 039a89e5 Panagiotis Kanavos
                        var command =
243 3c76f045 Panagiotis Kanavos
                            new SQLiteCommand("update FileState set FileStatus= :fileStatus where FilePath = :path COLLATE NOCASE",
244 039a89e5 Panagiotis Kanavos
                                              connection))
245 039a89e5 Panagiotis Kanavos
                    {
246 e81dd1f6 Panagiotis Kanavos
247 e81dd1f6 Panagiotis Kanavos
248 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("fileStatus", status);
249 039a89e5 Panagiotis Kanavos
250 3c76f045 Panagiotis Kanavos
                        command.Parameters.AddWithValue("path", path);
251 039a89e5 Panagiotis Kanavos
                        
252 039a89e5 Panagiotis Kanavos
                        var affected = command.ExecuteNonQuery();
253 039a89e5 Panagiotis Kanavos
                        return affected;
254 039a89e5 Panagiotis Kanavos
                    }
255 039a89e5 Panagiotis Kanavos
                }
256 039a89e5 Panagiotis Kanavos
                catch (Exception exc)
257 039a89e5 Panagiotis Kanavos
                {
258 039a89e5 Panagiotis Kanavos
                    Log.Error(exc.ToString());
259 039a89e5 Panagiotis Kanavos
                    throw;
260 e81dd1f6 Panagiotis Kanavos
                }
261 e81dd1f6 Panagiotis Kanavos
            }
262 e81dd1f6 Panagiotis Kanavos
        }
263 e81dd1f6 Panagiotis Kanavos
264 e81dd1f6 Panagiotis Kanavos
        private int UpdateStatusDirect(string absolutePath, FileStatus fileStatus, FileOverlayStatus overlayStatus)
265 e81dd1f6 Panagiotis Kanavos
        {
266 039a89e5 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["StatusAgent"].Push("UpdateStatusDirect"))
267 e81dd1f6 Panagiotis Kanavos
            {
268 e81dd1f6 Panagiotis Kanavos
269 039a89e5 Panagiotis Kanavos
                try
270 e81dd1f6 Panagiotis Kanavos
                {
271 039a89e5 Panagiotis Kanavos
272 1b4a7550 Panagiotis Kanavos
                    
273 039a89e5 Panagiotis Kanavos
                    using (var connection = GetConnection())
274 039a89e5 Panagiotis Kanavos
                    using (
275 039a89e5 Panagiotis Kanavos
                        var command =
276 039a89e5 Panagiotis Kanavos
                            new SQLiteCommand(
277 3c76f045 Panagiotis Kanavos
                                "update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path COLLATE NOCASE ",
278 039a89e5 Panagiotis Kanavos
                                connection))
279 039a89e5 Panagiotis Kanavos
                    {
280 039a89e5 Panagiotis Kanavos
281 3c76f045 Panagiotis Kanavos
                        command.Parameters.AddWithValue("path", absolutePath);
282 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("fileStatus", fileStatus);
283 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("overlayStatus", overlayStatus);
284 039a89e5 Panagiotis Kanavos
                        
285 039a89e5 Panagiotis Kanavos
                        var affected = command.ExecuteNonQuery();
286 039a89e5 Panagiotis Kanavos
                        return affected;
287 039a89e5 Panagiotis Kanavos
                    }
288 039a89e5 Panagiotis Kanavos
                }
289 039a89e5 Panagiotis Kanavos
                catch (Exception exc)
290 039a89e5 Panagiotis Kanavos
                {
291 039a89e5 Panagiotis Kanavos
                    Log.Error(exc.ToString());
292 039a89e5 Panagiotis Kanavos
                    throw;
293 e81dd1f6 Panagiotis Kanavos
                }
294 e81dd1f6 Panagiotis Kanavos
            }
295 e81dd1f6 Panagiotis Kanavos
        }
296 e81dd1f6 Panagiotis Kanavos
        
297 0af3141d Panagiotis Kanavos
298 0eea575a Panagiotis Kanavos
299 9c4346c9 Panagiotis Kanavos
        public string BlockHash { get; set; }
300 9c4346c9 Panagiotis Kanavos
301 9c4346c9 Panagiotis Kanavos
        public int BlockSize { get; set; }
302 5120f3cb Panagiotis Kanavos
        public void ChangeRoots(string oldPath, string newPath)
303 5120f3cb Panagiotis Kanavos
        {
304 5120f3cb Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
305 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
306 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
307 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("oldPath must be an absolute path", "oldPath");
308 5120f3cb Panagiotis Kanavos
            if (string.IsNullOrWhiteSpace(newPath))
309 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
310 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
311 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("newPath must be an absolute path", "newPath");
312 5120f3cb Panagiotis Kanavos
            Contract.EndContractBlock();
313 5120f3cb Panagiotis Kanavos
314 5120f3cb Panagiotis Kanavos
            FileState.ChangeRootPath(oldPath,newPath);
315 5120f3cb Panagiotis Kanavos
316 5120f3cb Panagiotis Kanavos
        }
317 9c4346c9 Panagiotis Kanavos
318 0eea575a Panagiotis Kanavos
        private PithosStatus _pithosStatus=PithosStatus.InSynch;       
319 0eea575a Panagiotis Kanavos
320 0eea575a Panagiotis Kanavos
        public void SetPithosStatus(PithosStatus status)
321 0eea575a Panagiotis Kanavos
        {
322 0eea575a Panagiotis Kanavos
            _pithosStatus = status;
323 0eea575a Panagiotis Kanavos
        }
324 0eea575a Panagiotis Kanavos
325 0eea575a Panagiotis Kanavos
        public PithosStatus GetPithosStatus()
326 0eea575a Panagiotis Kanavos
        {
327 0eea575a Panagiotis Kanavos
            return _pithosStatus;
328 0eea575a Panagiotis Kanavos
        }
329 0eea575a Panagiotis Kanavos
330 283809f3 Panagiotis Kanavos
331 a0dcfcc9 Panagiotis Kanavos
        private readonly string _pithosDataPath;
332 283809f3 Panagiotis Kanavos
333 283809f3 Panagiotis Kanavos
334 039a89e5 Panagiotis Kanavos
        public FileState GetStateByFilePath(string path)
335 039a89e5 Panagiotis Kanavos
        {
336 039a89e5 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
337 039a89e5 Panagiotis Kanavos
                throw new ArgumentNullException("path");
338 039a89e5 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
339 039a89e5 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
340 039a89e5 Panagiotis Kanavos
            Contract.EndContractBlock();
341 039a89e5 Panagiotis Kanavos
342 039a89e5 Panagiotis Kanavos
            try
343 039a89e5 Panagiotis Kanavos
            {
344 039a89e5 Panagiotis Kanavos
                
345 039a89e5 Panagiotis Kanavos
                using (var connection = GetConnection())
346 3c76f045 Panagiotis Kanavos
                using (var command = new SQLiteCommand("select Id, FilePath, OverlayStatus,FileStatus ,Checksum   ,Version    ,VersionTimeStamp,IsShared   ,SharedBy   ,ShareWrite  from FileState where FilePath=:path COLLATE NOCASE", connection))
347 039a89e5 Panagiotis Kanavos
                {
348 039a89e5 Panagiotis Kanavos
                    
349 3c76f045 Panagiotis Kanavos
                    command.Parameters.AddWithValue("path", path);
350 039a89e5 Panagiotis Kanavos
                    
351 039a89e5 Panagiotis Kanavos
                    using (var reader = command.ExecuteReader())
352 039a89e5 Panagiotis Kanavos
                    {
353 039a89e5 Panagiotis Kanavos
                        if (reader.Read())
354 039a89e5 Panagiotis Kanavos
                        {
355 039a89e5 Panagiotis Kanavos
                            //var values = new object[reader.FieldCount];
356 039a89e5 Panagiotis Kanavos
                            //reader.GetValues(values);
357 039a89e5 Panagiotis Kanavos
                            var state = new FileState
358 039a89e5 Panagiotis Kanavos
                                            {
359 039a89e5 Panagiotis Kanavos
                                                Id = reader.GetGuid(0),
360 039a89e5 Panagiotis Kanavos
                                                FilePath = reader.IsDBNull(1)?"":reader.GetString(1),
361 039a89e5 Panagiotis Kanavos
                                                OverlayStatus =reader.IsDBNull(2)?FileOverlayStatus.Unversioned: (FileOverlayStatus) reader.GetInt64(2),
362 039a89e5 Panagiotis Kanavos
                                                FileStatus = reader.IsDBNull(3)?FileStatus.Missing:(FileStatus) reader.GetInt64(3),
363 039a89e5 Panagiotis Kanavos
                                                Checksum = reader.IsDBNull(4)?"":reader.GetString(4),
364 039a89e5 Panagiotis Kanavos
                                                Version = reader.IsDBNull(5)?default(long):reader.GetInt64(5),
365 039a89e5 Panagiotis Kanavos
                                                VersionTimeStamp = reader.IsDBNull(6)?default(DateTime):reader.GetDateTime(6),
366 039a89e5 Panagiotis Kanavos
                                                IsShared = !reader.IsDBNull(7) && reader.GetBoolean(7),
367 039a89e5 Panagiotis Kanavos
                                                SharedBy = reader.IsDBNull(8)?"":reader.GetString(8),
368 039a89e5 Panagiotis Kanavos
                                                ShareWrite = !reader.IsDBNull(9) && reader.GetBoolean(9)
369 039a89e5 Panagiotis Kanavos
                                            };
370 039a89e5 Panagiotis Kanavos
/*
371 039a89e5 Panagiotis Kanavos
                            var state = new FileState
372 039a89e5 Panagiotis Kanavos
                                            {
373 039a89e5 Panagiotis Kanavos
                                                Id = (Guid) values[0],
374 039a89e5 Panagiotis Kanavos
                                                FilePath = (string) values[1],
375 039a89e5 Panagiotis Kanavos
                                                OverlayStatus = (FileOverlayStatus) (long)values[2],
376 039a89e5 Panagiotis Kanavos
                                                FileStatus = (FileStatus) (long)values[3],
377 039a89e5 Panagiotis Kanavos
                                                Checksum = (string) values[4],
378 039a89e5 Panagiotis Kanavos
                                                Version = (long?) values[5],
379 039a89e5 Panagiotis Kanavos
                                                VersionTimeStamp = (DateTime?) values[6],
380 039a89e5 Panagiotis Kanavos
                                                IsShared = (long)values[7] == 1,
381 039a89e5 Panagiotis Kanavos
                                                SharedBy = (string) values[8],
382 039a89e5 Panagiotis Kanavos
                                                ShareWrite = (long)values[9] == 1
383 039a89e5 Panagiotis Kanavos
                                            };
384 039a89e5 Panagiotis Kanavos
*/
385 039a89e5 Panagiotis Kanavos
                            return state;
386 039a89e5 Panagiotis Kanavos
                        }
387 039a89e5 Panagiotis Kanavos
                        else
388 039a89e5 Panagiotis Kanavos
                        {
389 039a89e5 Panagiotis Kanavos
                            return null;
390 039a89e5 Panagiotis Kanavos
                        }
391 039a89e5 Panagiotis Kanavos
392 039a89e5 Panagiotis Kanavos
                    }                    
393 039a89e5 Panagiotis Kanavos
                }
394 039a89e5 Panagiotis Kanavos
            }
395 039a89e5 Panagiotis Kanavos
            catch (Exception exc)
396 039a89e5 Panagiotis Kanavos
            {
397 039a89e5 Panagiotis Kanavos
                Log.ErrorFormat(exc.ToString());
398 039a89e5 Panagiotis Kanavos
                throw;
399 039a89e5 Panagiotis Kanavos
            }            
400 039a89e5 Panagiotis Kanavos
        }
401 039a89e5 Panagiotis Kanavos
402 283809f3 Panagiotis Kanavos
        public FileOverlayStatus GetFileOverlayStatus(string path)
403 283809f3 Panagiotis Kanavos
        {
404 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
405 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
406 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
407 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
408 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
409 cfed7823 Panagiotis Kanavos
410 283809f3 Panagiotis Kanavos
            try
411 283809f3 Panagiotis Kanavos
            {
412 039a89e5 Panagiotis Kanavos
                
413 039a89e5 Panagiotis Kanavos
                using (var connection = GetConnection())
414 3c76f045 Panagiotis Kanavos
                using (var command = new SQLiteCommand("select OverlayStatus from FileState where FilePath=:path  COLLATE NOCASE", connection))
415 e81dd1f6 Panagiotis Kanavos
                {
416 1b4a7550 Panagiotis Kanavos
                    
417 3c76f045 Panagiotis Kanavos
                    command.Parameters.AddWithValue("path", path);
418 039a89e5 Panagiotis Kanavos
                    
419 e81dd1f6 Panagiotis Kanavos
                    var s = command.ExecuteScalar();
420 e81dd1f6 Panagiotis Kanavos
                    return (FileOverlayStatus) Convert.ToInt32(s);
421 e81dd1f6 Panagiotis Kanavos
                }
422 283809f3 Panagiotis Kanavos
            }
423 283809f3 Panagiotis Kanavos
            catch (Exception exc)
424 283809f3 Panagiotis Kanavos
            {
425 5120f3cb Panagiotis Kanavos
                Log.ErrorFormat(exc.ToString());
426 283809f3 Panagiotis Kanavos
                return FileOverlayStatus.Unversioned;
427 283809f3 Panagiotis Kanavos
            }
428 283809f3 Panagiotis Kanavos
        }
429 283809f3 Panagiotis Kanavos
430 e81dd1f6 Panagiotis Kanavos
        private string GetConnectionString()
431 e81dd1f6 Panagiotis Kanavos
        {
432 14ecd267 Panagiotis Kanavos
            var connectionString = String.Format(@"Data Source={0}\pithos.db;Version=3;Enlist=N;Pooling=True", _pithosDataPath);
433 e81dd1f6 Panagiotis Kanavos
            return connectionString;
434 e81dd1f6 Panagiotis Kanavos
        }
435 e81dd1f6 Panagiotis Kanavos
436 039a89e5 Panagiotis Kanavos
        private SQLiteConnection GetConnection()
437 039a89e5 Panagiotis Kanavos
        {
438 039a89e5 Panagiotis Kanavos
            var connectionString = GetConnectionString();
439 039a89e5 Panagiotis Kanavos
            var connection = new SQLiteConnection(connectionString);
440 039a89e5 Panagiotis Kanavos
            connection.Open();
441 039a89e5 Panagiotis Kanavos
            using(var cmd =connection.CreateCommand())
442 039a89e5 Panagiotis Kanavos
            {
443 039a89e5 Panagiotis Kanavos
                cmd.CommandText = "PRAGMA journal_mode=WAL";
444 039a89e5 Panagiotis Kanavos
                cmd.ExecuteNonQuery();
445 039a89e5 Panagiotis Kanavos
            }
446 039a89e5 Panagiotis Kanavos
            return connection;
447 039a89e5 Panagiotis Kanavos
        }
448 039a89e5 Panagiotis Kanavos
449 0eea575a Panagiotis Kanavos
        public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
450 0eea575a Panagiotis Kanavos
        {
451 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
452 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
453 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
454 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted","path");
455 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
456 cfed7823 Panagiotis Kanavos
457 3c76f045 Panagiotis Kanavos
            _persistenceAgent.Post(() => FileState.StoreOverlayStatus(path,overlayStatus));
458 0eea575a Panagiotis Kanavos
        }
459 0eea575a Panagiotis Kanavos
460 a0dcfcc9 Panagiotis Kanavos
       /* public void RenameFileOverlayStatus(string oldPath, string newPath)
461 bfc13ed8 Panagiotis Kanavos
        {
462 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
463 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
464 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
465 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The oldPath must be rooted", "oldPath");
466 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(newPath))
467 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
468 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
469 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The newPath must be rooted", "newPath");
470 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
471 cfed7823 Panagiotis Kanavos
472 ab2f6f79 Panagiotis Kanavos
            _persistenceAgent.Post(() =>FileState.RenameState(oldPath, newPath));
473 a0dcfcc9 Panagiotis Kanavos
        }*/
474 0eea575a Panagiotis Kanavos
475 283809f3 Panagiotis Kanavos
        public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
476 0eea575a Panagiotis Kanavos
        {
477 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
478 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
479 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
480 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
481 bfc13ed8 Panagiotis Kanavos
            Contract.EndContractBlock();
482 bfc13ed8 Panagiotis Kanavos
483 ab2f6f79 Panagiotis Kanavos
            Debug.Assert(!path.Contains(FolderConstants.CacheFolder));
484 ab2f6f79 Panagiotis Kanavos
            Debug.Assert(!path.EndsWith(".ignore"));
485 4ec636f6 Panagiotis Kanavos
486 3c76f045 Panagiotis Kanavos
            _persistenceAgent.Post(() => UpdateStatusDirect(path, fileStatus, overlayStatus));
487 0eea575a Panagiotis Kanavos
        }
488 0eea575a Panagiotis Kanavos
489 039a89e5 Panagiotis Kanavos
/*
490 283809f3 Panagiotis Kanavos
        public void StoreInfo(string path,ObjectInfo objectInfo)
491 0eea575a Panagiotis Kanavos
        {
492 283809f3 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
493 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
494 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
495 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");            
496 cfed7823 Panagiotis Kanavos
            if (objectInfo == null)
497 283809f3 Panagiotis Kanavos
                throw new ArgumentNullException("objectInfo", "objectInfo can't be empty");
498 bfc13ed8 Panagiotis Kanavos
            Contract.EndContractBlock();
499 5ce54458 Panagiotis Kanavos
500 5ce54458 Panagiotis Kanavos
            _persistenceAgent.Post(() =>
501 3c43ec9b Panagiotis Kanavos
            {
502 5ce54458 Panagiotis Kanavos
                var filePath = path.ToLower();
503 5ce54458 Panagiotis Kanavos
                //Load the existing files state and set its properties in one session            
504 5ce54458 Panagiotis Kanavos
                using (new SessionScope())
505 5ce54458 Panagiotis Kanavos
                {
506 5ce54458 Panagiotis Kanavos
                    //Forgetting to use a sessionscope results in two sessions being created, one by 
507 5ce54458 Panagiotis Kanavos
                    //FirstOrDefault and one by Save()
508 bfc13ed8 Panagiotis Kanavos
                    var state =FileState.FindByFilePath(filePath);
509 ab2f6f79 Panagiotis Kanavos
                    
510 5ce54458 Panagiotis Kanavos
                    //Create a new empty state object if this is a new file
511 5ce54458 Panagiotis Kanavos
                    state = state ?? new FileState();
512 5ce54458 Panagiotis Kanavos
513 5ce54458 Panagiotis Kanavos
                    state.FilePath = filePath;
514 5ce54458 Panagiotis Kanavos
                    state.Checksum = objectInfo.Hash;
515 bfc13ed8 Panagiotis Kanavos
                    state.Version = objectInfo.Version;
516 bfc13ed8 Panagiotis Kanavos
                    state.VersionTimeStamp = objectInfo.VersionTimestamp;
517 bfc13ed8 Panagiotis Kanavos
518 5ce54458 Panagiotis Kanavos
                    state.FileStatus = FileStatus.Unchanged;
519 5ce54458 Panagiotis Kanavos
                    state.OverlayStatus = FileOverlayStatus.Normal;
520 bfc13ed8 Panagiotis Kanavos
                    
521 a0dcfcc9 Panagiotis Kanavos
                  
522 5ce54458 Panagiotis Kanavos
                    //Do the save
523 5ce54458 Panagiotis Kanavos
                    state.Save();
524 5ce54458 Panagiotis Kanavos
                }
525 5ce54458 Panagiotis Kanavos
            });
526 5ce54458 Panagiotis Kanavos
527 283809f3 Panagiotis Kanavos
        }
528 039a89e5 Panagiotis Kanavos
*/
529 039a89e5 Panagiotis Kanavos
        
530 039a89e5 Panagiotis Kanavos
        public void StoreInfo(string path, ObjectInfo objectInfo)
531 1b4a7550 Panagiotis Kanavos
        {
532 1b4a7550 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
533 1b4a7550 Panagiotis Kanavos
                throw new ArgumentNullException("path");
534 1b4a7550 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
535 1b4a7550 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
536 1b4a7550 Panagiotis Kanavos
            if (objectInfo == null)
537 1b4a7550 Panagiotis Kanavos
                throw new ArgumentNullException("objectInfo", "objectInfo can't be empty");
538 1b4a7550 Panagiotis Kanavos
            Contract.EndContractBlock();
539 1b4a7550 Panagiotis Kanavos
540 039a89e5 Panagiotis Kanavos
            _persistenceAgent.Post(() => StoreInfoDirect(path, objectInfo));
541 1b4a7550 Panagiotis Kanavos
542 1b4a7550 Panagiotis Kanavos
        }
543 1b4a7550 Panagiotis Kanavos
544 039a89e5 Panagiotis Kanavos
        private void StoreInfoDirect(string path, ObjectInfo objectInfo)
545 039a89e5 Panagiotis Kanavos
        {
546 039a89e5 Panagiotis Kanavos
            try
547 039a89e5 Panagiotis Kanavos
            {
548 039a89e5 Panagiotis Kanavos
                
549 039a89e5 Panagiotis Kanavos
                using (var connection = GetConnection())
550 039a89e5 Panagiotis Kanavos
                using (var command = new SQLiteCommand(connection))
551 039a89e5 Panagiotis Kanavos
                {
552 039a89e5 Panagiotis Kanavos
                    if (StateExists(path, connection))
553 039a89e5 Panagiotis Kanavos
                        command.CommandText =
554 3c76f045 Panagiotis Kanavos
                            "update FileState set FileStatus= :fileStatus where FilePath = :path  COLLATE NOCASE ";
555 039a89e5 Panagiotis Kanavos
                    else
556 039a89e5 Panagiotis Kanavos
                    {
557 039a89e5 Panagiotis Kanavos
                        command.CommandText =
558 039a89e5 Panagiotis Kanavos
                            "INSERT INTO FileState (Id,FilePath,Checksum,Version,VersionTimeStamp,FileStatus,OverlayStatus) VALUES (:id,:path,:checksum,:version,:versionTimeStamp,:fileStatus,:overlayStatus)";
559 039a89e5 Panagiotis Kanavos
                        command.Parameters.AddWithValue("id", Guid.NewGuid());
560 039a89e5 Panagiotis Kanavos
                    }
561 039a89e5 Panagiotis Kanavos
562 3c76f045 Panagiotis Kanavos
                    command.Parameters.AddWithValue("path", path);
563 039a89e5 Panagiotis Kanavos
                    command.Parameters.AddWithValue("checksum", objectInfo.Hash);
564 039a89e5 Panagiotis Kanavos
                    command.Parameters.AddWithValue("version", objectInfo.Version);
565 039a89e5 Panagiotis Kanavos
                    command.Parameters.AddWithValue("versionTimeStamp",
566 039a89e5 Panagiotis Kanavos
                                                    objectInfo.VersionTimestamp);
567 039a89e5 Panagiotis Kanavos
                    command.Parameters.AddWithValue("fileStatus", FileStatus.Unchanged);
568 039a89e5 Panagiotis Kanavos
                    command.Parameters.AddWithValue("overlayStatus",
569 039a89e5 Panagiotis Kanavos
                                                    FileOverlayStatus.Normal);
570 039a89e5 Panagiotis Kanavos
571 039a89e5 Panagiotis Kanavos
                    var affected = command.ExecuteNonQuery();
572 039a89e5 Panagiotis Kanavos
                    return;
573 039a89e5 Panagiotis Kanavos
                }
574 039a89e5 Panagiotis Kanavos
            }
575 039a89e5 Panagiotis Kanavos
            catch (Exception exc)
576 039a89e5 Panagiotis Kanavos
            {
577 039a89e5 Panagiotis Kanavos
                Log.Error(exc.ToString());
578 039a89e5 Panagiotis Kanavos
                throw;
579 039a89e5 Panagiotis Kanavos
            }
580 039a89e5 Panagiotis Kanavos
        }
581 039a89e5 Panagiotis Kanavos
582 1b4a7550 Panagiotis Kanavos
        private bool StateExists(string filePath,SQLiteConnection connection)
583 1b4a7550 Panagiotis Kanavos
        {
584 3c76f045 Panagiotis Kanavos
            using (var command = new SQLiteCommand("Select count(*) from FileState where FilePath=:path  COLLATE NOCASE", connection))
585 1b4a7550 Panagiotis Kanavos
            {
586 3c76f045 Panagiotis Kanavos
                command.Parameters.AddWithValue("path", filePath);
587 039a89e5 Panagiotis Kanavos
                var result = command.ExecuteScalar();
588 039a89e5 Panagiotis Kanavos
                return ((long)result >= 1);
589 039a89e5 Panagiotis Kanavos
            }
590 1b4a7550 Panagiotis Kanavos
591 1b4a7550 Panagiotis Kanavos
        }
592 283809f3 Panagiotis Kanavos
593 283809f3 Panagiotis Kanavos
        public void SetFileStatus(string path, FileStatus status)
594 ab2f6f79 Panagiotis Kanavos
        {
595 ab2f6f79 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
596 ab2f6f79 Panagiotis Kanavos
                throw new ArgumentNullException("path");
597 ab2f6f79 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
598 ab2f6f79 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
599 ab2f6f79 Panagiotis Kanavos
            Contract.EndContractBlock();
600 e81dd1f6 Panagiotis Kanavos
            
601 3c76f045 Panagiotis Kanavos
            _persistenceAgent.Post(() => UpdateStatusDirect(path, status));
602 283809f3 Panagiotis Kanavos
        }
603 283809f3 Panagiotis Kanavos
604 0eea575a Panagiotis Kanavos
        public FileStatus GetFileStatus(string path)
605 bfc13ed8 Panagiotis Kanavos
        {
606 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
607 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
608 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
609 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
610 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
611 cfed7823 Panagiotis Kanavos
612 039a89e5 Panagiotis Kanavos
            
613 039a89e5 Panagiotis Kanavos
            using (var connection = GetConnection())
614 e81dd1f6 Panagiotis Kanavos
            {
615 3c76f045 Panagiotis Kanavos
                var command = new SQLiteCommand("select FileStatus from FileState where FilePath=:path  COLLATE NOCASE", connection);
616 3c76f045 Panagiotis Kanavos
                command.Parameters.AddWithValue("path", path);
617 039a89e5 Panagiotis Kanavos
                
618 025046f1 Panagiotis Kanavos
                var statusValue = command.ExecuteScalar();
619 025046f1 Panagiotis Kanavos
                if (statusValue==null)
620 025046f1 Panagiotis Kanavos
                    return FileStatus.Missing;
621 025046f1 Panagiotis Kanavos
                return (FileStatus)Convert.ToInt32(statusValue);
622 e81dd1f6 Panagiotis Kanavos
            }
623 0eea575a Panagiotis Kanavos
        }
624 0eea575a Panagiotis Kanavos
625 3c76f045 Panagiotis Kanavos
        /// <summary>
626 3c76f045 Panagiotis Kanavos
        /// Deletes the status of the specified file
627 3c76f045 Panagiotis Kanavos
        /// </summary>
628 3c76f045 Panagiotis Kanavos
        /// <param name="path"></param>
629 0eea575a Panagiotis Kanavos
        public void ClearFileStatus(string path)
630 0eea575a Panagiotis Kanavos
        {
631 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
632 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
633 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
634 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
635 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
636 e81dd1f6 Panagiotis Kanavos
637 e81dd1f6 Panagiotis Kanavos
            _persistenceAgent.Post(() => DeleteDirect(path));   
638 e81dd1f6 Panagiotis Kanavos
        }
639 e81dd1f6 Panagiotis Kanavos
640 3c76f045 Panagiotis Kanavos
        /// <summary>
641 3c76f045 Panagiotis Kanavos
        /// Deletes the status of the specified folder and all its contents
642 3c76f045 Panagiotis Kanavos
        /// </summary>
643 3c76f045 Panagiotis Kanavos
        /// <param name="path"></param>
644 3c76f045 Panagiotis Kanavos
        public void ClearFolderStatus(string path)
645 3c76f045 Panagiotis Kanavos
        {
646 3c76f045 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
647 3c76f045 Panagiotis Kanavos
                throw new ArgumentNullException("path");
648 3c76f045 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
649 3c76f045 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");
650 3c76f045 Panagiotis Kanavos
            Contract.EndContractBlock();
651 3c76f045 Panagiotis Kanavos
652 3c76f045 Panagiotis Kanavos
            _persistenceAgent.Post(() => DeleteFolderDirect(path));   
653 3c76f045 Panagiotis Kanavos
        }
654 3c76f045 Panagiotis Kanavos
655 3c76f045 Panagiotis Kanavos
        public IEnumerable<FileState> GetChildren(FileState fileState)
656 3c76f045 Panagiotis Kanavos
        {
657 3c76f045 Panagiotis Kanavos
            if (fileState == null)
658 3c76f045 Panagiotis Kanavos
                throw new ArgumentNullException("fileState");
659 3c76f045 Panagiotis Kanavos
            Contract.EndContractBlock();
660 3c76f045 Panagiotis Kanavos
661 3c76f045 Panagiotis Kanavos
            var children = from state in FileState.Queryable
662 3c76f045 Panagiotis Kanavos
                           where state.FilePath.StartsWith(fileState.FilePath + "\\")
663 3c76f045 Panagiotis Kanavos
                           select state;
664 3c76f045 Panagiotis Kanavos
            return children;
665 3c76f045 Panagiotis Kanavos
        }
666 3c76f045 Panagiotis Kanavos
667 e81dd1f6 Panagiotis Kanavos
        private int DeleteDirect(string filePath)
668 e81dd1f6 Panagiotis Kanavos
        {
669 039a89e5 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["StatusAgent"].Push("DeleteDirect"))
670 e81dd1f6 Panagiotis Kanavos
            {
671 e81dd1f6 Panagiotis Kanavos
672 039a89e5 Panagiotis Kanavos
                try
673 e81dd1f6 Panagiotis Kanavos
                {
674 e81dd1f6 Panagiotis Kanavos
675 039a89e5 Panagiotis Kanavos
                    
676 039a89e5 Panagiotis Kanavos
                    using (var connection = GetConnection())
677 039a89e5 Panagiotis Kanavos
                    {
678 3c76f045 Panagiotis Kanavos
                        var command = new SQLiteCommand("delete from FileState where FilePath = :path  COLLATE NOCASE",
679 3c76f045 Panagiotis Kanavos
                                                        connection);
680 3c76f045 Panagiotis Kanavos
681 3c76f045 Panagiotis Kanavos
                        command.Parameters.AddWithValue("path", filePath);
682 3c76f045 Panagiotis Kanavos
                        
683 3c76f045 Panagiotis Kanavos
                        var affected = command.ExecuteNonQuery();
684 3c76f045 Panagiotis Kanavos
                        return affected;
685 3c76f045 Panagiotis Kanavos
                    }
686 3c76f045 Panagiotis Kanavos
                }
687 3c76f045 Panagiotis Kanavos
                catch (Exception exc)
688 3c76f045 Panagiotis Kanavos
                {
689 3c76f045 Panagiotis Kanavos
                    Log.Error(exc.ToString());
690 3c76f045 Panagiotis Kanavos
                    throw;
691 3c76f045 Panagiotis Kanavos
                }
692 3c76f045 Panagiotis Kanavos
            }
693 3c76f045 Panagiotis Kanavos
        }
694 3c76f045 Panagiotis Kanavos
695 3c76f045 Panagiotis Kanavos
        private int DeleteFolderDirect(string filePath)
696 3c76f045 Panagiotis Kanavos
        {
697 3c76f045 Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["StatusAgent"].Push("DeleteDirect"))
698 3c76f045 Panagiotis Kanavos
            {
699 3c76f045 Panagiotis Kanavos
700 3c76f045 Panagiotis Kanavos
                try
701 3c76f045 Panagiotis Kanavos
                {
702 3c76f045 Panagiotis Kanavos
703 3c76f045 Panagiotis Kanavos
                    
704 3c76f045 Panagiotis Kanavos
                    using (var connection = GetConnection())
705 3c76f045 Panagiotis Kanavos
                    {
706 3c76f045 Panagiotis Kanavos
                        var command = new SQLiteCommand("delete from FileState where FilePath = :path or FilePath like :path + '/%'  COLLATE NOCASE",
707 039a89e5 Panagiotis Kanavos
                                                        connection);
708 039a89e5 Panagiotis Kanavos
709 3c76f045 Panagiotis Kanavos
                        command.Parameters.AddWithValue("path", filePath);
710 039a89e5 Panagiotis Kanavos
                        
711 039a89e5 Panagiotis Kanavos
                        var affected = command.ExecuteNonQuery();
712 039a89e5 Panagiotis Kanavos
                        return affected;
713 039a89e5 Panagiotis Kanavos
                    }
714 039a89e5 Panagiotis Kanavos
                }
715 039a89e5 Panagiotis Kanavos
                catch (Exception exc)
716 039a89e5 Panagiotis Kanavos
                {
717 039a89e5 Panagiotis Kanavos
                    Log.Error(exc.ToString());
718 039a89e5 Panagiotis Kanavos
                    throw;
719 e81dd1f6 Panagiotis Kanavos
                }
720 e81dd1f6 Panagiotis Kanavos
            }
721 0eea575a Panagiotis Kanavos
        }
722 0eea575a Panagiotis Kanavos
723 0eea575a Panagiotis Kanavos
        public void UpdateFileChecksum(string path, string checksum)
724 cfed7823 Panagiotis Kanavos
        {
725 cfed7823 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
726 cfed7823 Panagiotis Kanavos
                throw new ArgumentNullException("path");
727 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
728 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("The path must be rooted", "path");            
729 cfed7823 Panagiotis Kanavos
            Contract.EndContractBlock();
730 cfed7823 Panagiotis Kanavos
731 3c76f045 Panagiotis Kanavos
            _persistenceAgent.Post(() => FileState.UpdateChecksum(path, checksum));
732 0eea575a Panagiotis Kanavos
        }
733 283809f3 Panagiotis Kanavos
734 283809f3 Panagiotis Kanavos
    }
735 5ce54458 Panagiotis Kanavos
736 5ce54458 Panagiotis Kanavos
   
737 0eea575a Panagiotis Kanavos
}