public void PutBlob(string filename, byte[] data) { // Guard if (String.IsNullOrEmpty(filename)) { throw new Exception("Can't store in LibraryDB with null filename."); } // Calculate the MD5 of this blobbiiiieeeeee string md5 = StreamMD5.FromBytes(data); using (var connection = GetConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using (var command = new SQLiteCommand("DELETE FROM LibraryItem WHERE filename=@filename", connection, transaction)) { command.Parameters.AddWithValue("@filename", filename); command.ExecuteNonQuery(); } using (var command = new SQLiteCommand("INSERT INTO LibraryItem(filename, last_updated_by, md5, data) VALUES(@filename, @last_updated_by, @md5, @data)", connection, transaction)) { command.Parameters.AddWithValue("@filename", filename); command.Parameters.AddWithValue("@last_updated_by", Environment.UserName); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.ExecuteNonQuery(); } transaction.Commit(); } } }
internal void PutBlob(SQLiteConnection connection, SQLiteTransaction transaction, string fingerprint, string extension, byte[] data) { // Calculate the MD5 of this blobbiiiieeeeee string md5 = StreamMD5.FromBytes(data); using (var command = new SQLiteCommand("INSERT INTO LibraryItem(fingerprint, extension, md5, data) VALUES(@fingerprint, @extension, @md5, @data)", connection, transaction)) { command.Parameters.AddWithValue("@fingerprint", fingerprint); command.Parameters.AddWithValue("@extension", extension); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.ExecuteNonQuery(); } }
public void PutBlob(string fingerprint, string extension, byte[] data) { // Guard if (String.IsNullOrEmpty(fingerprint)) { throw new Exception("Can't store in LibraryDB with null fingerprint."); } if (String.IsNullOrEmpty(extension)) { throw new Exception("Can't store in LibraryDB with null extension."); } // Calculate the MD5 of this blobbiiiieeeeee string md5 = StreamMD5.FromBytes(data); using (var connection = GetConnection()) { connection.Open(); bool managed_update = false; using (var command = new SQLiteCommand("UPDATE LibraryItem SET MD5=@md5, DATA=@data WHERE fingerprint=@fingerprint AND extension=@extension", connection)) { command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.Parameters.AddWithValue("@fingerprint", fingerprint); command.Parameters.AddWithValue("@extension", extension); int num_rows_updated = command.ExecuteNonQuery(); if (1 == num_rows_updated) { managed_update = true; } } if (!managed_update) { using (var command = new SQLiteCommand("INSERT INTO LibraryItem(fingerprint, extension, md5, data) VALUES(@fingerprint, @extension, @md5, @data)", connection)) { command.Parameters.AddWithValue("@fingerprint", fingerprint); command.Parameters.AddWithValue("@extension", extension); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.ExecuteNonQuery(); } } } }
public void PutBlob(string fingerprint, string extension, byte[] data) { // Guard if (String.IsNullOrWhiteSpace(fingerprint)) { throw new Exception("Can't store in LibraryDB with null fingerprint."); } if (String.IsNullOrWhiteSpace(extension)) { throw new Exception("Can't store in LibraryDB with null extension."); } // Calculate the MD5 of this blobbiiiieeeeee string md5 = StreamMD5.FromBytes(data); try { lock (DBAccessLock.db_access_lock) { using (var connection = GetConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { bool managed_update = false; using (var command = new SQLiteCommand("UPDATE LibraryItem SET MD5=@md5, DATA=@data WHERE fingerprint=@fingerprint AND extension=@extension", connection, transaction)) { command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.Parameters.AddWithValue("@fingerprint", fingerprint); command.Parameters.AddWithValue("@extension", extension); int num_rows_updated = command.ExecuteNonQuery(); if (1 == num_rows_updated) { managed_update = true; } } if (!managed_update) { using (var command = new SQLiteCommand("INSERT INTO LibraryItem(fingerprint, extension, md5, data) VALUES(@fingerprint, @extension, @md5, @data)", connection, transaction)) { command.Parameters.AddWithValue("@fingerprint", fingerprint); command.Parameters.AddWithValue("@extension", extension); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.ExecuteNonQuery(); } } transaction.Commit(); } connection.Close(); } // // see SO link above at the `DBAccessLock.db_access_lock` declaration. // // We keep this *inside* the critical section so that we know we'll be the only active SQLite // action which just transpired. // *This* is also the reason why I went with a *global* lock (singleton) for *all* databases, // even while *theoretically* this is *wrong* or rather: *unnecessary* as the databases // i.e. Qiqqa Libraries shouldn't bite one another. I, however, need to ensure that the // added `System.Data.SQLite.SQLiteConnection.ClearAllPools();` statements don't foul up // matters in library B while lib A I/O is getting cleaned up. // // In short: Yuck. + Cave canem. // SQLiteConnection.ClearAllPools(); } } catch (Exception ex) { Logging.Error(ex, "LibraryDB::PutBLOB: Database I/O failure for DB '{0}'.", library_path); LibraryDB.FurtherDiagnoseDBProblem(ex, null, library_path); throw; } }
private static int DoDownloads(Library library, bool restricted_metadata_sync, Dictionary <string, string> historical_sync_file, SynchronisationAction synchronisation_action) { int download_count = 0; StatusManager.Instance.ClearCancelled(StatusCodes.SYNC_META(library)); foreach (SynchronisationState ss in synchronisation_action.states_to_download) { StatusManager.Instance.UpdateStatus(StatusCodes.SYNC_META(library), String.Format("Downloading metadata from your Web/Intranet Library ({0} to go)", synchronisation_action.states_to_download.Count - download_count), download_count, synchronisation_action.states_to_download.Count, true); ++download_count; // Has the user cancelled? if (StatusManager.Instance.IsCancelled(StatusCodes.SYNC_META(library))) { Logging.Info("User has cancelled their metadata download"); break; } try { Logging.Info("+Downloading {0}", ss.filename); StoredUserFile stored_user_file = null; // --- TODO: Replace this with a pretty interface class ------------------------------------------------ if (false) { } else if (library.WebLibraryDetail.IsIntranetLibrary) { stored_user_file = SynchronisationExecutor_Intranet.DoDownload(library, ss); } else { throw new Exception(String.Format("Did not understand how to download for library {0}", library.WebLibraryDetail.Title)); } // ----------------------------------------------------------------------------------------------------- Logging.Info("-Downloading {0}", ss.filename); { // Check that the MD5s match, or we have had some issue in the download Logging.Info("Checking content"); string md5_metadata = StreamMD5.FromBytes(stored_user_file.Content); string header_etag = stored_user_file.Md5; string header_etag_nik = header_etag; if (null != header_etag && !String.IsNullOrEmpty(header_etag) && 0 != String.Compare(md5_metadata, header_etag, true) && 0 != String.Compare(md5_metadata, header_etag_nik, true)) { throw new Exception(String.Format("Local and remote MD5s do not match. local={0} remote={1} remote_nik={2}", md5_metadata, header_etag, header_etag_nik)); } Logging.Info("Copying content"); library.LibraryDB.PutBlob(ss.fingerprint, ss.extension, stored_user_file.Content); // Remember this MD5 for our sync clash detection Logging.Info("Remembering md5"); historical_sync_file[ss.filename] = md5_metadata; } } catch (Exception ex) { Logging.Error(ex, "There was a problem downloading one of your sync files"); } } StatusManager.Instance.UpdateStatus(StatusCodes.SYNC_META(library), String.Format("Downloaded {0} metadata from your Web/Intranet Library", download_count)); return(download_count); }
public void PutBlob(string filename, byte[] data) { // Guard if (String.IsNullOrWhiteSpace(filename)) { throw new Exception("Can't store in LibraryDB with null filename."); } // Calculate the MD5 of this blobbiiiieeeeee string md5 = StreamMD5.FromBytes(data); lock (DBAccessLock.db_access_lock) { using (var connection = GetConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { bool managed_update = false; using (var command = new SQLiteCommand("UPDATE LibraryItem SET MD5=@md5, DATA=@data, LAST_UPDATED_BY=@last_updated_by WHERE filename=@filename", connection, transaction)) { command.Parameters.AddWithValue("@filename", filename); command.Parameters.AddWithValue("@last_updated_by", Environment.UserName); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); int num_rows_updated = command.ExecuteNonQuery(); if (1 == num_rows_updated) { managed_update = true; } } if (!managed_update) { using (var command = new SQLiteCommand("INSERT INTO LibraryItem(filename, last_updated_by, md5, data) VALUES(@filename, @last_updated_by, @md5, @data)", connection, transaction)) { command.Parameters.AddWithValue("@filename", filename); command.Parameters.AddWithValue("@last_updated_by", Environment.UserName); command.Parameters.AddWithValue("@md5", md5); command.Parameters.AddWithValue("@data", data); command.ExecuteNonQuery(); } } transaction.Commit(); } connection.Close(); } // // see SO link in ../LibraryDB.cs at the `DBAccessLock.db_access_lock` declaration. // // We keep this *inside* the critical section so that we know we'll be the only active SQLite // action which just transpired. // *This* is also the reason why I went with a *global* lock (singeton) for *all* databases, // even while *theoretically* this is *wrong* or rather: *unneccessary* as the databases // i.e. Qiqqa Libraries shouldn't bite one another. I, however, need to ensure that the // added `System.Data.SQLite.SQLiteConnection.ClearAllPools();` statements don't foul up // matters in another library while lib A I/O is getting cleaned up. // // In short: Yuck. + Cave canem. // SQLiteConnection.ClearAllPools(); } }