Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / FileState.cs @ 4ec636f6

History | View | Annotate | Download (7.6 kB)

1
// -----------------------------------------------------------------------
2
// <copyright file="FileState.cs" company="Microsoft">
3
// TODO: Update copyright text.
4
// </copyright>
5
// -----------------------------------------------------------------------
6

    
7
using System.Diagnostics.Contracts;
8
using System.IO;
9
using System.Threading.Tasks;
10
using Castle.ActiveRecord;
11
using Castle.ActiveRecord.Framework;
12
using Castle.ActiveRecord.Queries;
13
using NHibernate.Engine;
14
using Pithos.Core.Agents;
15
using Pithos.Interfaces;
16
using Pithos.Network;
17
using log4net;
18

    
19
namespace Pithos.Core
20
{
21
    using System;
22
    using System.Collections.Generic;
23
    using System.Linq;
24
    using System.Text;
25

    
26
    /// <summary>
27
    /// TODO: Update summary.
28
    /// </summary>
29
    [ActiveRecord]
30
    public class FileState:ActiveRecordLinqBase<FileState>
31
    {
32
        private static readonly ILog Log = LogManager.GetLogger("FileState");
33
        
34
        private string _filePath;
35
        private IList<FileTag> _tags=new List<FileTag>();
36

    
37
        [PrimaryKey(PrimaryKeyType.Guid)]
38
        public Guid Id { get; set; }
39

    
40
        [Property(Unique=true,UniqueKey="IX_FileState_FilePath")]
41
        public string FilePath
42
        {
43
            get { return _filePath; }
44
            set { _filePath = value.ToLower(); }
45
        }
46

    
47
        [Property]
48
        public FileOverlayStatus OverlayStatus { get; set; }
49

    
50
        [Property]
51
        public FileStatus FileStatus { get; set; }
52

    
53
        [Property]
54
        public string Checksum { get; set; }
55

    
56
/*
57
        [Property]
58
        public string TopHash { get; set; }
59
*/
60

    
61
        [Property]
62
        public long? Version { get; set; }
63

    
64
        [Property]
65
        public DateTime? VersionTimeStamp { get; set; }
66

    
67

    
68
        [Property]
69
        public bool IsShared { get; set; }
70

    
71
        [Property]
72
        public string SharedBy { get; set; }
73

    
74
        [Property]
75
        public bool ShareWrite { get; set; }
76

    
77

    
78
       [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true,Inverse=true)]
79
        public IList<FileTag> Tags
80
        {
81
            get { return _tags; }   
82
            set { _tags=value;}
83
        }
84

    
85
//        [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
86
//        public IList<FileHash> Hashes { get; set; }
87

    
88
//        [Property]
89
//        public byte[] HashmapHash { get; set; }
90
       
91
        public static FileState FindByFilePath(string absolutePath)
92
        {
93
            if (string.IsNullOrWhiteSpace(absolutePath))
94
                throw new ArgumentNullException("absolutePath");
95
            Contract.EndContractBlock();
96
            try
97
            {
98
                return Queryable.FirstOrDefault(s => s.FilePath == absolutePath.ToLower());
99
            }
100
            catch (Exception ex)
101
            {
102
                Log.Error(ex.ToString());
103
                throw;
104
            }
105
                
106

    
107
        }
108

    
109
        public static void DeleteByFilePath(string absolutePath)
110
        {
111
            if(string.IsNullOrWhiteSpace(absolutePath))
112
                throw new ArgumentNullException("absolutePath");
113
            Contract.EndContractBlock();
114
            
115
            FileState.Execute((session, instance) =>
116
                             {
117
                                 const string hqlDelete = "delete FileState where FilePath = :path";                                 
118
                                 var deletedEntities = session.CreateQuery(hqlDelete)
119
                                         .SetString("path", absolutePath.ToLower())
120
                                         .ExecuteUpdate();
121
                                 return null;
122
                             },null);
123
            
124
        }
125

    
126
        public static void ChangeRootPath(string oldPath,string newPath)
127
        {
128
            if (String.IsNullOrWhiteSpace(oldPath))
129
                throw new ArgumentNullException("oldPath");
130
            if (!Path.IsPathRooted(oldPath))
131
                throw new ArgumentException("oldPath must be an absolute path", "oldPath");
132
            if (string.IsNullOrWhiteSpace(newPath))
133
                throw new ArgumentNullException("newPath");
134
            if (!Path.IsPathRooted(newPath))
135
                throw new ArgumentException("newPath must be an absolute path", "newPath");
136
            Contract.EndContractBlock();
137

    
138
            //Ensure the paths end with the same character
139
            if (!oldPath.EndsWith("\\"))
140
                oldPath = oldPath + "\\";
141
            if (!newPath.EndsWith("\\"))
142
                newPath = newPath + "\\";
143

    
144
            using (new TransactionScope())
145
            {
146
                Execute((session, instance) =>
147
                            {
148
                                const string hqlUpdate =
149
                                    "update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
150
                                var result=session.CreateQuery(hqlUpdate)
151
                                    .SetString("oldPath", oldPath.ToLower())
152
                                    .SetString("newPath", newPath.ToLower())
153
                                    .ExecuteUpdate();
154
                                return null;
155
                            }, null);
156
            }
157
        }
158

    
159
        public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
160
        {
161
            if (blockSize <= 0)
162
                throw new ArgumentOutOfRangeException("blockSize");
163
            if (String.IsNullOrWhiteSpace(algorithm))
164
                throw new ArgumentNullException("algorithm");
165
            Contract.EndContractBlock();
166

    
167

    
168
            var fileState = new FileState
169
                                {
170
                                    FilePath = filePath, 
171
                                    OverlayStatus = FileOverlayStatus.Unversioned, 
172
                                    FileStatus = FileStatus.Created,
173
                                    Id=Guid.NewGuid()
174
                                };
175

    
176

    
177
            return fileState.UpdateHashesAsync(blockSize,algorithm);            
178
        }
179

    
180
        public Task<FileState> UpdateHashesAsync(int blockSize,string algorithm)
181
        {
182
            if (blockSize<=0)
183
                throw new ArgumentOutOfRangeException("blockSize");
184
            if (String.IsNullOrWhiteSpace(algorithm))
185
                throw new ArgumentNullException("algorithm");
186
            Contract.EndContractBlock();
187
            
188
            //Skip updating the hash for folders
189
            if (Directory.Exists(FilePath))
190
                return Task.Factory.FromResult(this);
191

    
192
            var results = Task.Factory.StartNew(() =>
193
            {
194
                var info = new FileInfo(FilePath);
195
                return info.CalculateHash(blockSize, algorithm);
196
            });
197

    
198
            var state=results.Then(hash =>
199
            {
200
                Checksum = hash;
201
                return Task.Factory.FromResult(this);
202
            });
203
            
204
            return state;
205
        }
206
    }
207

    
208
    [ActiveRecord("Tags")]
209
    public class FileTag : ActiveRecordLinqBase<FileTag>
210
    {
211
        [PrimaryKey]
212
        public int Id { get; set; }
213

    
214
        [Property]
215
        public string Name { get; set; }
216

    
217
        [Property]
218
        public string Value { get; set; }
219

    
220
        [BelongsTo("FileStateId")]
221
        public FileState FileState { get; set; }
222

    
223
    }
224
    
225
  /*  [ActiveRecord("hashes")]
226
    public class FileHash : ActiveRecordLinqBase<FileHash>
227
    {
228
        [PrimaryKey]
229
        public int Id { get; set; }
230

    
231
        [Property]
232
        public int Order { get; set; }
233

    
234
        [Property]
235
        public byte[] Value { get; set; }        
236

    
237
        [BelongsTo("FileStateID")]
238
        public FileState FileState { get; set; }
239

    
240
    }*/
241

    
242

    
243
}