-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLinqFileSystemProvider.vb
203 lines (190 loc) · 9.93 KB
/
LinqFileSystemProvider.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports DevExpress.Web
Imports System.IO
Public Class LinqFileSystemProvider
Inherits FileSystemProviderBase
Private Const DbRootItemId As Integer = 1
Private dataContext_Renamed As DbFileSystemDataContext
Private folderCache_Renamed As Dictionary(Of Integer, DbFileSystemItem)
Private rootFolderDisplayName_Renamed As String
Public Sub New(ByVal rootFolder As String)
MyBase.New(rootFolder)
Me.dataContext_Renamed = New DbFileSystemDataContext()
RefreshFolderCache()
End Sub
Public ReadOnly Property DataContext() As DbFileSystemDataContext
Get
Return dataContext_Renamed
End Get
End Property
' Used to decrease the number of recursive LINQ to SQL queries made to a database
Public ReadOnly Property FolderCache() As Dictionary(Of Integer, DbFileSystemItem)
Get
Return folderCache_Renamed
End Get
End Property
Public Overrides ReadOnly Property RootFolderDisplayName() As String
Get
Return rootFolderDisplayName_Renamed
End Get
End Property
Public Overrides Function GetFiles(ByVal folder As FileManagerFolder) As IEnumerable(Of FileManagerFile)
Dim dbFolderItem As DbFileSystemItem = FindDbFolderItem(folder)
Return _
From dbItem In DataContext.DbFileSystemItems _
Where (Not dbItem.IsFolder) AndAlso dbItem.ParentId = dbFolderItem.Id _
Select New FileManagerFile(Me, folder, dbItem.Name, dbItem.Id.ToString())
End Function
Public Overrides Function GetFolders(ByVal parentFolder As FileManagerFolder) As IEnumerable(Of FileManagerFolder)
Dim dbFolderItem As DbFileSystemItem = FindDbFolderItem(parentFolder)
Return _
From dbItem In FolderCache.Values _
Where dbItem.IsFolder AndAlso dbItem.ParentId = dbFolderItem.Id _
Select New FileManagerFolder(Me, parentFolder, dbItem.Name, dbItem.Id.ToString())
End Function
Public Overrides Function Exists(ByVal file As FileManagerFile) As Boolean
Return FindDbFileItem(file) IsNot Nothing
End Function
Public Overrides Function Exists(ByVal folder As FileManagerFolder) As Boolean
Return FindDbFolderItem(folder) IsNot Nothing
End Function
Public Overrides Function ReadFile(ByVal file As FileManagerFile) As System.IO.Stream
Return New MemoryStream(FindDbFileItem(file).Data.ToArray())
End Function
Public Overrides Function GetLastWriteTime(ByVal file As FileManagerFile) As DateTime
Dim dbFileItem = FindDbFileItem(file)
Return dbFileItem.LastWriteTime.GetValueOrDefault(DateTime.Now)
End Function
' File/folder management operations
Public Overrides Sub CreateFolder(ByVal parent As FileManagerFolder, ByVal name As String)
UpdateAndSubmitChanges(parent, Sub(dbItem) DataContext.DbFileSystemItems.InsertOnSubmit(New DbFileSystemItem() With {.IsFolder = True, .LastWriteTime = DateTime.Now, .Name = name, .ParentId = dbItem.Id}))
End Sub
Public Overrides Sub DeleteFile(ByVal file As FileManagerFile)
UpdateAndSubmitChanges(file, Sub(dbItem) DataContext.DbFileSystemItems.DeleteOnSubmit(dbItem))
End Sub
Public Overrides Sub DeleteFolder(ByVal folder As FileManagerFolder)
UpdateAndSubmitChanges(folder, Sub(dbItem) DataContext.DbFileSystemItems.DeleteOnSubmit(dbItem))
End Sub
Public Overrides Sub MoveFile(ByVal file As FileManagerFile, ByVal newParentFolder As FileManagerFolder)
UpdateAndSubmitChanges(file, Sub(dbItem) dbItem.ParentId = FindDbFolderItem(newParentFolder).Id)
End Sub
Public Overrides Sub MoveFolder(ByVal folder As FileManagerFolder, ByVal newParentFolder As FileManagerFolder)
UpdateAndSubmitChanges(folder, Sub(dbItem) dbItem.ParentId = FindDbFolderItem(newParentFolder).Id)
End Sub
Public Overrides Sub RenameFile(ByVal file As FileManagerFile, ByVal name As String)
UpdateAndSubmitChanges(file, Sub(dbItem) dbItem.Name = name)
End Sub
Public Overrides Sub RenameFolder(ByVal folder As FileManagerFolder, ByVal name As String)
UpdateAndSubmitChanges(folder, Sub(dbItem) dbItem.Name = name)
End Sub
Public Overrides Sub UploadFile(ByVal folder As FileManagerFolder, ByVal fileName As String, ByVal content As Stream)
UpdateAndSubmitChanges(folder, Sub(dbItem) DataContext.DbFileSystemItems.InsertOnSubmit(New DbFileSystemItem() With {.Name = fileName, .Data = ReadAllBytes(content), .ParentId = dbItem.Id, .LastWriteTime = DateTime.Now, .IsFolder = False}))
End Sub
Public Overrides Sub CopyFile(ByVal file As FileManagerFile, ByVal newParentFolder As FileManagerFolder)
Dim dbFileItem = FindDbFileItem(file)
CopyCore(dbFileItem, newParentFolder.RelativeName, False)
End Sub
Public Overrides Sub CopyFolder(ByVal folder As FileManagerFolder, ByVal newParentFolder As FileManagerFolder)
Dim folders As New List(Of FileManagerFolder)()
FillSubFoldersList(folder, folders)
Dim folderNameOffset As Integer = If((Not String.IsNullOrEmpty(folder.Parent.RelativeName)), folder.Parent.RelativeName.Length + 1, 0)
For Each copyingFolder As FileManagerFolder In folders
Dim dbFolderItem As DbFileSystemItem = FindDbFolderItem(copyingFolder)
Dim folderPath As String = newParentFolder.RelativeName
If copyingFolder IsNot folder Then
folderPath = Path.Combine(folderPath, copyingFolder.Parent.RelativeName.Substring(folderNameOffset))
End If
CopyCore(dbFolderItem, folderPath, True)
For Each currentFile As FileManagerFile In copyingFolder.GetFiles()
Dim dbFileItem As DbFileSystemItem = FindDbFileItem(currentFile)
CopyCore(dbFileItem, Path.Combine(folderPath, copyingFolder.Name), False)
Next currentFile
Next copyingFolder
End Sub
Private Sub FillSubFoldersList(ByVal folder As FileManagerFolder, ByVal list As List(Of FileManagerFolder))
list.Add(folder)
For Each subFolder As FileManagerFolder In folder.GetFolders()
FillSubFoldersList(subFolder, list)
Next subFolder
End Sub
Private Sub CopyCore(ByVal item As DbFileSystemItem, ByVal path As String, ByVal isFolder As Boolean)
Dim newParentFolder As New FileManagerFolder(Me, path)
UpdateAndSubmitChanges(newParentFolder, Sub(dbItem) DataContext.DbFileSystemItems.InsertOnSubmit(New DbFileSystemItem() With {.Name = item.Name, .Data = item.Data, .ParentId = dbItem.Id, .LastWriteTime = DateTime.Now, .IsFolder = isFolder}))
End Sub
Protected Sub UpdateAndSubmitChanges(ByVal file As FileManagerFile, ByVal update As Action(Of DbFileSystemItem))
UpdateAndSubmitChangesCore(FindDbFileItem(file), update)
End Sub
Protected Sub UpdateAndSubmitChanges(ByVal folder As FileManagerFolder, ByVal update As Action(Of DbFileSystemItem))
UpdateAndSubmitChangesCore(FindDbFolderItem(folder), update)
End Sub
Protected Sub UpdateAndSubmitChangesCore(ByVal dbitem As DbFileSystemItem, ByVal update As Action(Of DbFileSystemItem))
update(dbitem)
DataContext.SubmitChanges()
RefreshFolderCache()
End Sub
Protected Function FindDbFileItem(ByVal file As FileManagerFile) As DbFileSystemItem
Dim dbFolderItem As DbFileSystemItem = FindDbFolderItem(file.Folder)
If dbFolderItem Is Nothing Then
Return Nothing
End If
Return ( _
From dbItem In DataContext.DbFileSystemItems _
Where dbItem.ParentId = dbFolderItem.Id AndAlso (Not dbItem.IsFolder) AndAlso dbItem.Name = file.Name _
Select dbItem).FirstOrDefault()
End Function
Protected Function FindDbFolderItem(ByVal folder As FileManagerFolder) As DbFileSystemItem
Return ( _
From dbItem In FolderCache.Values _
Where dbItem.IsFolder AndAlso GetRelativeName(dbItem) = folder.RelativeName _
Select dbItem).FirstOrDefault()
End Function
' Returns the path to a specified folder relative to a root folder
Protected Function GetRelativeName(ByVal dbFolder As DbFileSystemItem) As String
If dbFolder.Id = DbRootItemId Then
Return String.Empty
End If
If dbFolder.ParentId = DbRootItemId Then
Return dbFolder.Name
End If
If (Not FolderCache.ContainsKey(dbFolder.ParentId)) Then
Return Nothing
End If
Dim name As String = GetRelativeName(FolderCache(dbFolder.ParentId))
If name Is Nothing Then
Return Nothing
Else
Return Path.Combine(name, dbFolder.Name)
End If
End Function
' Caches folder names in memory and obtains a root folder's name
Protected Sub RefreshFolderCache()
Me.folderCache_Renamed = ( _
From dbItem In DataContext.DbFileSystemItems _
Where dbItem.IsFolder _
Select dbItem).ToDictionary(Function(i) i.Id)
Me.rootFolderDisplayName_Renamed = ( _
From dbItem In FolderCache.Values _
Where dbItem.Id = DbRootItemId _
Select dbItem.Name).First()
End Sub
Protected Shared Function ReadAllBytes(ByVal stream As Stream) As Byte()
Dim buffer(16 * 1024 - 1) As Byte
Dim readCount As Integer
Using ms As New MemoryStream()
readCount = stream.Read(buffer, 0, buffer.Length)
Do While readCount > 0
ms.Write(buffer, 0, readCount)
readCount = stream.Read(buffer, 0, buffer.Length)
Loop
Return ms.ToArray()
End Using
End Function
' Get file size (length).
Public Overrides Function GetLength(ByVal file As FileManagerFile) As Long
Return FindDbFileItem(file).Data.Length
End Function
End Class