Uploading and downloading with hashes
[pithos-ms-client] / trunk / Pithos.Core / FileState.cs
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 NHibernate.Engine;
13 using Pithos.Interfaces;
14 using Pithos.Network;
15
16 namespace Pithos.Core
17 {
18     using System;
19     using System.Collections.Generic;
20     using System.Linq;
21     using System.Text;
22
23     /// <summary>
24     /// TODO: Update summary.
25     /// </summary>
26     [ActiveRecord]
27     public class FileState:ActiveRecordLinqBase<FileState>
28     {
29         private string _filePath;
30         private IList<FileTag> _tags=new List<FileTag>();
31
32         [PrimaryKey(PrimaryKeyType.Guid)]
33         public Guid Id { get; set; }
34
35         [Property(Unique=true,UniqueKey="IX_FileState_FilePath")]
36         public string FilePath
37         {
38             get { return _filePath; }
39             set { _filePath = value.ToLower(); }
40         }
41
42         [Property]
43         public FileOverlayStatus OverlayStatus { get; set; }
44
45         [Property]
46         public FileStatus FileStatus { get; set; }
47
48         [Property]
49         public string Checksum { get; set; }
50
51         [Property]
52         public string TopHash { get; set; }
53
54         [Property]
55         public long? Version { get; set; }
56
57         [Property]
58         public DateTime? VersionTimeStamp { get; set; }
59         
60
61        [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true,Inverse=true)]
62         public IList<FileTag> Tags
63         {
64             get { return _tags; }   
65             set { _tags=value;}
66         }
67
68 //        [HasMany(Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
69 //        public IList<FileHash> Hashes { get; set; }
70
71 //        [Property]
72 //        public byte[] HashmapHash { get; set; }
73        
74         public static FileState FindByFilePath(string absolutePath)
75         {
76             return Queryable.FirstOrDefault(s => s.FilePath == absolutePath.ToLower());
77         }
78
79         public static Task<FileState> CreateForAsync(string filePath,int blockSize,string algorithm)
80         {
81             if (blockSize <= 0)
82                 throw new ArgumentOutOfRangeException("blockSize");
83             if (String.IsNullOrWhiteSpace(algorithm))
84                 throw new ArgumentNullException("algorithm");
85             Contract.EndContractBlock();
86
87
88             var fileState = new FileState
89                                 {
90                                     FilePath = filePath, 
91                                     OverlayStatus = FileOverlayStatus.Unversioned, 
92                                     FileStatus = FileStatus.Created,
93                                     Id=Guid.NewGuid()
94                                 };
95
96
97             return fileState.UpdateHashesAsync(blockSize,algorithm);            
98         }
99
100         public Task<FileState> UpdateHashesAsync(int blockSize,string algorithm)
101         {
102             if (blockSize<=0)
103                 throw new ArgumentOutOfRangeException("blockSize");
104             if (String.IsNullOrWhiteSpace(algorithm))
105                 throw new ArgumentNullException("algorithm");
106             Contract.EndContractBlock();
107
108             //Skip updating the hash for folders
109             if (Directory.Exists(FilePath))
110                 return Task.Factory.StartNew(() => this);
111
112             var results=Task.Factory.TrackedSequence(
113                 () => Task.Factory.StartNew(() => Signature.CalculateMD5(FilePath)),
114                 () => Signature.CalculateTreeHashAsync(FilePath, blockSize, algorithm)
115                 );
116
117             results.ContinueWith(t =>
118             {
119                 var hashes = t.Result;
120                 Checksum = (hashes[0] as Task<string>).Result;
121                 TopHash = (hashes[0] as Task<TreeHash>).Result.TopHash.ToHashString();
122             });
123             
124             return results.ContinueWith(t => this);
125         }
126     }
127
128     [ActiveRecord("Tags")]
129     public class FileTag : ActiveRecordLinqBase<FileTag>
130     {
131         [PrimaryKey]
132         public int Id { get; set; }
133
134         [Property]
135         public string Name { get; set; }
136
137         [Property]
138         public string Value { get; set; }
139
140         [BelongsTo("FileStateId")]
141         public FileState FileState { get; set; }
142
143     }
144     
145   /*  [ActiveRecord("hashes")]
146     public class FileHash : ActiveRecordLinqBase<FileHash>
147     {
148         [PrimaryKey]
149         public int Id { get; set; }
150
151         [Property]
152         public int Order { get; set; }
153
154         [Property]
155         public byte[] Value { get; set; }        
156
157         [BelongsTo("FileStateID")]
158         public FileState FileState { get; set; }
159
160     }*/
161
162
163 }