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