public bool Get(string uid, out uint flags)
        {
            SqliteCommand    command;
            SqliteDataReader reader;

            lock (connection) {
                command             = new SqliteCommand();
                command.Connection  = connection;
                command.CommandText = String.Format(
                    "SELECT flags FROM mapping WHERE uid='{0}'",
                    uid.Replace("'", "''"));

                reader = SqliteUtils.ExecuteReaderOrWait(command);

                try {
                    if (SqliteUtils.ReadOrWait(reader))
                    {
                        flags = (uint)reader.GetInt32(0);
                        return(true);
                    }
                    else
                    {
                        flags = 0;
                        return(false);
                    }
                } finally {
                    reader.Close();
                    command.Dispose();
                }
            }
        }
        // FIXME: I don't really like this, the collection could be huge
        public ArrayList GetOlderThan(DateTime dt)
        {
            SqliteCommand    command;
            SqliteDataReader reader;

            lock (connection) {
                command             = new SqliteCommand();
                command.Connection  = connection;
                command.CommandText =
                    "SELECT uid FROM mapping WHERE last_seen < " +
                    StringFu.DateTimeToString(dt);

                reader = SqliteUtils.ExecuteReaderOrWait(command);

                ArrayList uids = new ArrayList();

                while (SqliteUtils.ReadOrWait(reader))
                {
                    uids.Add(reader.GetString(0));
                }

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

                return(uids);
            }
        }
        ///////////////////////////////////////////////////////////////////

        // Return all attributes in the attributes database, used for merging

        private ICollection ReadAllAttributes()
        {
            ArrayList attributes = new ArrayList();

            SqliteCommand    command;
            SqliteDataReader reader;

            lock (connection) {
                command             = new SqliteCommand();
                command.Connection  = connection;
                command.CommandText =
                    "SELECT unique_id, directory, filename, last_mtime, last_attrtime, filter_name, filter_version " +
                    "FROM file_attributes";

                reader = SqliteUtils.ExecuteReaderOrWait(command);

                while (SqliteUtils.ReadOrWait(reader))
                {
                    attributes.Add(GetFromReader(reader));
                }
                reader.Close();
                command.Dispose();
            }

            return(attributes);
        }
        ///////////////////////////////////////////////////////////////////

        public FileAttributes Read(string path)
        {
            // Sanitize the path; remove the last '/'
            if (path != null && path != "/" && path.EndsWith("/"))
            {
                path = path.TrimEnd('/');
            }

            if (!GetPathFlag(path))
            {
                return(null);
            }

            FileAttributes attr = null;

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

            lock (connection) {
                ReadCommand.Parameters.AddWithValue("@dir", directory);
                ReadCommand.Parameters.AddWithValue("@fname", filename);
                using (SqliteDataReader reader = SqliteUtils.ExecuteReaderOrWait(ReadCommand)) {
                    if (SqliteUtils.ReadOrWait(reader))
                    {
                        attr = GetFromReader(reader);
                    }
                }
            }

            return(attr);
        }
        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");
        }
Exemple #6
0
        // Returns raw path as stored in the db i.e. relative path wrt the text_cache_dir
        private string LookupPathRawUnlocked(Uri uri)
        {
            //SqliteCommand command;
            string path = null;

            LookupPathCommand.Parameters.AddWithValue("@uri", UriToString(uri));
            using (SqliteDataReader reader = SqliteUtils.ExecuteReaderOrWait(LookupPathCommand)) {
                if (SqliteUtils.ReadOrWait(reader))
                {
                    path = reader.GetString(0);
                }
            }

            return(path);
        }
Exemple #7
0
        public IList <string> GetLinks(Uri uri)
        {
            string        links_text = null;
            List <string> links      = null;

            lock (connection) {
                LookupLinksCommand.Parameters.AddWithValue("@uri", UriToString(uri));
                using (SqliteDataReader reader = SqliteUtils.ExecuteReaderOrWait(LookupLinksCommand)) {
                    if (!SqliteUtils.ReadOrWait(reader))
                    {
                        return(null);
                    }

                    links_text = reader.GetString(0);
                }
            }

            if (String.IsNullOrEmpty(links_text))
            {
                return(null);
            }

            return(links_text.Split(links_separator, StringSplitOptions.RemoveEmptyEntries));
        }
Exemple #8
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();
        }
Exemple #9
0
        // If self_cache is true when called, then self_cache will be set upon return
        public TextReader GetReader(Uri uri, ref bool self_cache)
        {
            byte[] blob     = null;
            string filename = null;

            lock (connection) {
                LookupDataCommand.Parameters.AddWithValue("@uri", UriToString(uri));
                using (SqliteDataReader reader = SqliteUtils.ExecuteReaderOrWait(LookupDataCommand)) {
                    if (!SqliteUtils.ReadOrWait(reader))
                    {
                        if (self_cache)
                        {
                            self_cache = false;
                        }
                        return(null);
                    }

                    filename = reader.GetString(0);
                    if (!reader.IsDBNull(1))
                    {
                        blob = reader.GetValue(1) as byte [];
                    }
                }
            }

            if (filename == SELF_CACHE_TAG)
            {
                if (self_cache)
                {
                    self_cache = true;
                    return(null);
                }

                if (!uri.IsFile)
                {
                    string msg = String.Format("non-file uri {0} flagged as self-cached", uri);
                    throw new Exception(msg);
                }
                return(new StreamReader(uri.LocalPath));
            }

            if (self_cache)
            {
                self_cache = false;
            }

            if (filename == BLOB_TAG && (blob == null || blob.Length == 0))
            {
                return(null);
            }

            Stream stream;

            if (filename == BLOB_TAG)
            {
                stream = new MemoryStream(blob);
            }
            else
            {
                stream = new FileStream(Path.Combine(text_cache_dir, filename), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            }

            stream = new GZipInputStream(stream);
            TextReader text_reader = new StreamReader(new BufferedStream(stream));

            return(text_reader);
        }
        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";
        }