Replaced object load and update with direct HQL execution to resolve database locks...
authorPanagiotis Kanavos <pkanavos@gmail.com>
Thu, 5 Jan 2012 18:08:09 +0000 (20:08 +0200)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Thu, 5 Jan 2012 18:08:09 +0000 (20:08 +0200)
Removed dead code in StatusAgent.cs

trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/NetworkAgent.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Core/FileState.cs
trunk/Pithos.Core/IStatusKeeper.cs
trunk/Pithos.Core/NativeMethods.cs
trunk/Pithos.Interfaces/ObjectInfo.cs
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.sln

index fc5637f..761199c 100644 (file)
@@ -114,15 +114,6 @@ namespace Pithos.Core.Agents
             return CompletedTask<object>.Default;
         }
 
-
-/*
-        private Task Process(Task<WorkflowState> action)
-        {
-            return action.ContinueWith(t => Process(t.Result));
-        }
-*/
-
-
         public bool Pause
         {
             get { return _watcher == null || !_watcher.EnableRaisingEvents; }
@@ -214,8 +205,9 @@ namespace Pithos.Core.Agents
             //Ignore events that affect the cache folder
             var filePath = e.FullPath;
             if (Ignore(filePath)) 
-                return;           
-            
+                return;
+            if (Directory.Exists(filePath))
+                return;            
             _agent.Post(new WorkflowState{AccountInfo=AccountInfo, Path = filePath, FileName = e.Name, TriggeringChange = e.ChangeType });
         }
 
index 6c1284e..a6ebcb7 100644 (file)
@@ -95,7 +95,7 @@ namespace Pithos.Core.Agents
                             break;
                         case CloudActionType.DownloadUnconditional:
 
-                            await DownloadCloudFile(accountInfo,  cloudFile,downloadPath);
+                            await DownloadCloudFile(accountInfo, cloudFile, downloadPath);
                             break;
                         case CloudActionType.DeleteCloud:
                             DeleteCloudFile(accountInfo, cloudFile);
@@ -107,7 +107,7 @@ namespace Pithos.Core.Agents
                         case CloudActionType.MustSynch:
 
                             if (!File.Exists(downloadPath))
-                            {                                
+                            {
                                 await DownloadCloudFile(accountInfo, cloudFile, downloadPath);
                             }
                             else
@@ -119,6 +119,10 @@ namespace Pithos.Core.Agents
                     Log.InfoFormat("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile,
                                            action.CloudFile.Name);
                 }
+                catch (WebException exc)
+                {
+                    Log.ErrorFormat("[WEB ERROR] {0} : {1} -> {2} due to exception\r\n{3}", action.Action, action.LocalFile, action.CloudFile, exc);                    
+                }
                 catch (OperationCanceledException)
                 {
                     throw;
@@ -345,7 +349,7 @@ namespace Pithos.Core.Agents
                     if (task.IsFaulted)
                     {
                         //ListObjects failed at this point, need to reschedule
-                        Log.ErrorFormat("[FAIL] ListObjects for{0} in ProcessRemoteFiles with {0}", accountInfo.UserName,task.Exception);
+                        Log.ErrorFormat("[FAIL] ListObjects for{0} in ProcessRemoteFiles with {1}", accountInfo.UserName,task.Exception);
                         return;
                     }
                     using (log4net.ThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
@@ -364,7 +368,7 @@ namespace Pithos.Core.Agents
                         //Items with the same name, hash may be both in the container and the trash
                         //Don't delete items that exist in the container
                         var realTrash = from trash in trashObjects
-                                        where !remoteObjects.Any(info => info.Hash == trash.Hash)
+                                        where !remoteObjects.Any(info => info.Name == trash.Name &&  info.Hash == trash.Hash)
                                         select trash;
                         ProcessDeletedFiles(accountInfo,realTrash);                        
 
index a85be0b..de7af7b 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
+using System.Data.SQLite;
 using System.Diagnostics;
 using System.Diagnostics.Contracts;
 using System.IO;
@@ -12,9 +13,6 @@ using Castle.ActiveRecord.Framework.Config;
 using Pithos.Interfaces;
 using Pithos.Network;
 using log4net;
-using log4net.Appender;
-using log4net.Config;
-using log4net.Layout;
 
 namespace Pithos.Core.Agents
 {
@@ -87,11 +85,17 @@ namespace Pithos.Core.Agents
                         {
                             action();
                         }
+                        catch (SQLiteException ex)
+                        {
+                            Log.ErrorFormat("[ERROR] SQL \n{0}", ex);
+                        }
                         catch (Exception ex)
                         {
-                            Log.ErrorFormat("[ERROR] STATE \n{0}",ex);
+                            Log.ErrorFormat("[ERROR] STATE \n{0}", ex);
                         }
+// ReSharper disable AccessToModifiedClosure
                         queue.DoAsync(loop);
+// ReSharper restore AccessToModifiedClosure
                     });
                 };
                 loop();
@@ -144,7 +148,7 @@ namespace Pithos.Core.Agents
                 {
                     //This is a new file
                     var fullPath = pair.File.FullName.ToLower();
-                    var createState = FileState.CreateForAsync(fullPath, this.BlockSize, this.BlockHash);
+                    var createState = FileState.CreateForAsync(fullPath, BlockSize, BlockHash);
                     createState.ContinueWith(state => _persistenceAgent.Post(state.Result.Create));
                 }                
                 else if (file == null)
@@ -152,7 +156,7 @@ namespace Pithos.Core.Agents
                     //This file was deleted while we were down. We should mark it as deleted
                     //We have to go through UpdateStatus here because the state object we are using
                     //was created by a different ORM session.
-                    UpdateStatus(fileState.Id,state=> state.FileStatus = FileStatus.Deleted);                    
+                    FileState.UpdateStatus(fileState.Id,FileStatus.Deleted);                    
                 }
                 else
                 {
@@ -161,7 +165,7 @@ namespace Pithos.Core.Agents
                     //If the hashes don't match the file was changed
                     if (fileState.Checksum != hashString)
                     {
-                        UpdateStatus(fileState.Id, state => state.FileStatus = FileStatus.Modified);
+                        FileState.UpdateStatus(fileState.Id, FileStatus.Modified);
                     }                    
                 }
             });            
@@ -203,137 +207,8 @@ namespace Pithos.Core.Agents
         }
 
 
-        private string _pithosDataPath;
-
-        public T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue )
-        {
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path");
-            if (!Path.IsPathRooted(path))
-                throw new ArgumentException("path must be a rooted path", "path");
-            if (getter == null)
-                throw new ArgumentNullException("getter");
-            Contract.EndContractBlock();
-
-
-            try
-            {                
-                var state = FileState.FindByFilePath(path);
-                return state == null ? defaultValue : getter(state);
-            }
-            catch (Exception exc)
-            {
-                Log.ErrorFormat(exc.ToString());
-                return defaultValue;
-            }
-        }
-
-        /// <summary>
-        /// Sets the status of a file, creating a new FileState entry if one doesn't already exist.
-        /// </summary>
-        /// <param name="path"></param>
-        /// <param name="setter"></param>
-        public void SetStatus(string path,Action<FileState> setter)
-        {
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path", "path can't be empty");
-            if (setter==null)
-                throw new ArgumentNullException("setter", "setter can't be empty");
-            Contract.EndContractBlock();
+        private readonly string _pithosDataPath;
 
-            _persistenceAgent.Post(() =>
-            {
-                using (new SessionScope())
-                {
-                    var filePath = path.ToLower();
-                    var state = FileState.FindByFilePath(filePath);
-                    if (state != null)
-                    {
-                        setter(state);
-                        state.Save();
-                    }
-                    else
-                    {
-                        state = new FileState {FilePath = filePath,Id=Guid.NewGuid()};
-                        setter(state);
-                        state.Save();
-                    }                    
-                }
-            });
-        }
-
-        /// <summary>
-        /// Sets the status of a file only if the file already exists
-        /// </summary>
-        /// <param name="path"></param>
-        /// <param name="setter"></param>
-        private void UpdateStatus(string path, Action<FileState> setter)
-        {
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path");
-            if (!Path.IsPathRooted(path))
-                throw new ArgumentException("The path must be rooted", "path");
-            if (setter == null)
-                throw new ArgumentNullException("setter");
-            Contract.EndContractBlock();
-
-            Debug.Assert(!path.Contains(FolderConstants.CacheFolder));
-            Debug.Assert(!path.EndsWith(".ignore"));
-
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path", "path can't be empty");
-
-            if (setter == null)
-                throw new ArgumentNullException("setter", "setter can't be empty");
-
-            _persistenceAgent.Post(() =>
-            {
-                using (new SessionScope())
-                {
-                    var filePath = path.ToLower();
-
-                    var state = FileState.FindByFilePath(filePath);
-                    if (state == null)
-                    {
-                        Log.WarnFormat("[NOFILE] Unable to set status for {0}.", filePath);
-                        state = new FileState { FilePath = path, Id = Guid.NewGuid() };
-                        state.Create();                        
-                    }
-                    setter(state);
-                    state.Save();
-                }
-                
-            });
-        }
-        
-        /// <summary>
-        /// Sets the status of a specific state
-        /// </summary>
-        /// <param name="path"></param>
-        /// <param name="setter"></param>
-        private void UpdateStatus(Guid stateID, Action<FileState> setter)
-        {
-            if (setter == null)
-                throw new ArgumentNullException("setter");
-            Contract.EndContractBlock();
-
-
-            _persistenceAgent.Post(() =>
-            {
-                using (new SessionScope())
-                {
-                    var state = FileState.Find(stateID);
-                    if (state == null)
-                    {
-                        Log.WarnFormat("[NOFILE] Unable to set status for {0}.", stateID);
-                        return;
-                    }
-                    setter(state);
-                    state.Save();
-                }
-                
-            });
-        }
 
         public FileOverlayStatus GetFileOverlayStatus(string path)
         {
@@ -346,11 +221,10 @@ namespace Pithos.Core.Agents
             try
             {
 
-                //var state = FileState.FindByFilePath(path);
-                var st=from state in FileState.Queryable
-                       where state.FilePath == path.ToLower()
-                       select state.OverlayStatus; ;                
-                return st.FirstOrDefault(); // state == null ? FileOverlayStatus.Unversioned : state.OverlayStatus;
+                var status = from state in  FileState.Queryable 
+                                 where state.FilePath ==path.ToLower()
+                                 select state.OverlayStatus;
+                return status.Any()? status.First():FileOverlayStatus.Unversioned;
             }
             catch (Exception exc)
             {
@@ -367,49 +241,10 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The path must be rooted","path");
             Contract.EndContractBlock();
 
-            SetStatus(path.ToLower(),s=>s.OverlayStatus=overlayStatus);
-        }
-
-        /*public void RemoveFileOverlayStatus(string path)
-        {
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path");
-            if (!Path.IsPathRooted(path))
-                throw new ArgumentException("The path must be rooted", "path");
-            Contract.EndContractBlock();
-
-            _persistenceAgent.Post(() =>
-                InnerRemoveFileOverlayStatus(path));
-        }
-
-        private static void InnerRemoveFileOverlayStatus(string path)
-        {
-            if (String.IsNullOrWhiteSpace(path))
-                throw new ArgumentNullException("path");
-            if (!Path.IsPathRooted(path))
-                throw new ArgumentException("The path must be rooted", "path");
-            Contract.EndContractBlock();
-
-            FileState.DeleteByFilePath(path);            
-        }*/
-
-        public void RenameFileOverlayStatus(string oldPath, string newPath)
-        {
-            if (String.IsNullOrWhiteSpace(oldPath))
-                throw new ArgumentNullException("oldPath");
-            if (!Path.IsPathRooted(oldPath))
-                throw new ArgumentException("The oldPath must be rooted", "oldPath");
-            if (String.IsNullOrWhiteSpace(newPath))
-                throw new ArgumentNullException("newPath");
-            if (!Path.IsPathRooted(newPath))
-                throw new ArgumentException("The newPath must be rooted", "newPath");
-            Contract.EndContractBlock();
-
-            _persistenceAgent.Post(() =>
-                InnerRenameFileOverlayStatus(oldPath, newPath));
+            _persistenceAgent.Post(() => FileState.StoreOverlayStatus(path.ToLower(),overlayStatus));
         }
 
-        private static void InnerRenameFileOverlayStatus(string oldPath, string newPath)
+       /* public void RenameFileOverlayStatus(string oldPath, string newPath)
         {
             if (String.IsNullOrWhiteSpace(oldPath))
                 throw new ArgumentNullException("oldPath");
@@ -421,17 +256,8 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The newPath must be rooted", "newPath");
             Contract.EndContractBlock();
 
-            var state = FileState.FindByFilePath(oldPath);
-
-            if (state == null)
-            {
-                Log.WarnFormat("[NOFILE] Unable to set status for {0}.", oldPath);
-                return;
-            }
-            //NOTE: This will cause problems if path is used as a key in relationships
-            state.FilePath = newPath;
-            state.Update();
-        }
+            _persistenceAgent.Post(() =>FileState.RenameState(oldPath, newPath));
+        }*/
 
         public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
         {
@@ -441,13 +267,10 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The path must be rooted", "path");
             Contract.EndContractBlock();
 
-            checked HERE to fix conflicts
+            Debug.Assert(!path.Contains(FolderConstants.CacheFolder));
+            Debug.Assert(!path.EndsWith(".ignore"));
 
-            UpdateStatus(path.ToLower(),state=>
-                                  {
-                                      state.FileStatus = fileStatus;
-                                      state.OverlayStatus = overlayStatus;
-                                  });            
+            _persistenceAgent.Post(() => FileState.UpdateStatus(path.ToLower(), fileStatus, overlayStatus));
         }
 
         public void StoreInfo(string path,ObjectInfo objectInfo)
@@ -469,6 +292,7 @@ namespace Pithos.Core.Agents
                     //Forgetting to use a sessionscope results in two sessions being created, one by 
                     //FirstOrDefault and one by Save()
                     var state =FileState.FindByFilePath(filePath);
+                    
                     //Create a new empty state object if this is a new file
                     state = state ?? new FileState();
 
@@ -480,18 +304,7 @@ namespace Pithos.Core.Agents
                     state.FileStatus = FileStatus.Unchanged;
                     state.OverlayStatus = FileOverlayStatus.Normal;
                     
-                    //Create a list of tags from the ObjectInfo's tag dictionary
-                    //Make sure to bind each tag to its parent state so we don't have to save each tag separately
-                    //state.Tags = (from pair in objectInfo.Tags
-                    //                select
-                    //                    new FileTag
-                    //                        {
-                    //                            FileState = state,
-                    //                            Name = pair.Key,
-                    //                            Value = pair.Value
-                    //                        }
-                    //            ).ToList();
-
+                  
                     //Do the save
                     state.Save();
                 }
@@ -501,8 +314,14 @@ namespace Pithos.Core.Agents
 
         
         public void SetFileStatus(string path, FileStatus status)
-        {            
-            UpdateStatus(path.ToLower(), state=>state.FileStatus = status);
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("path");
+            if (!Path.IsPathRooted(path))
+                throw new ArgumentException("The path must be rooted", "path");
+            Contract.EndContractBlock();
+
+            _persistenceAgent.Post(() => FileState.UpdateStatus(path.ToLower(), status));
         }
 
         public FileStatus GetFileStatus(string path)
@@ -513,8 +332,10 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The path must be rooted", "path");
             Contract.EndContractBlock();
 
-            var state = FileState.FindByFilePath(path);
-            return (state==null)?FileStatus.Missing:state.FileStatus ;
+            var status = from r in FileState.Queryable
+                     where r.FilePath == path.ToLower()
+                     select r.FileStatus;                        
+            return status.Any()?status.First(): FileStatus.Missing;
         }
 
         public void ClearFileStatus(string path)
@@ -524,15 +345,8 @@ namespace Pithos.Core.Agents
             if (!Path.IsPathRooted(path))
                 throw new ArgumentException("The path must be rooted", "path");
             Contract.EndContractBlock();
-
-            //TODO:SHOULDN'T need both clear file status and remove overlay status
-            _persistenceAgent.Post(() =>
-            {
-                using (new SessionScope())
-                {
-                    FileState.DeleteByFilePath(path);
-                }
-            });   
+            
+            _persistenceAgent.Post(() => FileState.DeleteByFilePath(path));   
         }
 
         public void UpdateFileChecksum(string path, string checksum)
@@ -543,20 +357,7 @@ namespace Pithos.Core.Agents
                 throw new ArgumentException("The path must be rooted", "path");            
             Contract.EndContractBlock();
 
-            _persistenceAgent.Post(() =>
-            {
-                using (new SessionScope())
-                {
-                    var state = FileState.FindByFilePath(path);
-                    if (state == null)
-                    {
-                        Log.WarnFormat("[NOFILE] Unable to set checkesum for {0}.", path);
-                        return;
-                    }
-                    state.Checksum = checksum;
-                    state.Update();
-                }
-            });
+            _persistenceAgent.Post(() => FileState.UpdateChecksum(path.ToLower(), checksum));
         }
 
     }
index bc412b1..f288591 100644 (file)
@@ -48,48 +48,59 @@ namespace Pithos.Core.Agents
             var accountInfo = state.AccountInfo;
             using (log4net.ThreadContext.Stacks["Workflow"].Push("Process"))
             {
-                if (Log.IsDebugEnabled) Log.DebugFormat("State {0} {1} {2}", state.FileName,state.Status,state.TriggeringChange);
-
-                if (state.Skip)
+                try
                 {
-                    if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}",state.FileName);
-                    
-                    return CompletedTask<object>.Default;
-                }
-                string path = state.Path.ToLower();
 
-                //Bypass deleted files, unless the status is Deleted
-                if (!File.Exists(path) && state.Status != FileStatus.Deleted)
-                {
-                    state.Skip = true;
-                    this.StatusKeeper.ClearFileStatus(path);
-                    
-                    if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
+                    if (Log.IsDebugEnabled)
+                        Log.DebugFormat("State {0} {1} {2}", state.FileName, state.Status, state.TriggeringChange);
 
-                    return CompletedTask<object>.Default;
-                }
+                    if (state.Skip)
+                    {
+                        if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}", state.FileName);
+
+                        return CompletedTask<object>.Default;
+                    }
+                    string path = state.Path.ToLower();
+
+                    //Bypass deleted files, unless the status is Deleted
+                    if (!File.Exists(path) && state.Status != FileStatus.Deleted)
+                    {
+                        state.Skip = true;
+                        this.StatusKeeper.ClearFileStatus(path);
+
+                        if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName);
+
+                        return CompletedTask<object>.Default;
+                    }
+
+                    var fileState = FileState.FindByFilePath(path);
+                    var info = new FileInfo(path);
 
-                var fileState = FileState.FindByFilePath(path);
-                var info = new FileInfo(path);
 
+                    switch (state.Status)
+                    {
+                        case FileStatus.Created:
+                        case FileStatus.Modified:
+                            NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState, accountInfo.BlockSize,
+                                                                    accountInfo.BlockHash));
+                            break;
+                        case FileStatus.Deleted:
+                            NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState));
+                            break;
+                        case FileStatus.Renamed:
+                            NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud,
+                                                                  new FileInfo(state.OldPath),
+                                                                  new FileInfo(state.Path)));
+                            break;
+                    }
 
-                switch (state.Status)
+                    return CompletedTask<object>.Default;
+                }
+                catch (Exception ex)
                 {
-                    case FileStatus.Created:
-                    case FileStatus.Modified:
-                        NetworkAgent.Post(new CloudUploadAction(accountInfo,info, fileState, accountInfo.BlockSize,
-                            accountInfo.BlockHash));
-                        break;
-                    case FileStatus.Deleted:                       
-                        NetworkAgent.Post(new CloudDeleteAction(accountInfo,info, fileState));
-                        break;
-                    case FileStatus.Renamed:
-                        NetworkAgent.Post(new CloudMoveAction(accountInfo,CloudActionType.RenameCloud, new FileInfo(state.OldPath),
-                                                              new FileInfo(state.Path)));
-                        break;
+                    Log.Error(ex.ToString());
+                    throw;
                 }
-
-                return CompletedTask<object>.Default;
             }
         }
 
@@ -120,7 +131,8 @@ namespace Pithos.Core.Agents
                 var pendingStates = new List<WorkflowState>();
                 foreach (var state in pendingEntries)
                 {
-                    pendingStates.Add(new WorkflowState(account, state));
+                    if (!Directory.Exists(state.FilePath))
+                        pendingStates.Add(new WorkflowState(account, state));
                 }
                 if (Log.IsDebugEnabled)
                     Log.DebugFormat("Found {0} interrupted files", pendingStates.Count);
index 41393dd..59d5e70 100644 (file)
@@ -9,11 +9,8 @@ using System.IO;
 using System.Threading.Tasks;
 using Castle.ActiveRecord;
 using Castle.ActiveRecord.Framework;
-using Castle.ActiveRecord.Queries;
-using NHibernate.Engine;
 using Pithos.Core.Agents;
 using Pithos.Interfaces;
-using Pithos.Network;
 using log4net;
 
 namespace Pithos.Core
@@ -21,7 +18,6 @@ namespace Pithos.Core
     using System;
     using System.Collections.Generic;
     using System.Linq;
-    using System.Text;
 
     /// <summary>
     /// TODO: Update summary.
@@ -53,10 +49,6 @@ namespace Pithos.Core
         [Property]
         public string Checksum { get; set; }
 
-/*
-        [Property]
-        public string TopHash { get; set; }
-*/
 
         [Property]
         public long? Version { get; set; }
@@ -82,12 +74,7 @@ namespace Pithos.Core
             set { _tags=value;}
         }
 
-//        [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
-//        public IList<FileHash> Hashes { get; set; }
-
-//        [Property]
-//        public byte[] HashmapHash { get; set; }
-       
+   
         public static FileState FindByFilePath(string absolutePath)
         {
             if (string.IsNullOrWhiteSpace(absolutePath))
@@ -112,17 +99,151 @@ namespace Pithos.Core
                 throw new ArgumentNullException("absolutePath");
             Contract.EndContractBlock();
             
-            FileState.Execute((session, instance) =>
+            Execute((session, instance) =>
                              {
                                  const string hqlDelete = "delete FileState where FilePath = :path";                                 
                                  var deletedEntities = session.CreateQuery(hqlDelete)
                                          .SetString("path", absolutePath.ToLower())
                                          .ExecuteUpdate();
-                                 return null;
+                                 return deletedEntities;
                              },null);
             
         }
 
+        public static void StoreFileStatus(string absolutePath, FileStatus newStatus)
+        {
+            if (string.IsNullOrWhiteSpace(absolutePath))
+                throw new ArgumentNullException("absolutePath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set FileStatus= :status where FilePath = :path  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("path", absolutePath.ToLower())
+                        .SetEnum("status", newStatus)
+                        .ExecuteUpdate();
+                if (updatedEntities == 0)
+                {
+                    var newState = new FileState { FilePath = absolutePath, Id = Guid.NewGuid(), FileStatus = newStatus };
+                    newState.CreateAndFlush();
+                }
+                return null;
+            }, null);
+
+        }
+
+        public static void StoreOverlayStatus(string absolutePath, FileOverlayStatus newStatus)
+        {
+            if (string.IsNullOrWhiteSpace(absolutePath))
+                throw new ArgumentNullException("absolutePath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set OverlayStatus= :status where FilePath = :path  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("path", absolutePath.ToLower())
+                        .SetEnum("status", newStatus)
+                        .ExecuteUpdate();
+                if (updatedEntities == 0)
+                {
+                    var newState = new FileState { FilePath = absolutePath, Id = Guid.NewGuid(), OverlayStatus = newStatus };
+                    newState.CreateAndFlush();
+                }
+                return null;
+            }, null);
+
+        }
+
+        public static void UpdateStatus(string absolutePath, FileStatus fileStatus, FileOverlayStatus overlayStatus)
+        {
+            if (string.IsNullOrWhiteSpace(absolutePath))
+                throw new ArgumentNullException("absolutePath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set OverlayStatus= :overlayStatus, FileStatus= :fileStatus where FilePath = :path  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("path", absolutePath.ToLower())
+                        .SetEnum("fileStatus", fileStatus)
+                        .SetEnum("overlayStatus", overlayStatus)
+                        .ExecuteUpdate();
+                return updatedEntities;
+            }, null);
+
+        }
+        public static void UpdateStatus(string absolutePath, FileStatus fileStatus)
+        {
+            if (string.IsNullOrWhiteSpace(absolutePath))
+                throw new ArgumentNullException("absolutePath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set FileStatus= :fileStatus where FilePath = :path  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("path", absolutePath.ToLower())
+                        .SetEnum("fileStatus", fileStatus)                        
+                        .ExecuteUpdate();
+                return updatedEntities;
+            }, null);
+
+        }
+
+        public static void RenameState(string oldPath, string newPath)
+        {
+            if (string.IsNullOrWhiteSpace(oldPath))
+                throw new ArgumentNullException("oldPath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set FilePath= :newPath where FilePath = :oldPath  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("oldPath", oldPath.ToLower())
+                        .SetString("newPath", newPath.ToLower())                                          
+                        .ExecuteUpdate();
+                return updatedEntities;
+            }, null);
+
+        }
+
+        public static void UpdateStatus(Guid id, FileStatus fileStatus)
+        {
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set FileStatus= :fileStatus where Id = :id  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetGuid("id", id)
+                        .SetEnum("fileStatus", fileStatus)                        
+                        .ExecuteUpdate();
+                return updatedEntities;
+            }, null);
+
+        }
+
+        public static void UpdateChecksum(string absolutePath, string checksum)
+        {
+            if (string.IsNullOrWhiteSpace(absolutePath))
+                throw new ArgumentNullException("absolutePath");
+            Contract.EndContractBlock();
+
+            Execute((session, instance) =>
+            {
+                const string hqlUpdate = "update FileState set Checksum= :checksum where FilePath = :path  ";
+                var updatedEntities = session.CreateQuery(hqlUpdate)
+                        .SetString("path", absolutePath.ToLower())
+                        .SetString("checksum", checksum)                        
+                        .ExecuteUpdate();
+                return updatedEntities;
+            }, null);
+
+        }
+
         public static void ChangeRootPath(string oldPath,string newPath)
         {
             if (String.IsNullOrWhiteSpace(oldPath))
@@ -147,11 +268,11 @@ namespace Pithos.Core
                             {
                                 const string hqlUpdate =
                                     "update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
-                                var result=session.CreateQuery(hqlUpdate)
+                                var renames=session.CreateQuery(hqlUpdate)
                                     .SetString("oldPath", oldPath.ToLower())
                                     .SetString("newPath", newPath.ToLower())
                                     .ExecuteUpdate();
-                                return null;
+                                return renames;
                             }, null);
             }
         }
@@ -221,23 +342,5 @@ namespace Pithos.Core
         public FileState FileState { get; set; }
 
     }
-    
-  /*  [ActiveRecord("hashes")]
-    public class FileHash : ActiveRecordLinqBase<FileHash>
-    {
-        [PrimaryKey]
-        public int Id { get; set; }
-
-        [Property]
-        public int Order { get; set; }
-
-        [Property]
-        public byte[] Value { get; set; }        
-
-        [BelongsTo("FileStateID")]
-        public FileState FileState { get; set; }
-
-    }*/
-
-
+   
 }
index b4f2163..56f3bba 100644 (file)
@@ -22,8 +22,8 @@ namespace Pithos.Core
         void Stop();
         void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus);
         void StoreInfo(string path, ObjectInfo objectInfo);
-        T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue );
-        void SetStatus(string path, Action<FileState> setter);        
+        //T GetStatus<T>(string path,Func<FileState,T> getter,T defaultValue );
+        //void SetStatus(string path, Action<FileState> setter);        
 
         void StartProcessing(CancellationToken token);
 
index 0245ab8..56bba53 100644 (file)
@@ -283,7 +283,7 @@ namespace Pithos.Core
                 throw new ArgumentNullException("path", "The path parameter must not be emtpy");
 
             if (!Directory.Exists(path) && !File.Exists(path))
-                throw new FileNotFoundException("The specified file or path does not exist", path);
+                return;
 
 
             IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
index 67b60a0..b8378fc 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Diagnostics.Contracts;
 using System.Dynamic;
 using System.Globalization;
@@ -10,6 +11,7 @@ using Newtonsoft.Json;
 
 namespace Pithos.Interfaces
 {
+    [DebuggerDisplay("Name {Name}")]
     public class ObjectInfo:DynamicObject 
     {
         private readonly List<string> _knownContainers= new List<string>{"trash"};
@@ -148,7 +150,7 @@ namespace Pithos.Interfaces
             _extensions.TryGetValue(name, out value);
             return value ;                        
         }
-
+        
         private long? GetLong(string name)
         {
             string version;
index cf04099..3089b0e 100644 (file)
@@ -1110,7 +1110,7 @@ namespace Pithos.Network
         }
 
 
-        public Task<TreeHash> GetHashMap(string account, string container, string objectName)
+        public async Task<TreeHash> GetHashMap(string account, string container, string objectName)
         {
             if (String.IsNullOrWhiteSpace(container))
                 throw new ArgumentNullException("container");
@@ -1128,40 +1128,26 @@ namespace Pithos.Network
                 //object to avoid concurrency errors.
                 //
                 //Download operations take a long time therefore they have no timeout.
-                //TODO: Do we really? this is a hashmap operation, not a download
-                var client = new RestClient(_baseClient) { Timeout = 0 };
-                if (!String.IsNullOrWhiteSpace(account))
-                    client.BaseAddress = GetAccountUrl(account);
-
-
-                //The container and objectName are relative names. They are joined with the client's
-                //BaseAddress to create the object's absolute address
-                var builder = client.GetAddressBuilder(container, objectName);
-                builder.Query = "format=json&hashmap";
-                var uri = builder.Uri;
+                //TODO: Do they really? this is a hashmap operation, not a download
                 
                 //Start downloading the object asynchronously
-                var downloadTask = client.DownloadStringTask(uri);
-                
-                //Once the download completes
-                return downloadTask.ContinueWith(download =>
+                using (var client = new RestClient(_baseClient) { Timeout = 0 })
                 {
-                    //Delete the local client object
-                    client.Dispose();
-                    //And report failure or completion
-                    if (download.IsFaulted)
-                    {
-                        Log.ErrorFormat("[GET HASH] FAIL for {0} with \r{1}", objectName,
-                                        download.Exception);
-                        throw download.Exception;
-                    }
-                                          
-                    //The server will return an empty string if the file is empty
-                    var json = download.Result;
+                    if (!String.IsNullOrWhiteSpace(account))
+                        client.BaseAddress = GetAccountUrl(account);
+
+                    //The container and objectName are relative names. They are joined with the client's
+                    //BaseAddress to create the object's absolute address
+                    var builder = client.GetAddressBuilder(container, objectName);
+                    builder.Query = "format=json&hashmap";
+                    var uri = builder.Uri;
+
+
+                    var json = await client.DownloadStringTaskAsync(uri);
                     var treeHash = TreeHash.Parse(json);
-                    Log.InfoFormat("[GET HASH] END {0}", objectName);                                             
+                    Log.InfoFormat("[GET HASH] END {0}", objectName);
                     return treeHash;
-                });
+                }
             }
             catch (Exception exc)
             {
@@ -1169,8 +1155,6 @@ namespace Pithos.Network
                 throw;
             }
 
-
-
         }
 
 
index 6474704..d0d8612 100644 (file)
@@ -36,8 +36,6 @@ Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Pithos.Setup.x64", "Pithos.
 EndProject
 Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Pithos.Setup.x86", "Pithos.Setup.x86\Pithos.Setup.x86.vdproj", "{0D7E50F2-D7B4-4458-AA01-2CAC0F386737}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetworkTests", "Tests\NetworkTests\NetworkTests.csproj", "{052D04DA-28FE-471F-96FD-BC1E92BF2A54}"
-EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug All|Any CPU = Debug All|Any CPU
@@ -534,36 +532,6 @@ Global
                {0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|Mixed Platforms.ActiveCfg = Release
                {0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x64.ActiveCfg = Release
                {0D7E50F2-D7B4-4458-AA01-2CAC0F386737}.Test|x86.ActiveCfg = Release
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Any CPU.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|Mixed Platforms.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x64.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug All|x86.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Any CPU.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|Mixed Platforms.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x64.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Debug|x86.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Any CPU.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|Mixed Platforms.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x64.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.ActiveCfg = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Premium Debug|x86.Build.0 = Debug|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Any CPU.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|Mixed Platforms.Build.0 = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x64.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Release|x86.Build.0 = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Any CPU.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|Mixed Platforms.Build.0 = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x64.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.ActiveCfg = Release|x86
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54}.Test|x86.Build.0 = Release|x86
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -573,6 +541,5 @@ Global
                {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
                {E027200B-C26A-4877-BFD9-1A18CF5DF2F4} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
                {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
-               {052D04DA-28FE-471F-96FD-BC1E92BF2A54} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
        EndGlobalSection
 EndGlobal