Horizon – Diff between revs 3 and 5
?pathlinks?
Rev 3 | Rev 5 | |||
---|---|---|---|---|
Line 4... | Line 4... | |||
4 | using System.Drawing; |
4 | using System.Drawing; |
|
5 | using System.Drawing.Imaging; |
5 | using System.Drawing.Imaging; |
|
6 | using System.Globalization; |
6 | using System.Globalization; |
|
7 | using System.IO; |
7 | using System.IO; |
|
8 | using System.IO.Compression; |
8 | using System.IO.Compression; |
|
- | 9 | using System.Runtime.CompilerServices; |
||
9 | using System.Security.Cryptography; |
10 | using System.Security.Cryptography; |
|
10 | using System.Threading; |
11 | using System.Threading; |
|
11 | using System.Threading.Tasks; |
12 | using System.Threading.Tasks; |
|
12 | using Horizon.Snapshots; |
13 | using Horizon.Snapshots; |
|
13 | using Horizon.Utilities; |
14 | using Horizon.Utilities; |
|
Line 94... | Line 95... | |||
94 | #endregion |
95 | #endregion |
|
Line 95... | Line 96... | |||
95 | |
96 | |
|
Line 96... | Line 97... | |||
96 | #region Private Delegates, Events, Enums, Properties, Indexers and Fields |
97 | #region Private Delegates, Events, Enums, Properties, Indexers and Fields |
|
97 | |
- | ||
98 | private readonly CancellationTokenSource _cancellationTokenSource; |
98 | |
|
Line 99... | Line 99... | |||
99 | |
99 | private readonly CancellationTokenSource _cancellationTokenSource; |
|
Line 100... | Line 100... | |||
100 | private SemaphoreSlim _snapshotSemaphore; |
100 | private readonly SemaphoreSlim _databaseLock; |
|
Line 101... | Line 101... | |||
101 | |
101 | |
|
102 | #endregion |
102 | #endregion |
|
103 | |
- | ||
104 | #region Constructors, Destructors and Finalizers |
103 | |
|
Line 105... | Line 104... | |||
105 | |
104 | #region Constructors, Destructors and Finalizers |
|
- | 105 | |
||
Line -... | Line 106... | |||
- | 106 | private SnapshotDatabase() |
||
- | 107 | { |
||
- | 108 | Directory.CreateDirectory(Constants.DatabaseDirectory); |
||
106 | public SnapshotDatabase() |
109 | |
|
- | 110 | _databaseLock = new SemaphoreSlim(1, 1); |
||
- | 111 | } |
||
- | 112 | |
||
- | 113 | public SnapshotDatabase(CancellationToken cancellationToken) : this() |
||
- | 114 | { |
||
Line 107... | Line 115... | |||
107 | { |
115 | _cancellationTokenSource = new CancellationTokenSource(); |
|
108 | _cancellationTokenSource = new CancellationTokenSource(); |
116 | var localCancellationToken = _cancellationTokenSource.Token; |
|
109 | _cancellationToken = _cancellationTokenSource.Token; |
117 | var combinedCancellationTokenSource = |
|
110 | |
118 | CancellationTokenSource.CreateLinkedTokenSource(localCancellationToken, cancellationToken); |
|
Line 135... | Line 143... | |||
135 | } |
143 | } |
|
Line 136... | Line 144... | |||
136 | |
144 | |
|
137 | public void Dispose() |
145 | public void Dispose() |
|
138 | { |
146 | { |
|
139 | _cancellationTokenSource.Cancel(); |
- | ||
140 | |
- | ||
141 | _snapshotSemaphore?.Dispose(); |
- | ||
142 | _snapshotSemaphore = null; |
147 | _cancellationTokenSource.Cancel(); |
|
Line 143... | Line 148... | |||
143 | } |
148 | } |
|
Line 144... | Line 149... | |||
144 | |
149 | |
|
Line 151... | Line 156... | |||
151 | var connectionString = new SQLiteConnectionStringBuilder |
156 | var connectionString = new SQLiteConnectionStringBuilder |
|
152 | { |
157 | { |
|
153 | ConnectionString = DatabaseConnectionString |
158 | ConnectionString = DatabaseConnectionString |
|
154 | }; |
159 | }; |
|
Line 155... | Line 160... | |||
155 | |
160 | |
|
- | 161 | await _databaseLock.WaitAsync(cancellationToken); |
||
156 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
162 | try |
|
157 | { |
- | ||
158 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
159 | |
163 | { |
|
160 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
164 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
161 | { |
165 | { |
|
162 | // Insert the file change. |
- | ||
- | 166 | await sqliteConnection.OpenAsync(cancellationToken); |
||
163 | using (var sqliteCommand = |
167 | |
|
164 | new SQLiteCommand(RemoveScreenshotFromHashSql, sqliteConnection, dbTransaction)) |
168 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
- | 169 | { |
||
165 | { |
170 | // Insert the file change. |
|
- | 171 | using (var sqliteCommand = |
||
166 | try |
172 | new SQLiteCommand(RemoveScreenshotFromHashSql, sqliteConnection, dbTransaction)) |
|
167 | { |
173 | { |
|
168 | sqliteCommand.Parameters.AddRange(new[] |
174 | sqliteCommand.Parameters.AddRange(new[] |
|
169 | { |
175 | { |
|
170 | new SQLiteParameter("@hash", hash) |
176 | new SQLiteParameter("@hash", hash) |
|
Line 171... | Line 177... | |||
171 | }); |
177 | }); |
|
Line -... | Line 178... | |||
- | 178 | |
||
- | 179 | sqliteCommand.Prepare(); |
||
172 | |
180 | |
|
Line 173... | Line 181... | |||
173 | sqliteCommand.Prepare(); |
181 | try |
|
174 | |
182 | { |
|
175 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
183 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
176 | |
184 | |
|
177 | dbTransaction.Commit(); |
185 | dbTransaction.Commit(); |
|
Line 178... | Line 186... | |||
178 | } |
186 | } |
|
- | 187 | catch |
||
179 | catch |
188 | { |
|
180 | { |
189 | dbTransaction.Rollback(); |
|
181 | dbTransaction.Rollback(); |
190 | |
|
182 | |
191 | throw; |
|
- | 192 | } |
||
- | 193 | } |
||
- | 194 | } |
||
- | 195 | } |
||
183 | throw; |
196 | } |
|
Line 184... | Line 197... | |||
184 | } |
197 | finally |
|
185 | } |
198 | { |
|
186 | } |
199 | _databaseLock.Release(); |
|
187 | } |
200 | } |
|
188 | } |
201 | } |
|
189 | |
202 | |
|
Line 190... | Line 203... | |||
190 | public async Task NormalizeTime(string hash, CancellationToken cancellationToken) |
203 | public async Task NormalizeTime(string hash, CancellationToken cancellationToken) |
|
191 | { |
204 | { |
|
192 | var connectionString = new SQLiteConnectionStringBuilder |
205 | var connectionString = new SQLiteConnectionStringBuilder |
|
193 | { |
206 | { |
|
194 | ConnectionString = DatabaseConnectionString |
- | ||
195 | }; |
207 | ConnectionString = DatabaseConnectionString |
|
196 | |
208 | }; |
|
197 | using (var sqliteConnection = |
209 | |
|
- | 210 | await _databaseLock.WaitAsync(cancellationToken); |
||
- | 211 | try |
||
198 | new SQLiteConnection(connectionString.ConnectionString)) |
212 | { |
|
- | 213 | using (var sqliteConnection = |
||
- | 214 | new SQLiteConnection(connectionString.ConnectionString)) |
||
199 | { |
215 | { |
|
200 | await sqliteConnection.OpenAsync(cancellationToken); |
216 | await sqliteConnection.OpenAsync(cancellationToken); |
|
Line 201... | Line 217... | |||
201 | |
217 | |
|
Line 202... | Line 218... | |||
202 | using (var readSQLiteCommand = new SQLiteCommand(RetrieveTimeFromHash, sqliteConnection)) |
218 | using (var readSQLiteCommand = new SQLiteCommand(RetrieveTimeFromHash, sqliteConnection)) |
|
203 | { |
- | ||
204 | readSQLiteCommand.Parameters.AddRange(new[] |
- | ||
205 | { |
219 | { |
|
206 | new SQLiteParameter("@hash", hash) |
220 | readSQLiteCommand.Parameters.AddRange(new[] |
|
207 | }); |
221 | { |
|
208 | |
222 | new SQLiteParameter("@hash", hash) |
|
209 | readSQLiteCommand.Prepare(); |
223 | }); |
|
210 | |
224 | |
|
211 | using (var sqlDataReader = await readSQLiteCommand.ExecuteReaderAsync(cancellationToken)) |
- | ||
212 | { |
- | ||
213 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
- | ||
214 | { |
- | ||
215 | try |
- | ||
216 | { |
- | ||
217 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
225 | readSQLiteCommand.Prepare(); |
|
218 | { |
226 | |
|
219 | var time = (string)sqlDataReader["Time"]; |
- | ||
Line -... | Line 227... | |||
- | 227 | using (var sqlDataReader = await readSQLiteCommand.ExecuteReaderAsync(cancellationToken)) |
||
220 | |
228 | { |
|
- | 229 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
||
- | 230 | { |
||
- | 231 | try |
||
221 | // Skip if already ISO 8601 |
232 | { |
|
222 | if (DateTime.TryParseExact(time, |
233 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
|
223 | "yyyy-MM-ddTHH:mm:ss.fff", |
234 | { |
|
Line 224... | Line -... | |||
224 | CultureInfo.InvariantCulture, |
- | ||
225 | DateTimeStyles.None, out _)) |
- | ||
226 | { |
- | ||
227 | continue; |
235 | var time = (string)sqlDataReader["Time"]; |
|
228 | } |
236 | |
|
229 | |
- | ||
230 | if (!DateTime.TryParse(time, out var dateTime)) |
237 | // Skip if already ISO 8601 |
|
231 | { |
238 | if (DateTime.TryParseExact(time, |
|
Line -... | Line 239... | |||
- | 239 | "yyyy-MM-ddTHH:mm:ss.fff", |
||
- | 240 | CultureInfo.InvariantCulture, |
||
- | 241 | DateTimeStyles.None, out _)) |
||
232 | dateTime = DateTime.Now; |
242 | { |
|
- | 243 | continue; |
||
- | 244 | } |
||
- | 245 | |
||
- | 246 | if (!DateTime.TryParse(time, out var dateTime)) |
||
- | 247 | { |
||
Line -... | Line 248... | |||
- | 248 | dateTime = DateTime.Now; |
||
- | 249 | } |
||
233 | } |
250 | |
|
- | 251 | using (var writeSQLiteCommand = |
||
234 | |
252 | new SQLiteCommand(UpdateTimeFromHash, sqliteConnection, dbTransaction)) |
|
235 | using (var writeSQLiteCommand = |
- | ||
Line 236... | Line 253... | |||
236 | new SQLiteCommand(UpdateTimeFromHash, sqliteConnection, dbTransaction)) |
253 | { |
|
237 | { |
254 | writeSQLiteCommand.Parameters.AddRange(new[] |
|
238 | writeSQLiteCommand.Parameters.AddRange(new[] |
255 | { |
|
239 | { |
256 | new SQLiteParameter("@time", |
|
240 | new SQLiteParameter("@time", dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")), |
257 | dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")), |
|
Line 241... | Line 258... | |||
241 | new SQLiteParameter("@hash", hash) |
258 | new SQLiteParameter("@hash", hash) |
|
- | 259 | }); |
||
242 | }); |
260 | |
|
243 | |
261 | writeSQLiteCommand.Prepare(); |
|
244 | writeSQLiteCommand.Prepare(); |
262 | |
|
245 | |
263 | await writeSQLiteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
246 | await writeSQLiteCommand.ExecuteNonQueryAsync(cancellationToken); |
264 | } |
|
- | 265 | } |
||
- | 266 | |
||
- | 267 | dbTransaction.Commit(); |
||
- | 268 | } |
||
247 | } |
269 | catch |
|
Line 248... | Line 270... | |||
248 | } |
270 | { |
|
249 | |
271 | dbTransaction.Rollback(); |
|
250 | dbTransaction.Commit(); |
272 | |
|
251 | } |
273 | throw; |
|
252 | catch |
274 | } |
|
253 | { |
275 | } |
|
Line 254... | Line 276... | |||
254 | dbTransaction.Rollback(); |
276 | } |
|
- | 277 | } |
||
255 | |
278 | } |
|
256 | throw; |
- | ||
257 | } |
- | ||
258 | } |
- | ||
259 | } |
279 | } |
|
260 | } |
280 | finally |
|
261 | } |
- | ||
262 | } |
- | ||
263 | |
281 | { |
|
Line -... | Line 282... | |||
- | 282 | _databaseLock.Release(); |
||
264 | public async Task<long> CountSnapshots(CancellationToken cancellationToken) |
283 | } |
|
265 | { |
284 | } |
|
- | 285 | |
||
- | 286 | public async Task<long> CountSnapshots(CancellationToken cancellationToken) |
||
- | 287 | { |
||
- | 288 | var connectionString = new SQLiteConnectionStringBuilder |
||
266 | var connectionString = new SQLiteConnectionStringBuilder |
289 | { |
|
267 | { |
290 | ConnectionString = DatabaseConnectionString |
|
268 | ConnectionString = DatabaseConnectionString |
291 | }; |
|
269 | }; |
292 | |
|
- | 293 | await _databaseLock.WaitAsync(cancellationToken); |
||
- | 294 | try |
||
270 | |
295 | { |
|
271 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
296 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
- | 297 | { |
||
- | 298 | await sqliteConnection.OpenAsync(cancellationToken); |
||
- | 299 | |
||
272 | { |
300 | // Insert the file change. |
|
Line 273... | Line 301... | |||
273 | await sqliteConnection.OpenAsync(cancellationToken); |
301 | using (var sqliteCommand = new SQLiteCommand(CountSnapshotsSql, sqliteConnection)) |
|
274 | |
302 | { |
|
275 | // Insert the file change. |
- | ||
276 | using (var sqliteCommand = new SQLiteCommand(CountSnapshotsSql, sqliteConnection)) |
- | ||
277 | { |
303 | long count = 0; |
|
278 | long count = 0; |
304 | |
|
279 | |
305 | sqliteCommand.Prepare(); |
|
- | 306 | |
||
- | 307 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
||
- | 308 | { |
||
- | 309 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
||
280 | sqliteCommand.Prepare(); |
310 | { |
|
Line 281... | Line 311... | |||
281 | |
311 | if (!(sqlDataReader[0] is long dbCount)) |
|
282 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
312 | { |
|
283 | { |
313 | count = -1; |
|
284 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
314 | break; |
|
285 | { |
315 | } |
|
286 | if (!(sqlDataReader[0] is long dbCount)) |
316 | |
|
Line 287... | Line 317... | |||
287 | { |
317 | count = dbCount; |
|
288 | count = -1; |
318 | } |
|
289 | break; |
319 | |
|
290 | } |
- | ||
291 | |
- | ||
292 | count = dbCount; |
320 | return count; |
|
293 | } |
321 | } |
|
294 | |
322 | } |
|
295 | return count; |
323 | } |
|
Line -... | Line 324... | |||
- | 324 | } |
||
296 | } |
325 | finally |
|
297 | } |
326 | { |
|
298 | } |
- | ||
299 | } |
- | ||
300 | |
- | ||
301 | public async Task<IEnumerable<Snapshot>> LoadSnapshots(CancellationToken cancellationToken) |
- | ||
302 | { |
- | ||
303 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
304 | { |
- | ||
305 | ConnectionString = DatabaseConnectionString |
- | ||
306 | }; |
327 | _databaseLock.Release(); |
|
Line -... | Line 328... | |||
- | 328 | } |
||
- | 329 | } |
||
- | 330 | |
||
307 | |
331 | public async IAsyncEnumerable<Snapshot> LoadSnapshots([EnumeratorCancellation] CancellationToken cancellationToken) |
|
308 | using (var sqliteConnection = |
332 | { |
|
- | 333 | var connectionString = new SQLiteConnectionStringBuilder |
||
- | 334 | { |
||
- | 335 | ConnectionString = DatabaseConnectionString |
||
309 | new SQLiteConnection(connectionString.ConnectionString)) |
336 | }; |
|
Line 310... | Line 337... | |||
310 | { |
337 | |
|
- | 338 | await _databaseLock.WaitAsync(cancellationToken); |
||
- | 339 | try |
||
311 | await sqliteConnection.OpenAsync(cancellationToken); |
340 | { |
|
- | 341 | using (var sqliteConnection = |
||
- | 342 | new SQLiteConnection(connectionString.ConnectionString)) |
||
- | 343 | { |
||
- | 344 | await sqliteConnection.OpenAsync(cancellationToken); |
||
312 | |
345 | |
|
313 | // Insert the file change. |
346 | // Insert the file change. |
|
314 | using (var sqliteCommand = new SQLiteCommand(RetrieveSnapshotsSql, sqliteConnection)) |
347 | using (var sqliteCommand = new SQLiteCommand(RetrieveSnapshotsSql, sqliteConnection)) |
|
315 | { |
348 | { |
|
316 | sqliteCommand.Prepare(); |
349 | sqliteCommand.Prepare(); |
|
317 | |
350 | |
|
- | 351 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
||
318 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
352 | { |
|
319 | { |
- | ||
Line 320... | Line 353... | |||
320 | var snapshots = new List<Snapshot>(); |
353 | //var snapshots = new List<Snapshot>(); |
|
- | 354 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
||
321 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
355 | { |
|
322 | { |
- | ||
323 | var name = (string)sqlDataReader["Name"]; |
- | ||
324 | var path = (string)sqlDataReader["Path"]; |
356 | var name = (string)sqlDataReader["Name"]; |
|
325 | var time = (string)sqlDataReader["Time"]; |
357 | var path = (string)sqlDataReader["Path"]; |
|
326 | var hash = (string)sqlDataReader["Hash"]; |
358 | var time = (string)sqlDataReader["Time"]; |
|
- | 359 | var hash = (string)sqlDataReader["Hash"]; |
||
- | 360 | |
||
- | 361 | var color = Color.Empty; |
||
- | 362 | |
||
327 | |
363 | if (!(sqlDataReader["Color"] is DBNull)) |
|
Line 328... | Line 364... | |||
328 | var color = Color.Empty; |
364 | { |
|
329 | |
365 | var dbColor = Convert.ToInt32(sqlDataReader["Color"]); |
|
330 | if (!(sqlDataReader["Color"] is DBNull)) |
- | ||
331 | { |
- | ||
332 | var dbColor = Convert.ToInt32(sqlDataReader["Color"]); |
366 | |
|
333 | |
367 | switch (dbColor) |
|
334 | switch (dbColor) |
368 | { |
|
335 | { |
369 | case 0: |
|
Line 336... | Line 370... | |||
336 | case 0: |
370 | color = Color.Empty; |
|
337 | color = Color.Empty; |
371 | break; |
|
338 | break; |
372 | default: |
|
339 | default: |
373 | color = Color.FromArgb(dbColor); |
|
340 | color = Color.FromArgb(dbColor); |
- | ||
341 | break; |
374 | break; |
|
342 | } |
375 | } |
|
343 | } |
376 | } |
|
- | 377 | |
||
- | 378 | yield return new Snapshot(name, path, time, hash, color); |
||
344 | |
379 | } |
|
345 | snapshots.Add(new Snapshot(name, path, time, hash, color)); |
380 | } |
|
346 | } |
381 | } |
|
347 | |
382 | } |
|
348 | return snapshots; |
383 | } |
|
349 | } |
384 | finally |
|
350 | } |
- | ||
351 | } |
- | ||
352 | } |
- | ||
353 | |
385 | { |
|
- | 386 | _databaseLock.Release(); |
||
- | 387 | } |
||
- | 388 | } |
||
- | 389 | |
||
- | 390 | public async Task CreateSnapshot(string name, string path, Color color, CancellationToken cancellationToken) |
||
354 | public async Task CreateSnapshot(string name, string path, Color color, CancellationToken cancellationToken) |
391 | { |
|
355 | { |
392 | var connectionString = new SQLiteConnectionStringBuilder |
|
Line 356... | Line 393... | |||
356 | await _snapshotSemaphore.WaitAsync(cancellationToken); |
393 | { |
|
357 | |
394 | ConnectionString = DatabaseConnectionString |
|
358 | var connectionString = new SQLiteConnectionStringBuilder |
395 | }; |
|
359 | { |
396 | |
|
Line 360... | Line 397... | |||
360 | ConnectionString = DatabaseConnectionString |
397 | await _databaseLock.WaitAsync(cancellationToken); |
|
361 | }; |
- | ||
362 | |
- | ||
363 | using (var sqliteConnection = |
- | ||
364 | new SQLiteConnection(connectionString.ConnectionString)) |
398 | try |
|
365 | { |
- | ||
366 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
367 | |
- | ||
368 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
- | ||
369 | { |
- | ||
370 | try |
- | ||
371 | { |
- | ||
372 | using (var md5 = MD5.Create()) |
- | ||
373 | { |
- | ||
374 | using (var hashMemoryStream = new MemoryStream()) |
399 | { |
|
375 | { |
400 | using (var sqliteConnection = |
|
376 | using (var fileStream = |
- | ||
377 | await Miscellaneous.GetFileStream(path, FileMode.Open, FileAccess.Read, |
401 | new SQLiteConnection(connectionString.ConnectionString)) |
|
- | 402 | { |
||
- | 403 | await sqliteConnection.OpenAsync(cancellationToken); |
||
- | 404 | |
||
- | 405 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
||
- | 406 | { |
||
- | 407 | try |
||
378 | FileShare.Read, |
408 | { |
|
- | 409 | using (var md5 = MD5.Create()) |
||
- | 410 | { |
||
- | 411 | using (var hashMemoryStream = new MemoryStream()) |
||
- | 412 | { |
||
- | 413 | using (var fileStream = |
||
379 | cancellationToken)) |
414 | await Miscellaneous.GetFileStream(path, FileMode.Open, FileAccess.Read, |
|
- | 415 | FileShare.Read, |
||
- | 416 | cancellationToken)) |
||
380 | { |
417 | { |
|
381 | fileStream.Position = 0L; |
418 | fileStream.Position = 0L; |
|
382 | await fileStream.CopyToAsync(hashMemoryStream); |
419 | await fileStream.CopyToAsync(hashMemoryStream); |
|
383 | |
420 | |
|
384 | hashMemoryStream.Position = 0L; |
421 | hashMemoryStream.Position = 0L; |
|
385 | var hash = md5.ComputeHash(hashMemoryStream); |
422 | var hash = md5.ComputeHash(hashMemoryStream); |
|
386 | var hashHex = BitConverter.ToString(hash).Replace("-", "") |
423 | var hashHex = BitConverter.ToString(hash).Replace("-", "") |
|
Line 387... | Line 424... | |||
387 | .ToLowerInvariant(); |
424 | .ToLowerInvariant(); |
|
388 | |
425 | |
|
389 | using (var fileMemoryStream = new MemoryStream()) |
426 | using (var fileMemoryStream = new MemoryStream()) |
|
390 | { |
427 | { |
|
391 | using (var fileZipStream = |
428 | using (var fileZipStream = |
|
392 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
429 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
|
393 | { |
430 | { |
|
394 | fileStream.Position = 0L; |
431 | fileStream.Position = 0L; |
|
395 | await fileStream.CopyToAsync(fileZipStream); |
432 | await fileStream.CopyToAsync(fileZipStream); |
|
396 | fileZipStream.Close(); |
433 | fileZipStream.Close(); |
|
397 | |
434 | |
|
398 | var time = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff"); |
435 | var time = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff"); |
|
Line 399... | Line 436... | |||
399 | |
436 | |
|
Line 400... | Line 437... | |||
400 | fileMemoryStream.Position = 0L; |
437 | fileMemoryStream.Position = 0L; |
|
401 | |
438 | |
|
Line 402... | Line 439... | |||
402 | // Insert the file change. |
439 | // Insert the file change. |
|
403 | using (var sqliteCommand = |
440 | using (var sqliteCommand = |
|
404 | new SQLiteCommand(SnapshotFileNoScreenshotSql, sqliteConnection, |
441 | new SQLiteCommand(SnapshotFileNoScreenshotSql, sqliteConnection, |
|
405 | dbTransaction)) |
442 | dbTransaction)) |
|
406 | { |
443 | { |
|
407 | sqliteCommand.Parameters.AddRange(new[] |
444 | sqliteCommand.Parameters.AddRange(new[] |
|
Line 408... | Line 445... | |||
408 | { |
445 | { |
|
409 | new SQLiteParameter("@name", name), |
446 | new SQLiteParameter("@name", name), |
|
Line 410... | Line 447... | |||
410 | new SQLiteParameter("@time", time), |
447 | new SQLiteParameter("@time", time), |
|
411 | new SQLiteParameter("@path", path), |
448 | new SQLiteParameter("@path", path), |
|
- | 449 | new SQLiteParameter("@dataLength", |
||
412 | new SQLiteParameter("@dataLength", |
450 | fileMemoryStream.Length), |
|
413 | fileMemoryStream.Length), |
451 | new SQLiteParameter("@hash", hashHex) |
|
414 | new SQLiteParameter("@hash", hashHex) |
452 | }); |
|
415 | }); |
453 | |
|
Line 416... | Line 454... | |||
416 | |
454 | var numeric = color.ToArgb(); |
|
- | 455 | switch (numeric) |
||
417 | var numeric = color.ToArgb(); |
456 | { |
|
- | 457 | case 0: |
||
418 | switch (numeric) |
458 | sqliteCommand.Parameters.Add( |
|
419 | { |
- | ||
Line 420... | Line 459... | |||
420 | case 0: |
459 | new SQLiteParameter("@color", null)); |
|
Line 421... | Line 460... | |||
421 | sqliteCommand.Parameters.Add( |
460 | break; |
|
422 | new SQLiteParameter("@color", null)); |
461 | default: |
|
423 | break; |
462 | sqliteCommand.Parameters.Add( |
|
- | 463 | new SQLiteParameter("@color", numeric)); |
||
424 | default: |
464 | break; |
|
425 | sqliteCommand.Parameters.Add( |
465 | } |
|
426 | new SQLiteParameter("@color", numeric)); |
466 | |
|
427 | break; |
467 | sqliteCommand.Prepare(); |
|
428 | } |
468 | |
|
429 | |
- | ||
430 | sqliteCommand.Prepare(); |
469 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
431 | |
470 | } |
|
432 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
471 | |
|
Line 433... | Line 472... | |||
433 | } |
472 | // Insert the data blobs. |
|
- | 473 | using (var sqliteCommand = |
||
- | 474 | new SQLiteCommand(GetLastRowInsertSql, sqliteConnection, |
||
- | 475 | dbTransaction)) |
||
- | 476 | { |
||
- | 477 | sqliteCommand.Prepare(); |
||
- | 478 | |
||
- | 479 | var rowId = |
||
- | 480 | (long)await sqliteCommand.ExecuteScalarAsync(cancellationToken); |
||
434 | |
481 | |
|
- | 482 | using (var sqliteBlob = |
||
- | 483 | SQLiteBlob.Create(sqliteConnection, "main", "Snapshots", |
||
435 | // Insert the data blobs. |
484 | "Data", |
|
436 | using (var sqliteCommand = |
485 | rowId, |
|
437 | new SQLiteCommand(GetLastRowInsertSql, sqliteConnection, |
- | ||
438 | dbTransaction)) |
- | ||
439 | { |
- | ||
440 | sqliteCommand.Prepare(); |
- | ||
441 | |
- | ||
442 | var rowId = |
- | ||
443 | (long)await sqliteCommand.ExecuteScalarAsync(cancellationToken); |
- | ||
444 | |
- | ||
445 | using (var sqliteBlob = |
- | ||
Line 446... | Line 486... | |||
446 | SQLiteBlob.Create(sqliteConnection, "main", "Snapshots", "Data", |
486 | false)) |
|
447 | rowId, |
487 | { |
|
448 | false)) |
- | ||
449 | { |
- | ||
450 | var fileMemoryStreamData = fileMemoryStream.ToArray(); |
- | ||
451 | |
488 | var fileMemoryStreamData = fileMemoryStream.ToArray(); |
|
452 | sqliteBlob.Write(fileMemoryStreamData, fileMemoryStreamData.Length, |
489 | |
|
453 | 0); |
490 | sqliteBlob.Write(fileMemoryStreamData, |
|
- | 491 | fileMemoryStreamData.Length, |
||
- | 492 | 0); |
||
- | 493 | } |
||
- | 494 | } |
||
454 | } |
495 | |
|
Line 455... | Line 496... | |||
455 | } |
496 | dbTransaction.Commit(); |
|
456 | |
497 | |
|
457 | dbTransaction.Commit(); |
498 | SnapshotCreate?.Invoke(this, |
|
458 | |
- | ||
459 | SnapshotCreate?.Invoke(this, |
- | ||
460 | new SnapshotCreateSuccessEventArgs(name, time, path, color, |
499 | new SnapshotCreateSuccessEventArgs(name, time, path, color, |
|
461 | hashHex)); |
500 | hashHex)); |
|
462 | } |
501 | } |
|
463 | } |
502 | } |
|
Line 464... | Line 503... | |||
464 | } |
503 | } |
|
465 | } |
504 | } |
|
466 | } |
505 | } |
|
467 | } |
506 | } |
|
468 | catch (SQLiteException exception) |
- | ||
469 | { |
507 | catch (SQLiteException exception) |
|
470 | dbTransaction.Rollback(); |
508 | { |
|
471 | |
509 | dbTransaction.Rollback(); |
|
- | 510 | |
||
- | 511 | if (exception.ResultCode != SQLiteErrorCode.Constraint) |
||
472 | if (exception.ResultCode != SQLiteErrorCode.Constraint) |
512 | { |
|
473 | { |
513 | SnapshotCreate?.Invoke(this, |
|
474 | SnapshotCreate?.Invoke(this, |
514 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
|
475 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
515 | } |
|
476 | } |
516 | |
|
477 | |
517 | throw; |
|
478 | throw; |
- | ||
479 | } |
- | ||
480 | catch (Exception exception) |
- | ||
481 | { |
518 | } |
|
- | 519 | catch (Exception exception) |
||
- | 520 | { |
||
- | 521 | dbTransaction.Rollback(); |
||
- | 522 | |
||
- | 523 | SnapshotCreate?.Invoke(this, |
||
482 | dbTransaction.Rollback(); |
524 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
|
483 | |
525 | |
|
Line 484... | Line 526... | |||
484 | SnapshotCreate?.Invoke(this, new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
526 | throw; |
|
485 | |
527 | } |
|
486 | throw; |
528 | } |
|
487 | } |
529 | } |
|
Line 488... | Line 530... | |||
488 | finally |
530 | } |
|
489 | { |
- | ||
490 | _snapshotSemaphore.Release(); |
- | ||
491 | } |
- | ||
492 | } |
531 | finally |
|
493 | } |
- | ||
494 | } |
- | ||
495 | |
532 | { |
|
496 | public async Task CreateSnapshot(string name, string path, |
- | ||
497 | Bitmap shot, Color color, CancellationToken cancellationToken) |
533 | _databaseLock.Release(); |
|
498 | { |
534 | } |
|
499 | await _snapshotSemaphore.WaitAsync(cancellationToken); |
- | ||
500 | |
- | ||
501 | var connectionString = new SQLiteConnectionStringBuilder |
535 | } |
|
502 | { |
- | ||
503 | ConnectionString = DatabaseConnectionString |
536 | |
|
504 | }; |
537 | public async Task CreateSnapshot(string name, string path, |
|
Line -... | Line 538... | |||
- | 538 | Bitmap shot, Color color, CancellationToken cancellationToken) |
||
- | 539 | { |
||
- | 540 | var connectionString = new SQLiteConnectionStringBuilder |
||
- | 541 | { |
||
- | 542 | ConnectionString = DatabaseConnectionString |
||
- | 543 | }; |
||
505 | |
544 | |
|
- | 545 | await _databaseLock.WaitAsync(cancellationToken); |
||
Line 506... | Line -... | |||
506 | using (var sqliteConnection = |
- | ||
507 | new SQLiteConnection(connectionString.ConnectionString)) |
546 | try |
|
Line 508... | Line -... | |||
508 | { |
- | ||
509 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
510 | |
- | ||
511 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
547 | { |
|
512 | { |
- | ||
513 | try |
- | ||
514 | { |
- | ||
515 | using (var md5 = MD5.Create()) |
- | ||
516 | { |
- | ||
517 | using (var hashMemoryStream = new MemoryStream()) |
- | ||
518 | { |
- | ||
519 | using (var fileStream = |
548 | using (var sqliteConnection = |
|
520 | await Miscellaneous.GetFileStream(path, FileMode.Open, FileAccess.Read, |
- | ||
521 | FileShare.Read, |
- | ||
522 | cancellationToken)) |
- | ||
523 | { |
- | ||
Line 524... | Line 549... | |||
524 | fileStream.Position = 0L; |
549 | new SQLiteConnection(connectionString.ConnectionString)) |
|
- | 550 | { |
||
- | 551 | await sqliteConnection.OpenAsync(cancellationToken); |
||
525 | await fileStream.CopyToAsync(hashMemoryStream); |
552 | |
|
526 | |
553 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
- | 554 | { |
||
527 | hashMemoryStream.Position = 0L; |
555 | try |
|
528 | var hash = md5.ComputeHash(hashMemoryStream); |
556 | { |
|
529 | var hashHex = BitConverter.ToString(hash).Replace("-", "") |
557 | using (var md5 = MD5.Create()) |
|
530 | .ToLowerInvariant(); |
558 | { |
|
531 | |
559 | using (var hashMemoryStream = new MemoryStream()) |
|
532 | using (var fileMemoryStream = new MemoryStream()) |
560 | { |
|
533 | { |
561 | using (var fileStream = |
|
534 | using (var fileZipStream = |
562 | await Miscellaneous.GetFileStream(path, FileMode.Open, FileAccess.Read, |
|
- | 563 | FileShare.Read, |
||
535 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
564 | cancellationToken)) |
|
Line -... | Line 565... | |||
- | 565 | { |
||
- | 566 | fileStream.Position = 0L; |
||
- | 567 | await fileStream.CopyToAsync(hashMemoryStream); |
||
- | 568 | |
||
- | 569 | hashMemoryStream.Position = 0L; |
||
- | 570 | var hash = md5.ComputeHash(hashMemoryStream); |
||
536 | { |
571 | var hashHex = BitConverter.ToString(hash).Replace("-", "") |
|
- | 572 | .ToLowerInvariant(); |
||
- | 573 | |
||
- | 574 | using (var fileMemoryStream = new MemoryStream()) |
||
- | 575 | { |
||
- | 576 | using (var fileZipStream = |
||
Line 537... | Line 577... | |||
537 | fileStream.Position = 0L; |
577 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
|
538 | await fileStream.CopyToAsync(fileZipStream); |
- | ||
Line 539... | Line -... | |||
539 | fileZipStream.Close(); |
- | ||
540 | |
- | ||
541 | using (var bitmapMemoryStream = new MemoryStream()) |
578 | { |
|
542 | { |
- | ||
543 | using (var bitmapZipStream = |
579 | fileStream.Position = 0L; |
|
544 | new GZipStream(bitmapMemoryStream, CompressionMode.Compress, |
- | ||
Line 545... | Line -... | |||
545 | true)) |
- | ||
546 | { |
- | ||
547 | shot.Save(bitmapZipStream, ImageFormat.Bmp); |
580 | await fileStream.CopyToAsync(fileZipStream); |
|
548 | bitmapZipStream.Close(); |
- | ||
549 | |
581 | fileZipStream.Close(); |
|
550 | var time = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff"); |
582 | |
|
551 | |
- | ||
552 | fileMemoryStream.Position = 0L; |
- | ||
553 | bitmapMemoryStream.Position = 0L; |
583 | using (var bitmapMemoryStream = new MemoryStream()) |
|
554 | |
584 | { |
|
555 | // Insert the file change. |
585 | using (var bitmapZipStream = |
|
Line 556... | Line 586... | |||
556 | using (var sqliteCommand = |
586 | new GZipStream(bitmapMemoryStream, CompressionMode.Compress, |
|
557 | new SQLiteCommand(SnapshotFileSql, sqliteConnection, |
587 | true)) |
|
558 | dbTransaction)) |
588 | { |
|
559 | { |
- | ||
Line 560... | Line 589... | |||
560 | sqliteCommand.Parameters.AddRange(new[] |
589 | shot.Save(bitmapZipStream, ImageFormat.Bmp); |
|
561 | { |
590 | bitmapZipStream.Close(); |
|
- | 591 | |
||
562 | new SQLiteParameter("@name", name), |
592 | var time = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff"); |
|
563 | new SQLiteParameter("@time", time), |
593 | |
|
564 | new SQLiteParameter("@path", path), |
594 | fileMemoryStream.Position = 0L; |
|
565 | new SQLiteParameter("@shotLength", |
595 | bitmapMemoryStream.Position = 0L; |
|
566 | bitmapMemoryStream.Length), |
596 | |
|
Line -... | Line 597... | |||
- | 597 | // Insert the file change. |
||
- | 598 | using (var sqliteCommand = |
||
- | 599 | new SQLiteCommand(SnapshotFileSql, sqliteConnection, |
||
- | 600 | dbTransaction)) |
||
- | 601 | { |
||
- | 602 | sqliteCommand.Parameters.AddRange(new[] |
||
- | 603 | { |
||
- | 604 | new SQLiteParameter("@name", name), |
||
- | 605 | new SQLiteParameter("@time", time), |
||
- | 606 | new SQLiteParameter("@path", path), |
||
- | 607 | new SQLiteParameter("@shotLength", |
||
- | 608 | bitmapMemoryStream.Length), |
||
- | 609 | new SQLiteParameter("@dataLength", |
||
- | 610 | fileMemoryStream.Length), |
||
- | 611 | new SQLiteParameter("@hash", hashHex) |
||
567 | new SQLiteParameter("@dataLength", |
612 | }); |
|
568 | fileMemoryStream.Length), |
613 | |
|
569 | new SQLiteParameter("@hash", hashHex) |
614 | var numeric = color.ToArgb(); |
|
- | 615 | switch (numeric) |
||
570 | }); |
616 | { |
|
571 | |
- | ||
Line 572... | Line 617... | |||
572 | var numeric = color.ToArgb(); |
617 | case 0: |
|
Line 573... | Line 618... | |||
573 | switch (numeric) |
618 | sqliteCommand.Parameters.Add( |
|
574 | { |
619 | new SQLiteParameter("@color", null)); |
|
575 | case 0: |
620 | break; |
|
- | 621 | default: |
||
576 | sqliteCommand.Parameters.Add( |
622 | sqliteCommand.Parameters.Add( |
|
577 | new SQLiteParameter("@color", null)); |
623 | new SQLiteParameter("@color", numeric)); |
|
578 | break; |
624 | break; |
|
579 | default: |
625 | } |
|
580 | sqliteCommand.Parameters.Add( |
626 | |
|
581 | new SQLiteParameter("@color", numeric)); |
627 | sqliteCommand.Prepare(); |
|
582 | break; |
628 | |
|
- | 629 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
||
583 | } |
630 | } |
|
584 | |
631 | |
|
- | 632 | // Insert the data blobs. |
||
- | 633 | using (var sqliteCommand = |
||
585 | sqliteCommand.Prepare(); |
634 | new SQLiteCommand(GetLastRowInsertSql, sqliteConnection, |
|
586 | |
635 | dbTransaction)) |
|
- | 636 | { |
||
- | 637 | sqliteCommand.Prepare(); |
||
Line -... | Line 638... | |||
- | 638 | |
||
- | 639 | var rowId = |
||
587 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
640 | (long)await sqliteCommand.ExecuteScalarAsync( |
|
588 | } |
641 | cancellationToken); |
|
- | 642 | |
||
- | 643 | using (var sqliteBlob = |
||
589 | |
644 | SQLiteBlob.Create(sqliteConnection, "main", |
|
590 | // Insert the data blobs. |
645 | "Snapshots", |
|
591 | using (var sqliteCommand = |
- | ||
592 | new SQLiteCommand(GetLastRowInsertSql, sqliteConnection, |
- | ||
593 | dbTransaction)) |
- | ||
594 | { |
- | ||
595 | sqliteCommand.Prepare(); |
- | ||
596 | |
- | ||
597 | var rowId = |
- | ||
Line 598... | Line -... | |||
598 | (long)await sqliteCommand.ExecuteScalarAsync( |
- | ||
599 | cancellationToken); |
- | ||
600 | |
646 | "Data", |
|
601 | using (var sqliteBlob = |
647 | rowId, |
|
602 | SQLiteBlob.Create(sqliteConnection, "main", "Snapshots", |
- | ||
603 | "Data", |
- | ||
604 | rowId, |
- | ||
605 | false)) |
648 | false)) |
|
606 | { |
649 | { |
|
607 | var fileMemoryStreamData = fileMemoryStream.ToArray(); |
650 | var fileMemoryStreamData = fileMemoryStream.ToArray(); |
|
- | 651 | |
||
- | 652 | sqliteBlob.Write(fileMemoryStreamData, |
||
- | 653 | fileMemoryStreamData.Length, |
||
- | 654 | 0); |
||
608 | |
655 | } |
|
Line 609... | Line 656... | |||
609 | sqliteBlob.Write(fileMemoryStreamData, |
656 | |
|
610 | fileMemoryStreamData.Length, |
657 | using (var sqliteBlob = |
|
611 | 0); |
658 | SQLiteBlob.Create(sqliteConnection, "main", |
|
612 | } |
659 | "Snapshots", |
|
613 | |
660 | "Shot", |
|
614 | using (var sqliteBlob = |
661 | rowId, |
|
Line 615... | Line 662... | |||
615 | SQLiteBlob.Create(sqliteConnection, "main", "Snapshots", |
662 | false)) |
|
- | 663 | { |
||
616 | "Shot", |
664 | var bitmapMemoryStreamData = |
|
617 | rowId, |
665 | bitmapMemoryStream.ToArray(); |
|
618 | false)) |
- | ||
619 | { |
- | ||
620 | var bitmapMemoryStreamData = bitmapMemoryStream.ToArray(); |
- | ||
621 | |
- | ||
622 | sqliteBlob.Write(bitmapMemoryStreamData, |
666 | |
|
623 | bitmapMemoryStreamData.Length, |
667 | sqliteBlob.Write(bitmapMemoryStreamData, |
|
624 | 0); |
- | ||
625 | } |
- | ||
626 | } |
- | ||
627 | |
- | ||
628 | dbTransaction.Commit(); |
- | ||
Line -... | Line 668... | |||
- | 668 | bitmapMemoryStreamData.Length, |
||
- | 669 | 0); |
||
629 | |
670 | } |
|
630 | SnapshotCreate?.Invoke(this, |
671 | } |
|
631 | new SnapshotCreateSuccessEventArgs(name, time, path, color, |
672 | |
|
632 | hashHex)); |
673 | dbTransaction.Commit(); |
|
633 | } |
674 | |
|
634 | } |
675 | SnapshotCreate?.Invoke(this, |
|
Line 635... | Line -... | |||
635 | } |
- | ||
636 | } |
- | ||
637 | } |
676 | new SnapshotCreateSuccessEventArgs(name, time, path, color, |
|
638 | } |
- | ||
Line -... | Line 677... | |||
- | 677 | hashHex)); |
||
- | 678 | } |
||
639 | } |
679 | } |
|
640 | } |
680 | } |
|
641 | catch (SQLiteException exception) |
681 | } |
|
642 | { |
- | ||
643 | dbTransaction.Rollback(); |
682 | } |
|
- | 683 | } |
||
644 | |
684 | } |
|
645 | if (exception.ResultCode != SQLiteErrorCode.Constraint) |
685 | } |
|
646 | { |
686 | catch (SQLiteException exception) |
|
- | 687 | { |
||
Line 647... | Line 688... | |||
647 | SnapshotCreate?.Invoke(this, |
688 | dbTransaction.Rollback(); |
|
- | 689 | |
||
- | 690 | if (exception.ResultCode != SQLiteErrorCode.Constraint) |
||
- | 691 | { |
||
- | 692 | SnapshotCreate?.Invoke(this, |
||
- | 693 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
||
648 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
694 | } |
|
- | 695 | |
||
- | 696 | throw; |
||
- | 697 | } |
||
- | 698 | catch (Exception exception) |
||
649 | } |
699 | { |
|
- | 700 | dbTransaction.Rollback(); |
||
650 | |
701 | |
|
651 | throw; |
702 | SnapshotCreate?.Invoke(this, |
|
652 | } |
703 | new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
|
653 | catch (Exception exception) |
704 | |
|
654 | { |
705 | throw; |
|
655 | dbTransaction.Rollback(); |
706 | } |
|
656 | |
707 | } |
|
- | 708 | } |
||
- | 709 | } |
||
- | 710 | finally |
||
- | 711 | { |
||
657 | SnapshotCreate?.Invoke(this, new SnapshotCreateFailureEventArgs(name, path, color, exception)); |
712 | _databaseLock.Release(); |
|
Line 658... | Line 713... | |||
658 | |
713 | } |
|
659 | throw; |
714 | } |
|
660 | } |
- | ||
661 | finally |
- | ||
662 | { |
715 | |
|
663 | _snapshotSemaphore.Release(); |
716 | public async Task SaveFile(string path, string hash, CancellationToken cancellationToken) |
|
664 | } |
717 | { |
|
665 | } |
718 | var connectionString = new SQLiteConnectionStringBuilder |
|
Line 666... | Line 719... | |||
666 | } |
719 | { |
|
- | 720 | ConnectionString = DatabaseConnectionString |
||
667 | } |
721 | }; |
|
668 | |
722 | |
|
669 | public async Task SaveFile(string path, string hash, CancellationToken cancellationToken) |
- | ||
670 | { |
- | ||
671 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
672 | { |
- | ||
673 | ConnectionString = DatabaseConnectionString |
723 | await _databaseLock.WaitAsync(cancellationToken); |
|
- | 724 | try |
||
- | 725 | { |
||
- | 726 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
||
674 | }; |
727 | { |
|
- | 728 | await sqliteConnection.OpenAsync(cancellationToken); |
||
675 | |
729 | |
|
676 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
730 | // Insert the file change. |
|
677 | { |
731 | using (var sqliteCommand = |
|
- | 732 | new SQLiteCommand(RetrieveDataPathFromHashSql, sqliteConnection)) |
||
- | 733 | { |
||
678 | await sqliteConnection.OpenAsync(cancellationToken); |
734 | sqliteCommand.Parameters.AddRange(new[] |
|
679 | |
735 | { |
|
Line 680... | Line 736... | |||
680 | // Insert the file change. |
736 | new SQLiteParameter("@hash", hash) |
|
Line 681... | Line 737... | |||
681 | using (var sqliteCommand = |
737 | }); |
|
682 | new SQLiteCommand(RetrieveDataPathFromHashSql, sqliteConnection)) |
- | ||
683 | { |
- | ||
684 | sqliteCommand.Parameters.AddRange(new[] |
738 | |
|
- | 739 | sqliteCommand.Prepare(); |
||
- | 740 | |
||
685 | { |
741 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
|
Line 686... | Line 742... | |||
686 | new SQLiteParameter("@hash", hash) |
742 | { |
|
687 | }); |
743 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
|
Line 688... | Line 744... | |||
688 | |
744 | { |
|
689 | sqliteCommand.Prepare(); |
745 | // Create directories if they do not exist. |
|
690 | |
746 | var dir = Path.GetDirectoryName(path); |
|
691 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
747 | |
|
Line 692... | Line 748... | |||
692 | { |
748 | if (dir != null && !Directory.Exists(dir)) |
|
693 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
749 | { |
|
694 | { |
750 | Directory.CreateDirectory(dir); |
|
695 | // Create directories if they do not exist. |
751 | } |
|
696 | var dir = Path.GetDirectoryName(path); |
752 | |
|
697 | |
753 | using (var readStream = sqlDataReader.GetStream(2)) |
|
Line 698... | Line 754... | |||
698 | if (dir != null && !Directory.Exists(dir)) |
754 | { |
|
699 | { |
- | ||
700 | Directory.CreateDirectory(dir); |
- | ||
701 | } |
- | ||
702 | |
- | ||
703 | using (var readStream = sqlDataReader.GetStream(2)) |
755 | using (var fileStream = |
|
- | 756 | await Miscellaneous.GetFileStream(path, FileMode.Create, FileAccess.Write, |
||
704 | { |
757 | FileShare.Write, |
|
705 | using (var fileStream = |
758 | cancellationToken)) |
|
706 | await Miscellaneous.GetFileStream(path, FileMode.Create, FileAccess.Write, |
759 | { |
|
- | 760 | readStream.Position = 0L; |
||
- | 761 | |
||
- | 762 | using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress)) |
||
707 | FileShare.Write, |
763 | { |
|
- | 764 | await zipStream.CopyToAsync(fileStream); |
||
708 | cancellationToken)) |
765 | } |
|
709 | { |
766 | } |
|
710 | readStream.Position = 0L; |
- | ||
Line 711... | Line -... | |||
711 | |
- | ||
712 | using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress)) |
- | ||
713 | { |
- | ||
714 | await zipStream.CopyToAsync(fileStream); |
- | ||
715 | } |
- | ||
716 | } |
- | ||
717 | } |
767 | } |
|
718 | } |
768 | } |
|
719 | } |
769 | } |
|
720 | } |
770 | } |
|
721 | } |
771 | } |
|
722 | } |
772 | } |
|
- | 773 | finally |
||
- | 774 | { |
||
- | 775 | _databaseLock.Release(); |
||
- | 776 | } |
||
- | 777 | } |
||
- | 778 | |
||
723 | |
779 | public async Task RevertFile(string name, string hash, CancellationToken cancellationToken, bool atomic = true) |
|
724 | public async Task RevertFile(string name, string hash, CancellationToken cancellationToken, bool atomic = true) |
780 | { |
|
725 | { |
781 | var connectionString = new SQLiteConnectionStringBuilder |
|
Line 726... | Line 782... | |||
726 | await _snapshotSemaphore.WaitAsync(cancellationToken); |
782 | { |
|
727 | |
783 | ConnectionString = DatabaseConnectionString |
|
Line 728... | Line 784... | |||
728 | var connectionString = new SQLiteConnectionStringBuilder |
784 | }; |
|
729 | { |
785 | |
|
730 | ConnectionString = DatabaseConnectionString |
786 | await _databaseLock.WaitAsync(cancellationToken); |
|
731 | }; |
787 | try |
|
732 | |
- | ||
733 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
- | ||
734 | { |
- | ||
735 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
736 | |
- | ||
737 | // Insert the file change. |
- | ||
738 | using (var sqliteCommand = |
788 | { |
|
739 | new SQLiteCommand(RetrieveDataPathFromHashSql, sqliteConnection)) |
789 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
740 | { |
- | ||
- | 790 | { |
||
- | 791 | await sqliteConnection.OpenAsync(cancellationToken); |
||
741 | try |
792 | |
|
742 | { |
793 | // Insert the file change. |
|
743 | sqliteCommand.Parameters.AddRange(new[] |
794 | using (var sqliteCommand = |
|
- | 795 | new SQLiteCommand(RetrieveDataPathFromHashSql, sqliteConnection)) |
||
- | 796 | { |
||
- | 797 | try |
||
- | 798 | { |
||
- | 799 | sqliteCommand.Parameters.AddRange(new[] |
||
744 | { |
800 | { |
|
- | 801 | new SQLiteParameter("@hash", hash) |
||
745 | new SQLiteParameter("@hash", hash) |
802 | }); |
|
746 | }); |
803 | |
|
747 | |
- | ||
Line 748... | Line 804... | |||
748 | sqliteCommand.Prepare(); |
804 | sqliteCommand.Prepare(); |
|
749 | |
805 | |
|
Line 750... | Line 806... | |||
750 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
806 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
|
- | 807 | { |
||
751 | { |
808 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
|
752 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
809 | { |
|
753 | { |
- | ||
754 | var path = (string)sqlDataReader["Path"]; |
810 | var path = (string)sqlDataReader["Path"]; |
|
755 | |
811 | |
|
756 | // Create directories if they do not exist. |
812 | // Create directories if they do not exist. |
|
Line 757... | Line 813... | |||
757 | var dir = Path.GetDirectoryName(path); |
813 | var dir = Path.GetDirectoryName(path); |
|
758 | |
814 | |
|
759 | if (dir != null && !Directory.Exists(dir)) |
- | ||
760 | { |
- | ||
761 | Directory.CreateDirectory(dir); |
- | ||
762 | } |
815 | if (dir != null && !Directory.Exists(dir)) |
|
763 | |
816 | { |
|
764 | switch (atomic) |
817 | Directory.CreateDirectory(dir); |
|
- | 818 | } |
||
- | 819 | |
||
- | 820 | switch (atomic) |
||
- | 821 | { |
||
765 | { |
822 | case true: |
|
Line 766... | Line 823... | |||
766 | case true: |
823 | // Atomic |
|
767 | // Atomic |
824 | var temp = Path.Combine(Path.GetDirectoryName(path), |
|
768 | var temp = Path.Combine(Path.GetDirectoryName(path), |
825 | $"{Path.GetFileName(path)}.temp"); |
|
769 | $"{Path.GetFileName(path)}.temp"); |
826 | |
|
770 | |
827 | using (var readStream = sqlDataReader.GetStream(2)) |
|
771 | using (var readStream = sqlDataReader.GetStream(2)) |
828 | { |
|
Line 772... | Line 829... | |||
772 | { |
829 | using (var fileStream = new FileStream(temp, FileMode.Create, |
|
- | 830 | FileAccess.Write, |
||
773 | using (var fileStream = new FileStream(temp, FileMode.Create, |
831 | FileShare.None)) |
|
774 | FileAccess.Write, |
- | ||
775 | FileShare.None)) |
- | ||
776 | { |
832 | { |
|
777 | using (var zipStream = |
833 | using (var zipStream = |
|
778 | new GZipStream(readStream, CompressionMode.Decompress)) |
- | ||
779 | { |
- | ||
780 | zipStream.CopyTo(fileStream); |
834 | new GZipStream(readStream, CompressionMode.Decompress)) |
|
Line -... | Line 835... | |||
- | 835 | { |
||
- | 836 | zipStream.CopyTo(fileStream); |
||
781 | } |
837 | } |
|
782 | } |
838 | } |
|
783 | } |
839 | } |
|
- | 840 | |
||
784 | |
841 | try |
|
785 | try |
- | ||
786 | { |
842 | { |
|
- | 843 | File.Replace(temp, path, null, true); |
||
787 | File.Replace(temp, path, null, true); |
844 | } |
|
- | 845 | catch |
||
788 | } |
846 | { |
|
- | 847 | try |
||
- | 848 | { |
||
789 | catch |
849 | File.Delete(temp); |
|
790 | { |
850 | } |
|
Line 791... | Line 851... | |||
791 | try |
851 | catch (Exception exception) |
|
Line 792... | Line 852... | |||
792 | { |
852 | { |
|
Line 793... | Line 853... | |||
793 | File.Delete(temp); |
853 | // Suppress deletion errors of temporary file. |
|
- | 854 | Log.Warning(exception, "Could not delete temporary file.", temp); |
||
794 | } |
855 | } |
|
795 | catch (Exception exception) |
- | ||
Line 796... | Line 856... | |||
796 | { |
856 | |
|
Line 797... | Line 857... | |||
797 | // Suppress deletion errors of temporary file. |
857 | throw; |
|
798 | Log.Warning(exception, "Could not delete temporary file.", temp); |
858 | } |
|
799 | } |
859 | |
|
800 | |
860 | break; |
|
801 | throw; |
861 | default: |
|
Line 802... | Line 862... | |||
802 | } |
862 | // Asynchronous |
|
- | 863 | using (var readStream = sqlDataReader.GetStream(2)) |
||
803 | |
864 | { |
|
804 | break; |
865 | using (var fileStream = |
|
805 | default: |
866 | await Miscellaneous.GetFileStream(path, FileMode.Create, |
|
- | 867 | FileAccess.Write, |
||
- | 868 | FileShare.Write, |
||
- | 869 | cancellationToken)) |
||
- | 870 | { |
||
806 | // Asynchronous |
871 | readStream.Position = 0L; |
|
Line 807... | Line 872... | |||
807 | using (var readStream = sqlDataReader.GetStream(2)) |
872 | |
|
808 | { |
873 | using (var zipStream = |
|
809 | using (var fileStream = |
874 | new GZipStream(readStream, CompressionMode.Decompress)) |
|
810 | await Miscellaneous.GetFileStream(path, FileMode.Create, |
875 | { |
|
811 | FileAccess.Write, |
876 | await zipStream.CopyToAsync(fileStream); |
|
812 | FileShare.Write, |
877 | } |
|
813 | cancellationToken)) |
- | ||
814 | { |
878 | } |
|
- | 879 | } |
||
815 | readStream.Position = 0L; |
880 | |
|
816 | |
- | ||
817 | using (var zipStream = |
- | ||
818 | new GZipStream(readStream, CompressionMode.Decompress)) |
881 | |
|
819 | { |
882 | break; |
|
820 | await zipStream.CopyToAsync(fileStream); |
883 | } |
|
821 | } |
- | ||
- | 884 | |
||
822 | } |
885 | SnapshotRevert?.Invoke(this, new SnapshotRevertSuccessEventArgs(name)); |
|
823 | } |
886 | } |
|
- | 887 | } |
||
824 | |
888 | } |
|
- | 889 | catch |
||
825 | |
890 | { |
|
826 | break; |
891 | SnapshotRevert?.Invoke(this, new SnapshotRevertFailureEventArgs(name)); |
|
827 | } |
892 | |
|
828 | |
893 | throw; |
|
829 | SnapshotRevert?.Invoke(this, new SnapshotRevertSuccessEventArgs(name)); |
894 | } |
|
Line 830... | Line 895... | |||
830 | } |
895 | } |
|
Line -... | Line 896... | |||
- | 896 | } |
||
- | 897 | } |
||
831 | } |
898 | finally |
|
Line 832... | Line 899... | |||
832 | } |
899 | { |
|
833 | catch |
900 | _databaseLock.Release(); |
|
834 | { |
901 | } |
|
835 | SnapshotRevert?.Invoke(this, new SnapshotRevertFailureEventArgs(name)); |
902 | } |
|
836 | |
903 | |
|
Line 837... | Line 904... | |||
837 | throw; |
904 | public async Task RemoveFileFast(IEnumerable<string> hashes, CancellationToken cancellationToken) |
|
- | 905 | { |
||
838 | } |
906 | var connectionString = new SQLiteConnectionStringBuilder |
|
839 | finally |
907 | { |
|
840 | { |
908 | ConnectionString = DatabaseConnectionString |
|
841 | _snapshotSemaphore.Release(); |
909 | }; |
|
- | 910 | |
||
- | 911 | await _databaseLock.WaitAsync(cancellationToken); |
||
- | 912 | try |
||
- | 913 | { |
||
842 | } |
914 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
Line 843... | Line 915... | |||
843 | } |
915 | { |
|
844 | } |
916 | await sqliteConnection.OpenAsync(cancellationToken); |
|
845 | } |
917 | |
|
846 | |
918 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
847 | public async Task RemoveFileFast(IEnumerable<string> hashes, CancellationToken cancellationToken) |
919 | { |
|
848 | { |
920 | try |
|
Line 849... | Line -... | |||
849 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
850 | { |
- | ||
851 | ConnectionString = DatabaseConnectionString |
921 | { |
|
Line -... | Line 922... | |||
- | 922 | var transactionCommands = new List<Task>(); |
||
- | 923 | |
||
852 | }; |
924 | foreach (var hash in hashes) |
|
853 | |
925 | { |
|
854 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
926 | // Insert the file change. |
|
855 | { |
- | ||
- | 927 | using (var sqliteCommand = |
||
856 | await sqliteConnection.OpenAsync(cancellationToken); |
928 | new SQLiteCommand(RemoveSnapshotFromHashSql, sqliteConnection, dbTransaction)) |
|
857 | |
929 | { |
|
- | 930 | sqliteCommand.Parameters.AddRange(new[] |
||
858 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
931 | { |
|
- | 932 | new SQLiteParameter("@hash", hash) |
||
859 | { |
933 | }); |
|
860 | try |
934 | |
|
861 | { |
935 | sqliteCommand.Prepare(); |
|
862 | var transactionCommands = new List<Task>(); |
936 | |
|
863 | |
937 | var command = sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
864 | foreach (var hash in hashes) |
938 | |
|
Line 865... | Line 939... | |||
865 | { |
939 | transactionCommands.Add(command); |
|
Line -... | Line 940... | |||
- | 940 | } |
||
- | 941 | } |
||
866 | // Insert the file change. |
942 | |
|
Line 867... | Line 943... | |||
867 | using (var sqliteCommand = |
943 | await Task.WhenAll(transactionCommands); |
|
868 | new SQLiteCommand(RemoveSnapshotFromHashSql, sqliteConnection, dbTransaction)) |
944 | |
|
869 | { |
945 | dbTransaction.Commit(); |
|
870 | sqliteCommand.Parameters.AddRange(new[] |
946 | } |
|
871 | { |
947 | catch |
|
Line 872... | Line 948... | |||
872 | new SQLiteParameter("@hash", hash) |
948 | { |
|
- | 949 | dbTransaction.Rollback(); |
||
873 | }); |
950 | |
|
874 | |
951 | throw; |
|
875 | sqliteCommand.Prepare(); |
952 | } |
|
876 | |
953 | } |
|
- | 954 | } |
||
- | 955 | } |
||
- | 956 | finally |
||
- | 957 | { |
||
877 | var command = sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
958 | _databaseLock.Release(); |
|
Line 878... | Line 959... | |||
878 | |
959 | } |
|
879 | transactionCommands.Add(command); |
960 | } |
|
880 | } |
961 | |
|
881 | } |
962 | public async Task RemoveFile(string hash, CancellationToken cancellationToken) |
|
882 | |
963 | { |
|
883 | await Task.WhenAll(transactionCommands); |
964 | var connectionString = new SQLiteConnectionStringBuilder |
|
Line 884... | Line 965... | |||
884 | |
965 | { |
|
- | 966 | ConnectionString = DatabaseConnectionString |
||
885 | dbTransaction.Commit(); |
967 | }; |
|
886 | } |
- | ||
887 | catch |
- | ||
888 | { |
968 | await _databaseLock.WaitAsync(cancellationToken); |
|
889 | dbTransaction.Rollback(); |
969 | try |
|
890 | |
970 | { |
|
891 | throw; |
- | ||
- | 971 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
||
892 | } |
972 | { |
|
893 | } |
973 | await sqliteConnection.OpenAsync(cancellationToken); |
|
- | 974 | |
||
894 | } |
975 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
- | 976 | { |
||
895 | } |
977 | // Insert the file change. |
|
896 | |
978 | using (var sqliteCommand = |
|
897 | public async Task RemoveFile(string hash, CancellationToken cancellationToken) |
979 | new SQLiteCommand(RemoveSnapshotFromHashSql, sqliteConnection, dbTransaction)) |
|
898 | { |
980 | { |
|
899 | var connectionString = new SQLiteConnectionStringBuilder |
981 | sqliteCommand.Parameters.AddRange(new[] |
|
Line 900... | Line 982... | |||
900 | { |
982 | { |
|
Line -... | Line 983... | |||
- | 983 | new SQLiteParameter("@hash", hash) |
||
- | 984 | }); |
||
901 | ConnectionString = DatabaseConnectionString |
985 | |
|
Line 902... | Line 986... | |||
902 | }; |
986 | sqliteCommand.Prepare(); |
|
903 | |
987 | |
|
904 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
988 | try |
|
905 | { |
989 | { |
|
906 | await sqliteConnection.OpenAsync(cancellationToken); |
990 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
Line 907... | Line 991... | |||
907 | |
991 | |
|
- | 992 | dbTransaction.Commit(); |
||
908 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
993 | } |
|
909 | { |
994 | catch |
|
910 | // Insert the file change. |
995 | { |
|
911 | using (var sqliteCommand = |
996 | dbTransaction.Rollback(); |
|
- | 997 | |
||
- | 998 | throw; |
||
- | 999 | } |
||
- | 1000 | } |
||
912 | new SQLiteCommand(RemoveSnapshotFromHashSql, sqliteConnection, dbTransaction)) |
1001 | } |
|
Line 913... | Line 1002... | |||
913 | { |
1002 | } |
|
914 | try |
1003 | } |
|
915 | { |
1004 | finally |
|
916 | sqliteCommand.Parameters.AddRange(new[] |
1005 | { |
|
917 | { |
1006 | _databaseLock.Release(); |
|
918 | new SQLiteParameter("@hash", hash) |
1007 | } |
|
Line 919... | Line 1008... | |||
919 | }); |
1008 | } |
|
- | 1009 | |
||
920 | |
1010 | public async Task UpdateColor(string hash, Color color, CancellationToken cancellationToken) |
|
921 | sqliteCommand.Prepare(); |
- | ||
922 | |
- | ||
923 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
- | ||
924 | |
1011 | { |
|
925 | dbTransaction.Commit(); |
1012 | var connectionString = new SQLiteConnectionStringBuilder |
|
926 | } |
1013 | { |
|
927 | catch |
- | ||
928 | { |
- | ||
929 | dbTransaction.Rollback(); |
- | ||
930 | |
- | ||
931 | throw; |
- | ||
932 | } |
- | ||
933 | } |
- | ||
Line -... | Line 1014... | |||
- | 1014 | ConnectionString = DatabaseConnectionString |
||
934 | } |
1015 | }; |
|
935 | } |
1016 | |
|
936 | } |
1017 | await _databaseLock.WaitAsync(cancellationToken); |
|
937 | |
1018 | |
|
938 | public async Task UpdateColor(string hash, Color color, CancellationToken cancellationToken) |
1019 | try |
|
939 | { |
1020 | { |
|
940 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
941 | { |
- | ||
942 | ConnectionString = DatabaseConnectionString |
- | ||
943 | }; |
- | ||
Line 944... | Line -... | |||
944 | |
- | ||
945 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1021 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
946 | { |
- | ||
Line 947... | Line 1022... | |||
947 | await sqliteConnection.OpenAsync(cancellationToken); |
1022 | { |
|
Line 948... | Line 1023... | |||
948 | |
1023 | await sqliteConnection.OpenAsync(cancellationToken); |
|
- | 1024 | |
||
- | 1025 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
||
- | 1026 | { |
||
- | 1027 | // Insert the file change. |
||
949 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
1028 | using (var sqliteCommand = |
|
950 | { |
- | ||
951 | // Insert the file change. |
- | ||
952 | using (var sqliteCommand = |
1029 | new SQLiteCommand(UpdateColorFromHashSql, sqliteConnection, dbTransaction)) |
|
953 | new SQLiteCommand(UpdateColorFromHashSql, sqliteConnection, dbTransaction)) |
- | ||
954 | { |
1030 | { |
|
955 | try |
- | ||
956 | { |
- | ||
957 | sqliteCommand.Parameters.AddRange(new[] |
- | ||
958 | { |
- | ||
959 | new SQLiteParameter("@hash", hash), |
- | ||
960 | new SQLiteParameter("@color", color.ToArgb()) |
- | ||
961 | }); |
- | ||
962 | |
- | ||
963 | sqliteCommand.Prepare(); |
- | ||
964 | |
- | ||
965 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
- | ||
966 | |
- | ||
967 | dbTransaction.Commit(); |
- | ||
968 | } |
- | ||
969 | catch |
- | ||
970 | { |
- | ||
971 | dbTransaction.Rollback(); |
- | ||
972 | |
- | ||
973 | throw; |
- | ||
974 | } |
- | ||
975 | } |
- | ||
976 | } |
- | ||
977 | } |
- | ||
978 | } |
- | ||
979 | |
- | ||
980 | public async Task RemoveColor(string hash, CancellationToken cancellationToken) |
- | ||
981 | { |
- | ||
982 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
983 | { |
- | ||
984 | ConnectionString = DatabaseConnectionString |
- | ||
985 | }; |
- | ||
986 | |
- | ||
987 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
- | ||
Line 988... | Line 1031... | |||
988 | { |
1031 | sqliteCommand.Parameters.AddRange(new[] |
|
989 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
Line 990... | Line 1032... | |||
990 | |
1032 | { |
|
991 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
- | ||
992 | { |
- | ||
993 | // Insert the file change. |
- | ||
994 | using (var sqliteCommand = |
- | ||
995 | new SQLiteCommand(RemoveColorFromHashSql, sqliteConnection, dbTransaction)) |
- | ||
996 | { |
1033 | new SQLiteParameter("@hash", hash), |
|
- | 1034 | new SQLiteParameter("@color", color.ToArgb()) |
||
Line 997... | Line 1035... | |||
997 | try |
1035 | }); |
|
Line 998... | Line -... | |||
998 | { |
- | ||
999 | sqliteCommand.Parameters.AddRange(new[] |
- | ||
1000 | { |
- | ||
1001 | new SQLiteParameter("@hash", hash) |
- | ||
1002 | }); |
1036 | |
|
1003 | |
1037 | sqliteCommand.Prepare(); |
|
1004 | sqliteCommand.Prepare(); |
- | ||
1005 | |
1038 | |
|
1006 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
- | ||
1007 | |
1039 | try |
|
1008 | dbTransaction.Commit(); |
- | ||
1009 | } |
1040 | { |
|
1010 | catch |
- | ||
1011 | { |
1041 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
1012 | dbTransaction.Rollback(); |
1042 | |
|
1013 | |
1043 | dbTransaction.Commit(); |
|
- | 1044 | } |
||
- | 1045 | catch |
||
1014 | throw; |
1046 | { |
|
1015 | } |
- | ||
Line 1016... | Line 1047... | |||
1016 | } |
1047 | dbTransaction.Rollback(); |
|
- | 1048 | |
||
1017 | } |
1049 | throw; |
|
1018 | } |
1050 | } |
|
1019 | } |
1051 | } |
|
- | 1052 | } |
||
- | 1053 | } |
||
- | 1054 | } |
||
- | 1055 | finally |
||
1020 | |
1056 | { |
|
1021 | public async Task<SnapshotPreview> RetrievePreview(string hash, CancellationToken cancellationToken) |
- | ||
Line 1022... | Line 1057... | |||
1022 | { |
1057 | _databaseLock.Release(); |
|
1023 | var connectionString = new SQLiteConnectionStringBuilder |
1058 | } |
|
1024 | { |
1059 | } |
|
1025 | ConnectionString = DatabaseConnectionString |
1060 | |
|
1026 | }; |
1061 | public async Task RemoveColor(string hash, CancellationToken cancellationToken) |
|
1027 | |
1062 | { |
|
Line 1028... | Line 1063... | |||
1028 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1063 | var connectionString = new SQLiteConnectionStringBuilder |
|
- | 1064 | { |
||
1029 | { |
1065 | ConnectionString = DatabaseConnectionString |
|
1030 | await sqliteConnection.OpenAsync(cancellationToken); |
- | ||
1031 | |
- | ||
1032 | // Insert the file change. |
- | ||
1033 | using (var sqliteCommand = new SQLiteCommand(RetrievePreviewFromHashSql, sqliteConnection)) |
1066 | }; |
|
1034 | { |
1067 | |
|
1035 | sqliteCommand.Parameters.AddRange(new[] |
1068 | await _databaseLock.WaitAsync(cancellationToken); |
|
- | 1069 | try |
||
- | 1070 | { |
||
- | 1071 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
||
1036 | { |
1072 | { |
|
- | 1073 | await sqliteConnection.OpenAsync(cancellationToken); |
||
- | 1074 | |
||
1037 | new SQLiteParameter("@hash", hash) |
1075 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
1038 | }); |
1076 | { |
|
Line 1039... | Line 1077... | |||
1039 | |
1077 | // Insert the file change. |
|
Line 1040... | Line 1078... | |||
1040 | var note = string.Empty; |
1078 | using (var sqliteCommand = |
|
1041 | |
- | ||
1042 | sqliteCommand.Prepare(); |
- | ||
1043 | |
1079 | new SQLiteCommand(RemoveColorFromHashSql, sqliteConnection, dbTransaction)) |
|
1044 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
1080 | { |
|
1045 | { |
1081 | sqliteCommand.Parameters.AddRange(new[] |
|
1046 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
1082 | { |
|
1047 | { |
1083 | new SQLiteParameter("@hash", hash) |
|
- | 1084 | }); |
||
- | 1085 | |
||
1048 | if (!(sqlDataReader["Note"] is DBNull)) |
1086 | sqliteCommand.Prepare(); |
|
Line 1049... | Line 1087... | |||
1049 | { |
1087 | |
|
Line 1050... | Line 1088... | |||
1050 | note = (string)sqlDataReader["Note"]; |
1088 | try |
|
Line 1051... | Line 1089... | |||
1051 | } |
1089 | { |
|
1052 | |
1090 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
1053 | Bitmap shot = null; |
1091 | |
|
1054 | |
1092 | dbTransaction.Commit(); |
|
Line 1055... | Line 1093... | |||
1055 | if (!(sqlDataReader["Shot"] is DBNull)) |
1093 | } |
|
Line 1056... | Line 1094... | |||
1056 | { |
1094 | catch |
|
Line 1057... | Line 1095... | |||
1057 | var readStream = sqlDataReader.GetStream(2); |
1095 | { |
|
- | 1096 | dbTransaction.Rollback(); |
||
1058 | |
1097 | |
|
1059 | readStream.Position = 0L; |
1098 | throw; |
|
1060 | |
1099 | } |
|
1061 | using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress)) |
- | ||
Line 1062... | Line 1100... | |||
1062 | { |
1100 | } |
|
- | 1101 | } |
||
1063 | using (var image = Image.FromStream(zipStream)) |
1102 | } |
|
1064 | { |
1103 | } |
|
1065 | shot = new Bitmap(image); |
1104 | finally |
|
- | 1105 | { |
||
- | 1106 | _databaseLock.Release(); |
||
- | 1107 | } |
||
- | 1108 | } |
||
1066 | } |
1109 | |
|
Line 1067... | Line 1110... | |||
1067 | } |
1110 | public async Task<SnapshotPreview> RetrievePreview(string hash, CancellationToken cancellationToken) |
|
1068 | } |
1111 | { |
|
1069 | |
1112 | var connectionString = new SQLiteConnectionStringBuilder |
|
1070 | return new SnapshotPreview(hash, shot, note); |
1113 | { |
|
1071 | } |
1114 | ConnectionString = DatabaseConnectionString |
|
1072 | |
1115 | }; |
|
Line 1073... | Line 1116... | |||
1073 | return null; |
1116 | |
|
- | 1117 | await _databaseLock.WaitAsync(cancellationToken); |
||
1074 | } |
1118 | try |
|
1075 | } |
- | ||
1076 | } |
- | ||
1077 | } |
1119 | { |
|
1078 | |
1120 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
1079 | /* |
1121 | { |
|
1080 | public MemoryStream RetrieveFileStream(string hash, CancellationToken cancellationToken) |
- | ||
- | 1122 | await sqliteConnection.OpenAsync(cancellationToken); |
||
1081 | { |
1123 | |
|
1082 | var connectionString = new SQLiteConnectionStringBuilder |
1124 | // Insert the file change. |
|
- | 1125 | using (var sqliteCommand = new SQLiteCommand(RetrievePreviewFromHashSql, sqliteConnection)) |
||
1083 | { |
1126 | { |
|
- | 1127 | sqliteCommand.Parameters.AddRange(new[] |
||
1084 | ConnectionString = DatabaseConnectionString |
1128 | { |
|
1085 | }; |
1129 | new SQLiteParameter("@hash", hash) |
|
1086 | |
1130 | }); |
|
1087 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1131 | |
|
1088 | { |
1132 | var note = string.Empty; |
|
1089 | |
1133 | |
|
Line 1090... | Line 1134... | |||
1090 | sqliteConnection.Open(); |
1134 | sqliteCommand.Prepare(); |
|
Line -... | Line 1135... | |||
- | 1135 | |
||
- | 1136 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
||
1091 | |
1137 | { |
|
Line 1092... | Line 1138... | |||
1092 | // Insert the file change. |
1138 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
|
1093 | using (var sqliteCommand = new SQLiteCommand(RetrieveDataFromHashSql, sqliteConnection)) |
1139 | { |
|
1094 | { |
1140 | if (!(sqlDataReader["Note"] is DBNull)) |
|
1095 | sqliteCommand.Parameters.AddRange(new[] |
1141 | { |
|
1096 | { |
1142 | note = (string)sqlDataReader["Note"]; |
|
Line 1097... | Line 1143... | |||
1097 | new SQLiteParameter("@hash", hash) |
1143 | } |
|
- | 1144 | |
||
1098 | }); |
1145 | Bitmap shot = null; |
|
1099 | |
1146 | |
|
1100 | sqliteCommand.Prepare(); |
1147 | if (!(sqlDataReader["Shot"] is DBNull)) |
|
1101 | |
1148 | { |
|
- | 1149 | var readStream = sqlDataReader.GetStream(2); |
||
- | 1150 | |
||
- | 1151 | readStream.Position = 0L; |
||
- | 1152 | |
||
- | 1153 | using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress)) |
||
1102 | using (var sqlDataReader = sqliteCommand.ExecuteReader()) |
1154 | { |
|
Line 1103... | Line 1155... | |||
1103 | { |
1155 | using (var image = Image.FromStream(zipStream)) |
|
1104 | |
1156 | { |
|
1105 | while (sqlDataReader.Read()) |
1157 | shot = new Bitmap(image); |
|
1106 | { |
1158 | } |
|
1107 | using (var readStream = sqlDataReader.GetStream(1)) |
1159 | } |
|
1108 | { |
1160 | } |
|
Line 1109... | Line 1161... | |||
1109 | |
1161 | |
|
- | 1162 | return new SnapshotPreview(hash, shot, note); |
||
1110 | using (var memoryStream = new MemoryStream()) |
1163 | } |
|
1111 | { |
- | ||
1112 | |
- | ||
1113 | readStream.Position = 0L; |
1164 | |
|
1114 | |
1165 | return null; |
|
1115 | readStream.CopyTo(memoryStream); |
1166 | } |
|
1116 | |
- | ||
- | 1167 | } |
||
1117 | memoryStream.Position = 0L; |
1168 | } |
|
1118 | |
1169 | } |
|
- | 1170 | finally |
||
1119 | using (var zipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) |
1171 | { |
|
- | 1172 | _databaseLock.Release(); |
||
1120 | { |
1173 | } |
|
1121 | |
1174 | } |
|
1122 | var outputStream = new MemoryStream(); |
1175 | |
|
1123 | |
1176 | public async Task<MemoryStream> RetrieveFileStream(string hash, CancellationToken cancellationToken) |
|
1124 | zipStream.CopyTo(outputStream); |
1177 | { |
|
1125 | |
1178 | var connectionString = new SQLiteConnectionStringBuilder |
|
Line 1126... | Line 1179... | |||
1126 | outputStream.Position = 0L; |
1179 | { |
|
Line -... | Line 1180... | |||
- | 1180 | ConnectionString = DatabaseConnectionString |
||
- | 1181 | }; |
||
1127 | |
1182 | |
|
Line 1128... | Line 1183... | |||
1128 | return outputStream; |
1183 | await _databaseLock.WaitAsync(cancellationToken); |
|
Line 1129... | Line 1184... | |||
1129 | } |
1184 | try |
|
1130 | } |
1185 | { |
|
1131 | } |
1186 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
1132 | } |
1187 | { |
|
1133 | |
1188 | await sqliteConnection.OpenAsync(cancellationToken); |
|
Line 1134... | Line 1189... | |||
1134 | return null; |
1189 | |
|
Line 1135... | Line 1190... | |||
1135 | } |
1190 | // Insert the file change. |
|
- | 1191 | using (var sqliteCommand = new SQLiteCommand(RetrieveDataFromHashSql, sqliteConnection)) |
||
1136 | } |
1192 | { |
|
1137 | } |
1193 | sqliteCommand.Parameters.AddRange(new[] |
|
1138 | } |
1194 | { |
|
1139 | */ |
1195 | new SQLiteParameter("@hash", hash) |
|
- | 1196 | }); |
||
- | 1197 | |
||
- | 1198 | sqliteCommand.Prepare(); |
||
- | 1199 | |
||
1140 | |
1200 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
|
Line 1141... | Line 1201... | |||
1141 | public async Task<MemoryStream> RetrieveFileStream(string hash, CancellationToken cancellationToken) |
1201 | { |
|
1142 | { |
1202 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
|
1143 | var connectionString = new SQLiteConnectionStringBuilder |
1203 | { |
|
1144 | { |
1204 | using (var readStream = sqlDataReader.GetStream(1)) |
|
1145 | ConnectionString = DatabaseConnectionString |
- | ||
1146 | }; |
- | ||
1147 | |
1205 | { |
|
1148 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1206 | using (var memoryStream = new MemoryStream()) |
|
Line -... | Line 1207... | |||
- | 1207 | { |
||
- | 1208 | readStream.Position = 0L; |
||
- | 1209 | |
||
1149 | { |
1210 | await readStream.CopyToAsync(memoryStream); |
|
1150 | await sqliteConnection.OpenAsync(cancellationToken); |
1211 | |
|
1151 | |
- | ||
1152 | // Insert the file change. |
- | ||
1153 | using (var sqliteCommand = new SQLiteCommand(RetrieveDataFromHashSql, sqliteConnection)) |
1212 | memoryStream.Position = 0L; |
|
1154 | { |
1213 | |
|
1155 | sqliteCommand.Parameters.AddRange(new[] |
1214 | using (var zipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) |
|
- | 1215 | { |
||
- | 1216 | // Do not dispose the returned stream and leave it up to callers to dispose. |
||
1156 | { |
1217 | var outputStream = new MemoryStream(); |
|
1157 | new SQLiteParameter("@hash", hash) |
1218 | |
|
1158 | }); |
1219 | await zipStream.CopyToAsync(outputStream); |
|
1159 | |
1220 | |
|
1160 | sqliteCommand.Prepare(); |
1221 | outputStream.Position = 0L; |
|
- | 1222 | |
||
- | 1223 | return outputStream; |
||
1161 | |
1224 | } |
|
1162 | using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
1225 | } |
|
Line 1163... | Line 1226... | |||
1163 | { |
1226 | } |
|
1164 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
1227 | } |
|
1165 | { |
1228 | |
|
1166 | using (var readStream = sqlDataReader.GetStream(1)) |
1229 | return null; |
|
Line 1167... | Line 1230... | |||
1167 | { |
1230 | } |
|
1168 | using (var memoryStream = new MemoryStream()) |
- | ||
1169 | { |
- | ||
1170 | readStream.Position = 0L; |
- | ||
1171 | |
1231 | } |
|
1172 | await readStream.CopyToAsync(memoryStream); |
- | ||
1173 | |
- | ||
1174 | memoryStream.Position = 0L; |
- | ||
1175 | |
- | ||
1176 | using (var zipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) |
- | ||
1177 | { |
- | ||
1178 | // Do not dispose the returned stream and leave it up to callers to dispose. |
- | ||
1179 | var outputStream = new MemoryStream(); |
1232 | } |
|
1180 | |
1233 | } |
|
1181 | await zipStream.CopyToAsync(outputStream); |
1234 | finally |
|
- | 1235 | { |
||
- | 1236 | _databaseLock.Release(); |
||
- | 1237 | } |
||
- | 1238 | } |
||
1182 | |
1239 | |
|
- | 1240 | public async Task RelocateFile(string hash, string path, CancellationToken cancellationToken) |
||
- | 1241 | { |
||
- | 1242 | var connectionString = new SQLiteConnectionStringBuilder |
||
- | 1243 | { |
||
- | 1244 | ConnectionString = DatabaseConnectionString |
||
1183 | outputStream.Position = 0L; |
1245 | }; |
|
- | 1246 | |
||
- | 1247 | await _databaseLock.WaitAsync(cancellationToken); |
||
1184 | |
1248 | try |
|
1185 | return outputStream; |
1249 | { |
|
1186 | } |
1250 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
1187 | } |
1251 | { |
|
Line 1188... | Line 1252... | |||
1188 | } |
1252 | await sqliteConnection.OpenAsync(cancellationToken); |
|
1189 | } |
1253 | |
|
1190 | |
1254 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
Line 1191... | Line 1255... | |||
1191 | return null; |
1255 | { |
|
1192 | } |
1256 | // Insert the file change. |
|
1193 | } |
1257 | using (var sqliteCommand = |
|
1194 | } |
- | ||
1195 | } |
- | ||
1196 | |
1258 | new SQLiteCommand(RelocateFileFromHashSql, sqliteConnection, dbTransaction)) |
|
- | 1259 | { |
||
- | 1260 | sqliteCommand.Parameters.AddRange(new[] |
||
1197 | public async Task RelocateFile(string hash, string path, CancellationToken cancellationToken) |
1261 | { |
|
1198 | { |
1262 | new SQLiteParameter("@hash", hash), |
|
Line 1199... | Line 1263... | |||
1199 | var connectionString = new SQLiteConnectionStringBuilder |
1263 | new SQLiteParameter("@path", path) |
|
Line 1200... | Line 1264... | |||
1200 | { |
1264 | }); |
|
1201 | ConnectionString = DatabaseConnectionString |
1265 | |
|
1202 | }; |
- | ||
1203 | |
- | ||
1204 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1266 | sqliteCommand.Prepare(); |
|
1205 | { |
1267 | |
|
1206 | await sqliteConnection.OpenAsync(cancellationToken); |
1268 | try |
|
1207 | |
- | ||
1208 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
- | ||
1209 | { |
- | ||
1210 | // Insert the file change. |
- | ||
1211 | using (var sqliteCommand = |
1269 | { |
|
1212 | new SQLiteCommand(RelocateFileFromHashSql, sqliteConnection, dbTransaction)) |
1270 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
- | 1271 | |
||
- | 1272 | dbTransaction.Commit(); |
||
- | 1273 | } |
||
- | 1274 | catch |
||
- | 1275 | { |
||
- | 1276 | dbTransaction.Rollback(); |
||
- | 1277 | |
||
- | 1278 | throw; |
||
1213 | { |
1279 | } |
|
1214 | try |
1280 | } |
|
1215 | { |
1281 | } |
|
1216 | sqliteCommand.Parameters.AddRange(new[] |
1282 | } |
|
1217 | { |
1283 | } |
|
- | 1284 | |
||
1218 | new SQLiteParameter("@hash", hash), |
1285 | finally |
|
1219 | new SQLiteParameter("@path", path) |
1286 | { |
|
1220 | }); |
1287 | _databaseLock.Release(); |
|
1221 | |
1288 | } |
|
1222 | sqliteCommand.Prepare(); |
- | ||
Line 1223... | Line 1289... | |||
1223 | |
1289 | } |
|
Line 1224... | Line 1290... | |||
1224 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
1290 | |
|
1225 | |
1291 | public async Task UpdateNote(string hash, string note, CancellationToken cancellationToken) |
|
Line 1226... | Line 1292... | |||
1226 | dbTransaction.Commit(); |
1292 | { |
|
- | 1293 | var connectionString = new SQLiteConnectionStringBuilder |
||
1227 | } |
1294 | { |
|
1228 | catch |
1295 | ConnectionString = DatabaseConnectionString |
|
1229 | { |
1296 | }; |
|
1230 | dbTransaction.Rollback(); |
1297 | |
|
1231 | |
- | ||
1232 | throw; |
1298 | await _databaseLock.WaitAsync(cancellationToken); |
|
1233 | } |
1299 | try |
|
1234 | } |
1300 | { |
|
Line 1235... | Line 1301... | |||
1235 | } |
1301 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
Line 1236... | Line 1302... | |||
1236 | } |
1302 | { |
|
- | 1303 | await sqliteConnection.OpenAsync(cancellationToken); |
||
1237 | } |
1304 | |
|
1238 | |
1305 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
1239 | public async Task UpdateNote(string hash, string note, CancellationToken cancellationToken) |
1306 | { |
|
1240 | { |
1307 | // Insert the file change. |
|
- | 1308 | using (var sqliteCommand = |
||
- | 1309 | new SQLiteCommand(UpdateNoteFromHashSql, sqliteConnection, dbTransaction)) |
||
- | 1310 | { |
||
- | 1311 | sqliteCommand.Parameters.AddRange(new[] |
||
1241 | var connectionString = new SQLiteConnectionStringBuilder |
1312 | { |
|
Line 1242... | Line 1313... | |||
1242 | { |
1313 | new SQLiteParameter("@hash", hash), |
|
1243 | ConnectionString = DatabaseConnectionString |
1314 | new SQLiteParameter("@note", note) |
|
1244 | }; |
1315 | }); |
|
1245 | |
1316 | |
|
1246 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1317 | sqliteCommand.Prepare(); |
|
1247 | { |
1318 | |
|
Line 1248... | Line 1319... | |||
1248 | await sqliteConnection.OpenAsync(cancellationToken); |
1319 | try |
|
- | 1320 | { |
||
1249 | |
1321 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
|
1250 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
- | ||
1251 | { |
- | ||
1252 | // Insert the file change. |
1322 | |
|
1253 | using (var sqliteCommand = |
1323 | dbTransaction.Commit(); |
|
1254 | new SQLiteCommand(UpdateNoteFromHashSql, sqliteConnection, dbTransaction)) |
1324 | |
|
1255 | { |
- | ||
- | 1325 | SnapshotNoteUpdate?.Invoke(this, new SnapshotNoteUpdateSuccessEventArgs(note)); |
||
1256 | try |
1326 | } |
|
1257 | { |
1327 | catch |
|
- | 1328 | { |
||
1258 | sqliteCommand.Parameters.AddRange(new[] |
1329 | dbTransaction.Rollback(); |
|
- | 1330 | |
||
1259 | { |
1331 | SnapshotNoteUpdate?.Invoke(this, new SnapshotNoteUpdateFailureEventArgs()); |
|
1260 | new SQLiteParameter("@hash", hash), |
1332 | |
|
1261 | new SQLiteParameter("@note", note) |
1333 | throw; |
|
1262 | }); |
1334 | } |
|
1263 | |
1335 | } |
|
1264 | sqliteCommand.Prepare(); |
1336 | } |
|
Line 1265... | Line 1337... | |||
1265 | |
1337 | } |
|
Line -... | Line 1338... | |||
- | 1338 | } |
||
- | 1339 | finally |
||
1266 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
1340 | { |
|
Line 1267... | Line 1341... | |||
1267 | |
1341 | _databaseLock.Release(); |
|
1268 | dbTransaction.Commit(); |
1342 | } |
|
1269 | |
1343 | } |
|
1270 | SnapshotNoteUpdate?.Invoke(this, new SnapshotNoteUpdateSuccessEventArgs(note)); |
1344 | |
|
1271 | } |
1345 | public async Task<string> UpdateFile(string hash, byte[] data, CancellationToken cancellationToken) |
|
Line 1272... | Line 1346... | |||
1272 | catch |
1346 | { |
|
- | 1347 | var connectionString = new SQLiteConnectionStringBuilder |
||
1273 | { |
1348 | { |
|
1274 | dbTransaction.Rollback(); |
1349 | ConnectionString = DatabaseConnectionString |
|
1275 | |
1350 | }; |
|
1276 | SnapshotNoteUpdate?.Invoke(this, new SnapshotNoteUpdateFailureEventArgs()); |
1351 | |
|
- | 1352 | await _databaseLock.WaitAsync(cancellationToken); |
||
- | 1353 | try |
||
- | 1354 | { |
||
- | 1355 | using (var dataMemoryStream = new MemoryStream(data)) |
||
1277 | |
1356 | { |
|
Line 1278... | Line 1357... | |||
1278 | throw; |
1357 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
|
Line 1279... | Line 1358... | |||
1279 | } |
1358 | { |
|
Line 1280... | Line 1359... | |||
1280 | } |
1359 | await sqliteConnection.OpenAsync(cancellationToken); |
|
1281 | } |
1360 | |
|
1282 | } |
1361 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
|
1283 | } |
1362 | { |
|
1284 | |
1363 | try |
|
1285 | public async Task<string> UpdateFile(string hash, byte[] data, CancellationToken cancellationToken) |
1364 | { |
|
Line 1286... | Line 1365... | |||
1286 | { |
1365 | using (var md5 = MD5.Create()) |
|
1287 | using (var dataMemoryStream = new MemoryStream(data)) |
1366 | { |
|
1288 | { |
1367 | using (var hashMemoryStream = new MemoryStream()) |
|
1289 | var connectionString = new SQLiteConnectionStringBuilder |
- | ||
1290 | { |
- | ||
1291 | ConnectionString = DatabaseConnectionString |
1368 | { |
|
1292 | }; |
1369 | dataMemoryStream.Position = 0L; |
|
1293 | |
1370 | await dataMemoryStream.CopyToAsync(hashMemoryStream); |
|
- | 1371 | |
||
- | 1372 | hashMemoryStream.Position = 0L; |
||
- | 1373 | var recomputedHash = md5.ComputeHash(hashMemoryStream); |
||
- | 1374 | var hashHex = BitConverter.ToString(recomputedHash).Replace("-", "") |
||
- | 1375 | .ToLowerInvariant(); |
||
1294 | using (var sqliteConnection = new SQLiteConnection(connectionString.ConnectionString)) |
1376 | |
|
- | 1377 | using (var fileMemoryStream = new MemoryStream()) |
||
1295 | { |
1378 | { |
|
1296 | await sqliteConnection.OpenAsync(cancellationToken); |
1379 | using (var fileZipStream = |
|
- | 1380 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
||
- | 1381 | { |
||
- | 1382 | dataMemoryStream.Position = 0L; |
||
- | 1383 | await dataMemoryStream.CopyToAsync(fileZipStream); |
||
1297 | |
1384 | fileZipStream.Close(); |
|
Line 1298... | Line 1385... | |||
1298 | using (var dbTransaction = sqliteConnection.BeginTransaction()) |
1385 | |
|
1299 | { |
1386 | fileMemoryStream.Position = 0L; |
|
1300 | try |
1387 | |
|
1301 | { |
1388 | // Insert the file change. |
|
1302 | using (var md5 = MD5.Create()) |
1389 | using (var sqliteCommand = |
|
1303 | { |
1390 | new SQLiteCommand(UpdateFileSql, sqliteConnection, |
|
Line 1304... | Line 1391... | |||
1304 | using (var hashMemoryStream = new MemoryStream()) |
1391 | dbTransaction)) |
|
- | 1392 | { |
||
1305 | { |
1393 | sqliteCommand.Parameters.AddRange(new[] |
|
1306 | dataMemoryStream.Position = 0L; |
- | ||
1307 | await dataMemoryStream.CopyToAsync(hashMemoryStream); |
- | ||
1308 | |
1394 | { |
|
1309 | hashMemoryStream.Position = 0L; |
1395 | new SQLiteParameter("@dataLength", fileMemoryStream.Length), |
|
1310 | var recomputedHash = md5.ComputeHash(hashMemoryStream); |
1396 | new SQLiteParameter("@recomputedHash", hashHex), |
|
- | 1397 | new SQLiteParameter("@hash", hash) |
||
1311 | var hashHex = BitConverter.ToString(recomputedHash).Replace("-", "") |
1398 | }); |
|
1312 | .ToLowerInvariant(); |
1399 | |
|
1313 | |
1400 | sqliteCommand.Prepare(); |
|
- | 1401 | await sqliteCommand.ExecuteNonQueryAsync(cancellationToken); |
||
1314 | using (var fileMemoryStream = new MemoryStream()) |
1402 | } |
|
- | 1403 | |
||
- | 1404 | using (var sqliteCommand = |
||
1315 | { |
1405 | new SQLiteCommand(GetRowFromHashSql, sqliteConnection, |
|
Line 1316... | Line 1406... | |||
1316 | using (var fileZipStream = |
1406 | dbTransaction)) |
|
1317 | new GZipStream(fileMemoryStream, CompressionMode.Compress, true)) |
1407 | { |
|
1318 | { |
1408 | sqliteCommand.Parameters.AddRange(new[] |
|
1319 | dataMemoryStream.Position = 0L; |
1409 | { |
|
1320 | await dataMemoryStream.CopyToAsync(fileZipStream); |
1410 | new SQLiteParameter("@hash", hashHex) |
|
Line 1321... | Line 1411... | |||
1321 | fileZipStream.Close(); |
1411 | }); |
|
- | 1412 | |
||
1322 | |
1413 | sqliteCommand.Prepare(); |
|
1323 | fileMemoryStream.Position = 0L; |
1414 | |
|
1324 | |
1415 | using (var sqlDataReader = |
|
1325 | // Insert the file change. |
1416 | await sqliteCommand.ExecuteReaderAsync(cancellationToken)) |
|
- | 1417 | { |
||
- | 1418 | while (await sqlDataReader.ReadAsync(cancellationToken)) |
||
- | 1419 | { |
||
- | 1420 | if (sqlDataReader["id"] is long rowId) |
||
1326 | using (var sqliteCommand = |
1421 | { |
|
Line 1327... | Line 1422... | |||
1327 | new SQLiteCommand(UpdateFileSql, sqliteConnection, dbTransaction)) |
1422 | using (var sqliteBlob = SQLiteBlob.Create( |
|
1328 | { |
1423 | sqliteConnection, |
|
1329 | sqliteCommand.Parameters.AddRange(new[] |
1424 | "main", |
|
1330 | { |
1425 | "Snapshots", |