Exemple #1
0
        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;
            }
        }
Exemple #5
0
        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();
            }
        }