Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / FileState.cs @ 5120f3cb

History | View | Annotate | Download (7.3 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

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

    
25
    /// <summary>
26
    /// TODO: Update summary.
27
    /// </summary>
28
    [ActiveRecord]
29
    public class FileState:ActiveRecordLinqBase<FileState>
30
    {
31
        private string _filePath;
32
        private IList<FileTag> _tags=new List<FileTag>();
33

    
34
        [PrimaryKey(PrimaryKeyType.Guid)]
35
        public Guid Id { get; set; }
36

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

    
44
        [Property]
45
        public FileOverlayStatus OverlayStatus { get; set; }
46

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

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

    
53
/*
54
        [Property]
55
        public string TopHash { get; set; }
56
*/
57

    
58
        [Property]
59
        public long? Version { get; set; }
60

    
61
        [Property]
62
        public DateTime? VersionTimeStamp { get; set; }
63

    
64

    
65
        [Property]
66
        public bool IsShared { get; set; }
67

    
68
        [Property]
69
        public string SharedBy { get; set; }
70

    
71
        [Property]
72
        public bool ShareWrite { get; set; }
73

    
74

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

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

    
85
//        [Property]
86
//        public byte[] HashmapHash { get; set; }
87
       
88
        public static FileState FindByFilePath(string absolutePath)
89
        {
90
            if (string.IsNullOrWhiteSpace(absolutePath))
91
                throw new ArgumentNullException("absolutePath");
92
            Contract.EndContractBlock();
93
            return Queryable.FirstOrDefault(s => s.FilePath == absolutePath.ToLower());
94
        }
95

    
96
        public static void DeleteByFilePath(string absolutePath)
97
        {
98
            if(string.IsNullOrWhiteSpace(absolutePath))
99
                throw new ArgumentNullException("absolutePath");
100
            Contract.EndContractBlock();
101
            
102
            FileState.Execute((session, instance) =>
103
                             {
104
                                 const string hqlDelete = "delete FileState where FilePath = :path";                                 
105
                                 var deletedEntities = session.CreateQuery(hqlDelete)
106
                                         .SetString("path", absolutePath.ToLower())
107
                                         .ExecuteUpdate();
108
                                 return null;
109
                             },null);
110
            
111
        }
112

    
113
        public static void ChangeRootPath(string oldPath,string newPath)
114
        {
115
            if (String.IsNullOrWhiteSpace(oldPath))
116
                throw new ArgumentNullException("oldPath");
117
            if (!Path.IsPathRooted(oldPath))
118
                throw new ArgumentException("oldPath must be an absolute path", "oldPath");
119
            if (string.IsNullOrWhiteSpace(newPath))
120
                throw new ArgumentNullException("newPath");
121
            if (!Path.IsPathRooted(newPath))
122
                throw new ArgumentException("newPath must be an absolute path", "newPath");
123
            Contract.EndContractBlock();
124

    
125
            //Ensure the paths end with the same character
126
            if (!oldPath.EndsWith("\\"))
127
                oldPath = oldPath + "\\";
128
            if (!newPath.EndsWith("\\"))
129
                newPath = newPath + "\\";
130

    
131
            using (new TransactionScope())
132
            {
133
                Execute((session, instance) =>
134
                            {
135
                                const string hqlUpdate =
136
                                    "update FileState set FilePath = replace(FilePath,:oldPath,:newPath) where FilePath like :oldPath || '%' ";
137
                                var result=session.CreateQuery(hqlUpdate)
138
                                    .SetString("oldPath", oldPath.ToLower())
139
                                    .SetString("newPath", newPath.ToLower())
140
                                    .ExecuteUpdate();
141
                                return null;
142
                            }, null);
143
            }
144
        }
145

    
146
        public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
147
        {
148
            if (blockSize <= 0)
149
                throw new ArgumentOutOfRangeException("blockSize");
150
            if (String.IsNullOrWhiteSpace(algorithm))
151
                throw new ArgumentNullException("algorithm");
152
            Contract.EndContractBlock();
153

    
154

    
155
            var fileState = new FileState
156
                                {
157
                                    FilePath = filePath, 
158
                                    OverlayStatus = FileOverlayStatus.Unversioned, 
159
                                    FileStatus = FileStatus.Created,
160
                                    Id=Guid.NewGuid()
161
                                };
162

    
163

    
164
            return fileState.UpdateHashesAsync(blockSize,algorithm);            
165
        }
166

    
167
        public Task<FileState> UpdateHashesAsync(int blockSize,string algorithm)
168
        {
169
            if (blockSize<=0)
170
                throw new ArgumentOutOfRangeException("blockSize");
171
            if (String.IsNullOrWhiteSpace(algorithm))
172
                throw new ArgumentNullException("algorithm");
173
            Contract.EndContractBlock();
174
            
175
            //Skip updating the hash for folders
176
            if (Directory.Exists(FilePath))
177
                return Task.Factory.FromResult(this);
178

    
179
            var results = Task.Factory.StartNew(() =>
180
            {
181
                var info = new FileInfo(FilePath);
182
                return info.CalculateHash(blockSize, algorithm);
183
            });
184

    
185
            var state=results.Then(hash =>
186
            {
187
                Checksum = hash;
188
                return Task.Factory.FromResult(this);
189
            });
190
            
191
            return state;
192
        }
193
    }
194

    
195
    [ActiveRecord("Tags")]
196
    public class FileTag : ActiveRecordLinqBase<FileTag>
197
    {
198
        [PrimaryKey]
199
        public int Id { get; set; }
200

    
201
        [Property]
202
        public string Name { get; set; }
203

    
204
        [Property]
205
        public string Value { get; set; }
206

    
207
        [BelongsTo("FileStateId")]
208
        public FileState FileState { get; set; }
209

    
210
    }
211
    
212
  /*  [ActiveRecord("hashes")]
213
    public class FileHash : ActiveRecordLinqBase<FileHash>
214
    {
215
        [PrimaryKey]
216
        public int Id { get; set; }
217

    
218
        [Property]
219
        public int Order { get; set; }
220

    
221
        [Property]
222
        public byte[] Value { get; set; }        
223

    
224
        [BelongsTo("FileStateID")]
225
        public FileState FileState { get; set; }
226

    
227
    }*/
228

    
229

    
230
}