public void Checkpoint()
 {
     lock (connection) {
         // Commit any outstanding changes and open a new transaction
         SqliteUtils.DoNonQuery(connection, "COMMIT");
         SqliteUtils.DoNonQuery(connection, "BEGIN");
     }
 }
Beispiel #2
0
 private void MaybeStartTransaction_Unlocked()
 {
     if (transaction_state == TransactionState.Requested)
     {
         SqliteUtils.DoNonQuery(connection, "BEGIN");
     }
     transaction_state = TransactionState.Started;
 }
        public EvolutionSummaryTracker(string directory, string account_name, string folder_name)
        {
            // Make the on-disk files for folders have sane names
            folder_name = folder_name.Replace('/', '-');
            folder_name = folder_name.Replace(':', '_');
            folder_name = folder_name.Replace(',', ' ');              // Causes problems with the ConnectionString otherwise

            string filename      = Path.Combine(directory, String.Format("SummaryTracker-{0}-{1}.db", account_name, folder_name));
            bool   create_new_db = !File.Exists(filename);
            bool   purge_old_db  = false;

            connection = GetConnection(filename);
            try {
                connection.Open();
            } catch (ApplicationException) {
                purge_old_db = true;
            }

            if (!create_new_db && !purge_old_db)
            {
                // Run a dummy SELECT statement to catch more errors
                // indicating sqlite version mismatches.
                using (SqliteCommand command = new SqliteCommand()) {
                    command.Connection  = connection;
                    command.CommandText = "SELECT flags FROM mapping WHERE uid = 'fo/ky'";

                    SqliteDataReader reader;

                    try {
                        reader = SqliteUtils.ExecuteReaderOrWait(command);
                        reader.Close();
                    } catch (ApplicationException) {
                        purge_old_db = true;
                    }
                }
            }

            if (purge_old_db)
            {
                connection.Dispose();

                // Purge the old database and create a new one
                File.Delete(filename);
                connection = GetConnection(filename);
                connection.Open();

                create_new_db = true;
            }

            if (create_new_db)
            {
                CreateDatabase();
            }

            // Start a transaction for any updates
            SqliteUtils.DoNonQuery(connection, "BEGIN");
        }
 public void Remove(string uid)
 {
     lock (connection) {
         SqliteUtils.DoNonQuery(connection,
                                "DELETE FROM mapping WHERE uid=@uid",
                                new string [] { "@uid" },
                                new object [] { uid });
     }
 }
Beispiel #5
0
 public void AddLinks(Uri uri, IList <string> links)
 {
     lock (connection) {
         MaybeStartTransaction_Unlocked();
         UpdateLinksCommand.Parameters.AddWithValue("@uri", UriToString(uri));
         UpdateLinksCommand.Parameters.AddWithValue("@links", GetLinksText(links));
         SqliteUtils.DoNonQuery(UpdateLinksCommand);
     }
 }
 public void CommitTransaction()
 {
     if (transaction_state == TransactionState.Started)
     {
         lock (connection)
             SqliteUtils.DoNonQuery(connection, "COMMIT");
     }
     transaction_state = TransactionState.None;
 }
        public void Close()
        {
            lock (connection) {
                // Commit any outstanding changes
                SqliteUtils.DoNonQuery(connection, "COMMIT");

                connection.Close();
                connection = null;
            }
        }
Beispiel #8
0
 private void Insert(Uri uri, string filename, byte[] data)
 {
     lock (connection) {
         MaybeStartTransaction_Unlocked();
         InsertCommand.Parameters.AddWithValue("@uri", UriToString(uri));
         InsertCommand.Parameters.AddWithValue("@filename", filename);
         InsertCommand.Parameters.AddWithValue("@data", data);
         SqliteUtils.DoNonQuery(InsertCommand);
     }
 }
 public void Update(string uid, uint flags)
 {
     lock (connection) {
         SqliteUtils.DoNonQuery(connection,
                                "INSERT OR REPLACE INTO mapping " +
                                "  (uid, flags, last_seen) " +
                                "  VALUES (@uid, @flags, @last_seen)",
                                new string [] { "@uid", "@flags", "@last_seen" },
                                new object [] { uid, flags, StringFu.DateTimeToString(DateTime.UtcNow) });
     }
 }
 public void Flush()
 {
     lock (connection) {
         if (transaction_count > 0)
         {
             Logger.Log.Debug("Flushing requested -- committing sqlite transaction");
             SqliteUtils.DoNonQuery(connection, "COMMIT");
             transaction_count = 0;
         }
     }
 }
        private void CreateDatabase()
        {
            SqliteUtils.DoNonQuery(connection,
                                   "CREATE TABLE mapping (        " +
                                   "  uid       TEXT    UNIQUE,   " +
                                   "  flags     INTEGER NOT NULL, " +
                                   "  last_seen TEXT    NOT NULL  " +
                                   ")");

            SqliteUtils.DoNonQuery(connection,
                                   "CREATE INDEX mapping_uid on mapping (uid)");
        }
Beispiel #12
0
 public void Delete(Uri uri)
 {
     lock (connection) {
         string path = LookupPathRawUnlocked(uri);
         if (path != null)
         {
             MaybeStartTransaction_Unlocked();
             DeleteCommand.Parameters.AddWithValue("@uri", UriToString(uri));
             SqliteUtils.DoNonQuery(DeleteCommand);
             if (path != SELF_CACHE_TAG && path != BLOB_TAG)
             {
                 File.Delete(Path.Combine(text_cache_dir, path));
             }
         }
     }
 }
        public bool Write(FileAttributes fa)
        {
            SetPathFlag(fa.Path);
            int    ret = 0;
            string filter_name;

            // We need to quote any 's that appear in the strings
            // (in particular, in the path)
            lock (connection) {
                // If a transaction has been requested, start it now.
                MaybeStartTransaction();

                filter_name = fa.FilterName;
                if (filter_name == null)
                {
                    filter_name = "";
                }
                filter_name = filter_name.Replace("'", "''");
                string[] param = new string [] { "@unique_id", "@directory", "@filename", "@last_mtime", "@last_attrtime", "@filter_name", "@filter_version" };
                object[] vals  = new object [] {
                    GuidFu.ToShortString(fa.UniqueId),
                    fa.Directory.Replace("'", "''"), fa.Filename.Replace("'", "''"),
                    StringFu.DateTimeToString(fa.LastWriteTime),
                    StringFu.DateTimeToString(fa.LastAttrTime),
                    filter_name,
                    fa.FilterVersion
                };
                for (int i = 0; i < param.Length; i++)
                {
                    InsertCommand.Parameters.AddWithValue(param[i], vals[i]);
                }

                ret = SqliteUtils.DoNonQuery(InsertCommand);
            }

            return(ret != 0);
        }
        public void Drop(string path)
        {
            // Sanitize the path; remove the last '/'
            if (path != null && path != "/" && path.EndsWith("/"))
            {
                path = path.TrimEnd('/');
            }

            // We don't want to "UnSetPathFlag" here, since we have no way of knowing
            // if another path hashes to the same value as this one.

            // We need to quote any 's that appear in the strings
            // (in particular, in the path)
            string directory = FileSystem.GetDirectoryNameRootOk(path).Replace("'", "''");
            string filename  = Path.GetFileName(path).Replace("'", "''");

            lock (connection) {
                // If a transaction has been requested, start it now.
                MaybeStartTransaction();
                DeleteCommand.Parameters.AddWithValue("@directory", directory);
                DeleteCommand.Parameters.AddWithValue("@filename", filename);
                SqliteUtils.DoNonQuery(DeleteCommand);
            }
        }
Beispiel #15
0
        public TextCache(string storage_dir, bool read_only)
        {
            text_cache_dir = Path.Combine(storage_dir, "TextCache");
            if (!Directory.Exists(text_cache_dir))
            {
                Directory.CreateDirectory(text_cache_dir);

                // Create our cache subdirectories.
                for (int i = 0; i < 256; ++i)
                {
                    string subdir = i.ToString("x");
                    if (i < 16)
                    {
                        subdir = "0" + subdir;
                    }
                    subdir = Path.Combine(text_cache_dir, subdir);
                    Directory.CreateDirectory(subdir);
                }
            }

            // Create our Sqlite database
            string db_filename   = Path.Combine(text_cache_dir, "TextCache.db");
            bool   create_new_db = false;

            if (!File.Exists(db_filename))
            {
                create_new_db = true;
            }

            // Funky logic here to deal with sqlite versions.
            //
            // When sqlite 3 tries to open an sqlite 2 database,
            // it will throw an SqliteException with SqliteError
            // NOTADB when trying to execute a command.
            //
            // When sqlite 2 tries to open an sqlite 3 database,
            // it will throw an ApplicationException when it
            // tries to open the database.

            try {
                connection = Open(db_filename);
            } catch (ApplicationException) {
                Logger.Log.Warn("Likely sqlite database version mismatch trying to open {0}.  Purging.", db_filename);
                create_new_db = true;
            }

            if (!create_new_db)
            {
                // Run a dummy query to see if we get a NOTADB error.  Sigh.
                SqliteCommand    command;
                SqliteDataReader reader = null;

                command             = new SqliteCommand();
                command.Connection  = connection;
                command.CommandText =
                    "SELECT filename FROM textcache_data WHERE uri='blah'";

                try {
                    reader = SqliteUtils.ExecuteReaderOrWait(command);
                } catch (ApplicationException ex) {
                    Logger.Log.Warn("Likely sqlite database version mismatch trying to read from {0}.  Purging.", db_filename);
                    create_new_db = true;
                } catch (SqliteException ex) {
                    // When the table name changed from 0.2.18 -> 0.3.0.
                    Logger.Log.Warn("Sqlite error: {0}. Purging textcache.", ex.Message);
                    create_new_db = true;
                }

                if (reader != null)
                {
                    reader.Dispose();
                }
                command.Dispose();
            }

            if (create_new_db)
            {
                if (connection != null)
                {
                    connection.Dispose();
                }

                if (read_only)
                {
                    throw new UnauthorizedAccessException(String.Format("Unable to create read only text cache {0}", db_filename));
                }

                File.Delete(db_filename);

                try {
                    connection = Open(db_filename);
                } catch (Exception e) {
                    Log.Debug(e, "Exception opening text cache {0}", db_filename);
                }

                // Database schema: uri, filename, data
                SqliteUtils.DoNonQuery(connection,
                                       "CREATE TABLE textcache_data (     " +
                                       "  uri      TEXT UNIQUE NOT NULL,  " +
                                       "  filename TEXT NOT NULL,         " +
                                       "  data     BLOB                   " +
                                       ")");
            }
#if ENABLE_RDF_ADAPTER
            try {
                SqliteUtils.DoNonQuery(connection,
                                       "CREATE TABLE IF NOT EXISTS links_data (  " +
                                       "  uri TEXT UNIQUE NOT NULL,		  "+
                                       "  links TEXT				  "+
                                       ")");
            } catch (SqliteException) { }
#endif
            this.InitCommands();
        }
        public FileAttributesStore_Sqlite(string directory, string index_fingerprint)
        {
            bool create_new_db = false;

            path_flags = new BitArray(65536);

            if (!File.Exists(GetDbPath(directory)))
            {
                create_new_db = true;
            }
            else
            {
                // Funky logic here to deal with sqlite versions.
                //
                // When sqlite 3 tries to open an sqlite 2 database,
                // it will throw an SqliteException with SqliteError
                // NOTADB when trying to execute a command.
                //
                // When sqlite 2 tries to open an sqlite 3 database,
                // it will throw an ApplicationException when it
                // tries to open the database.

                try {
                    connection = Open(directory);
                } catch (ApplicationException) {
                    Logger.Log.Warn("Likely sqlite database version mismatch trying to open {0}.  Purging.", GetDbPath(directory));
                    create_new_db = true;
                }

                if (!create_new_db)
                {
                    SqliteCommand    command;
                    SqliteDataReader reader   = null;
                    int    stored_version     = 0;
                    string stored_fingerprint = null;


                    command             = new SqliteCommand();
                    command.Connection  = connection;
                    command.CommandText =
                        "SELECT version, fingerprint FROM db_info";
                    try {
                        reader = SqliteUtils.ExecuteReaderOrWait(command);
                    } catch (Exception ex) {
                        Logger.Log.Warn("Likely sqlite database version mismatch trying to read from {0}.  Purging.", GetDbPath(directory));
                        create_new_db = true;
                    }
                    if (reader != null && !create_new_db)
                    {
                        if (SqliteUtils.ReadOrWait(reader))
                        {
                            stored_version     = reader.GetInt32(0);
                            stored_fingerprint = reader.GetString(1);
                        }
                        reader.Close();
                    }
                    command.Dispose();

                    if (VERSION != stored_version ||
                        (index_fingerprint != null && index_fingerprint != stored_fingerprint))
                    {
                        create_new_db = true;
                    }
                }
            }

            if (create_new_db)
            {
                if (connection != null)
                {
                    connection.Dispose();
                }
                File.Delete(GetDbPath(directory));
                connection = Open(directory);

                SqliteUtils.DoNonQuery(connection,
                                       "CREATE TABLE db_info (             " +
                                       "  version       INTEGER NOT NULL,  " +
                                       "  fingerprint   TEXT NOT NULL    " +
                                       ")");

                SqliteUtils.DoNonQuery(connection,
                                       "INSERT INTO db_info (version, fingerprint) VALUES (@version, @index_fingerprint)",
                                       new string [] { "@version", "@index_fingerprint" },
                                       new object [] { VERSION, index_fingerprint });

                SqliteUtils.DoNonQuery(connection,
                                       "CREATE TABLE file_attributes (         " +
                                       "  unique_id      TEXT NOT NULL,        " +
                                       "  directory      TEXT NOT NULL,        " +
                                       "  filename       TEXT NOT NULL,        " +
                                       "  last_mtime     TEXT NOT NULL,        " +
                                       "  last_attrtime  TEXT NOT NULL,        " +
                                       "  filter_name    TEXT NOT NULL,        " +
                                       "  filter_version TEXT NOT NULL,        " +
                                       "  UNIQUE (directory, filename)         " +
                                       ")");
            }
            else
            {
                SqliteCommand    command;
                SqliteDataReader reader;
                int count = 0;

                DateTime dt1 = DateTime.Now;

                // Select all of the files and use them to populate our bit-vector.
                command             = new SqliteCommand();
                command.Connection  = connection;
                command.CommandText = "SELECT directory, filename FROM file_attributes";

                reader = SqliteUtils.ExecuteReaderOrWait(command);

                while (SqliteUtils.ReadOrWait(reader))
                {
                    string dir  = reader.GetString(0);
                    string file = reader.GetString(1);
                    string path = Path.Combine(dir, file);
                    SetPathFlag(path);
                    ++count;
                }

                reader.Close();
                command.Dispose();

                DateTime dt2 = DateTime.Now;

                Logger.Log.Debug("Loaded {0} records from {1} in {2:0.000}s",
                                 count, GetDbPath(directory), (dt2 - dt1).TotalSeconds);
            }
            ReadCommand             = new SqliteCommand(this.connection);
            ReadCommand.CommandText = "SELECT unique_id, directory, filename, last_mtime, last_attrtime, filter_name, filter_version " +
                                      "FROM file_attributes WHERE directory=@dir AND filename=@fname";
            InsertCommand             = new SqliteCommand(this.connection);
            InsertCommand.CommandText = "INSERT OR REPLACE INTO file_attributes " +
                                        " (unique_id, directory, filename, last_mtime, last_attrtime, filter_name, filter_version) " +
                                        " VALUES (@unique_id, @directory, @filename, @last_mtime, @last_attrtime, @filter_name, @filter_version)";
            DeleteCommand             = new SqliteCommand(this.connection);
            DeleteCommand.CommandText = "DELETE FROM file_attributes WHERE directory=@directory AND filename=@filename";
        }