// write given buffer to db // displays form to user to please wait // could make use of BackgroundWorker to prevent lockup, or async public void Write(WatcherEventBuffer buffer) { // get lock on db lock (lockObj) { // ensure the connection is alive first if (!AliveCheck()) { return; } // get buffer as new queue (to avoid having to keep is locked during DB write) Queue <WatcherEventArgs> queue = buffer.DequeueToQueue(); // form to display to user while writing to db FormWriteWait waitForm = new FormWriteWait(); waitForm.Show(); waitForm.Refresh(); try { // create command obj SQLiteCommand com = sqlite_connection.CreateCommand(); while (queue.Count > 0) { // dequque WatcherEventArgs args = queue.Dequeue(); // generate insert and execute com.CommandText = GenerateInsert(args); com.ExecuteNonQuery(); } } catch (Exception e) { // check if is an SQLite exception // just to avoid having to do 2 of almost the same catch blocks if (e is SQLiteException) { System.Windows.Forms.MessageBox.Show(string.Format("Failed to write to database\nSQLite Exception: {0}", e.Message)); } else { System.Windows.Forms.MessageBox.Show(string.Format("Failed to write to database\nException: {0}", e.Message)); } } // close form waitForm.Close(); // pass remaining queue back to buffer (if there was an error) while (queue.Count > 0) { buffer.Enqueue(queue.Dequeue()); } } }
// methods // log method, compiles event message, reports to screen/log file // string fullPath, absolute path to item changed // string change, change that occurred private static void Event(string fullPath, string change) { // determine if item was file or directory for message // cannot use DirectoryInfo/FileInfo because if created file is changed/renames right after they will not function properly // various other edge cases like that // also does not work with deletes string itemType = "unknown"; string itemName = fullPath; // tokenize by '\' string[] toks = fullPath.Split('\\'); // grab last token as itemName itemName = toks[toks.Length - 1]; // treat as, if contains '.' then is a file - else directory if (itemName.Contains(".")) { // get extension name toks = itemName.Split('.'); itemType = toks[toks.Length - 1]; } else { itemType = "Directory"; } // ignore updates on "unknown" or "directory" types if (itemType == "unknown" || itemType == "Directory") { return; } // check if item type is filtered if (filters.Filtered(itemType)) { return; } // Build arguments for event WatcherEventArgs args = new WatcherEventArgs(itemType, itemName, fullPath, change, DateTime.Now); // Invoke event for Form // ? to check for null, in case of race conditions // but shouldn't happen as long as Monitor sets up the event fnc before path and watching variable watcherEvent?.Invoke(args); }
// generates Insert statement for args private string GenerateInsert(WatcherEventArgs args) { // convert DateTime from args to unix time (in seconds) DateTimeOffset offset = args.EventDateTime; long unixTimeStamp = offset.ToUnixTimeSeconds(); // doesn't save UTC offset of machine, so on db query conversion will use current UTC machine to convert // generate and return insert return(string.Format("INSERT INTO '{0}' {1} VALUES ('{2}','{3}','{4}','{5}',{6});", currentTableName, TableSchema(), args.ItemName, args.ItemType, args.Path, args.EventName, unixTimeStamp)); }
// Watcher event public void EH_MonitorEvent(WatcherEventArgs args) { if (DataGridViewEvents.InvokeRequired) { // Need to invoke so is on main thread WatcherEventHandler handler = EH_MonitorEvent; Invoke(handler, args); } else { // add to data grid DataGridViewEvents.Rows.Add(args.ItemName, args.ItemType, args.Path, args.EventName, args.EventDateTime); // only push to buffer if db is active if (eventDB.Active) { // push to buffer eventBuffer.Enqueue(args); } } }
// query for list of extensions public List <WatcherEventArgs> QueryFor(List <string> extList) { // get lock on db lock (lockObj) { List <WatcherEventArgs> queryResults = new List <WatcherEventArgs>(); // ensure the connection is alive first if (!AliveCheck()) { return(queryResults); } // sqlite command obj SQLiteCommand com = null; // sqlite reader obj SQLiteDataReader reader = null; try { // create command com = sqlite_connection.CreateCommand(); // build query com.CommandText = GenerateQuery(extList); // create data reader reader = com.ExecuteReader(); // loop through reader while (reader.Read()) { // retrieve info, build new args, add to list WatcherEventArgs parsed = ParseRead(reader); if (parsed != null) { queryResults.Add(parsed); } } } catch (Exception e) { // check if is an SQLite exception // just to avoid having to do 2 of almost the same catch blocks if (e is SQLiteException) { System.Windows.Forms.MessageBox.Show(string.Format("Failed to query database\nSQLite Exception: {0}", e.Message)); } else { System.Windows.Forms.MessageBox.Show(string.Format("Failed to query database\nException: {0}", e.Message)); } } finally { // cleanup if (com != null) { if (reader != null) { reader.Dispose(); } com.Dispose(); } } return(queryResults); } }
// Enqueue public void Enqueue(WatcherEventArgs watcherEvent) { lock (lockObj) { buffer.Enqueue(watcherEvent); } }