[rhythmbox] rhythmdb: process file move events (bug #620857)



commit 1959bde6d3117c1aff55e7470d0576458243990f
Author: Jonathan Matthew <jonathan d14n org>
Date:   Fri Jun 11 23:13:01 2010 +1000

    rhythmdb: process file move events (bug #620857)
    
    When built against glib 2.24 or newer, we can request file move events
    from the file monitor.  We handle file move events by just updating the
    location of the entry, or deleting it if an entry already exists for the
    new location.
    
    While we're in there, simplify processing of file create/modify and delete
    events.  We don't need to send the event through the rhythmdb event queue,
    we can just make the required changes directly.  In the case of new files,
    we can just pass the URI to rhythmdb_add_uri().
    
    Based on a patch by Philipp Kerling <k philipp gmail com>

 rhythmdb/rhythmdb-monitor.c |   60 +++++++++++++++++++++++++++++++++----------
 rhythmdb/rhythmdb-private.h |    2 -
 rhythmdb/rhythmdb.c         |   54 +++++---------------------------------
 3 files changed, 53 insertions(+), 63 deletions(-)
---
diff --git a/rhythmdb/rhythmdb-monitor.c b/rhythmdb/rhythmdb-monitor.c
index cba49fa..b4749ad 100644
--- a/rhythmdb/rhythmdb-monitor.c
+++ b/rhythmdb/rhythmdb-monitor.c
@@ -44,6 +44,10 @@
 #include "rb-preferences.h"
 #include "eel-gconf-extensions.h"
 
+#if !GLIB_CHECK_VERSION(2,24,0)
+#define G_FILE_MONITOR_SEND_MOVED	0
+#endif
+
 #define RHYTHMDB_FILE_MODIFY_PROCESS_TIME 2
 
 static void rhythmdb_directory_change_cb (GFileMonitor *monitor,
@@ -136,7 +140,7 @@ actually_add_monitor (RhythmDB *db, GFile *directory, GError **error)
 		return;
 	}
 
-	monitor = g_file_monitor_directory (directory, 0, db->priv->exiting, error);
+	monitor = g_file_monitor_directory (directory, G_FILE_MONITOR_SEND_MOVED, db->priv->exiting, error);
 	if (monitor != NULL) {
 		g_signal_connect_object (G_OBJECT (monitor),
 					 "changed",
@@ -216,14 +220,8 @@ rhythmdb_check_changed_file (RBRefString *uri, gpointer data, RhythmDB *db)
 
 	g_get_current_time (&time);
 	if (time.tv_sec >= time_sec + RHYTHMDB_FILE_MODIFY_PROCESS_TIME) {
-		/* process and remove from table */
-		RhythmDBEvent *event = g_slice_new0 (RhythmDBEvent);
-		event->db = db;
-		event->type = RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED;
-		event->uri = rb_refstring_ref (uri);
-
-		g_async_queue_push (db->priv->event_queue, event);
 		rb_debug ("adding newly located file %s", rb_refstring_get (uri));
+		rhythmdb_add_uri (db, rb_refstring_get (uri));
 		return TRUE;
 	}
 
@@ -293,7 +291,14 @@ rhythmdb_directory_change_cb (GFileMonitor *monitor,
 			      RhythmDB *db)
 {
 	char *canon_uri;
+	char *other_canon_uri = NULL;
+	RhythmDBEntry *entry;
+
 	canon_uri = g_file_get_uri (file);
+	if (other_file != NULL) {
+		other_canon_uri = g_file_get_uri (other_file);
+	}
+
 	rb_debug ("directory event %d for %s", event_type, canon_uri);
 
 	switch (event_type) {
@@ -338,14 +343,40 @@ rhythmdb_directory_change_cb (GFileMonitor *monitor,
 		/* hmm.. */
 		break;
 	case G_FILE_MONITOR_EVENT_DELETED:
-		if (rhythmdb_entry_lookup_by_location (db, canon_uri)) {
-			RhythmDBEvent *event = g_slice_new0 (RhythmDBEvent);
-			event->db = db;
-			event->type = RHYTHMDB_EVENT_FILE_DELETED;
-			event->uri = rb_refstring_new (canon_uri);
-			g_async_queue_push (db->priv->event_queue, event);
+		entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
+		if (entry != NULL) {
+			g_hash_table_remove (db->priv->changed_files, entry->location);
+			rhythmdb_entry_set_visibility (db, entry, FALSE);
+			rhythmdb_commit (db);
+		}
+		break;
+#if GLIB_CHECK_VERSION(2,24,0)
+	case G_FILE_MONITOR_EVENT_MOVED:
+		if (other_canon_uri == NULL) {
+			break;
+		}
+
+		entry = rhythmdb_entry_lookup_by_location (db, other_canon_uri);
+		if (entry != NULL) {
+			rb_debug ("file move target %s already exists in database", other_canon_uri);
+			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
+			if (entry != NULL) {
+				g_hash_table_remove (db->priv->changed_files, entry->location);
+				rhythmdb_entry_set_visibility (db, entry, FALSE);
+				rhythmdb_commit (db);
+			}
+		} else {
+			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
+			if (entry != NULL) {
+				GValue v = {0,};
+				g_value_init (&v, G_TYPE_STRING);
+				g_value_set_string (&v, other_canon_uri);
+				rhythmdb_entry_set_internal (db, entry, TRUE, RHYTHMDB_PROP_LOCATION, &v);
+				g_value_unset (&v);
+			}
 		}
 		break;
+#endif
 	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
 	case G_FILE_MONITOR_EVENT_UNMOUNTED:
 	default:
@@ -353,6 +384,7 @@ rhythmdb_directory_change_cb (GFileMonitor *monitor,
 	}
 
 	g_free (canon_uri);
+	g_free (other_canon_uri);
 }
 
 void
diff --git a/rhythmdb/rhythmdb-private.h b/rhythmdb/rhythmdb-private.h
index 29e3e30..103dee3 100644
--- a/rhythmdb/rhythmdb-private.h
+++ b/rhythmdb/rhythmdb-private.h
@@ -201,8 +201,6 @@ typedef struct
 		RHYTHMDB_EVENT_THREAD_EXITED,
 		RHYTHMDB_EVENT_DB_SAVED,
 		RHYTHMDB_EVENT_QUERY_COMPLETE,
-		RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED,
-		RHYTHMDB_EVENT_FILE_DELETED,
 		RHYTHMDB_EVENT_ENTRY_SET
 	} type;
 	RBRefString *uri;
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index ac6f173..cc329dc 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -995,8 +995,6 @@ rhythmdb_event_free (RhythmDB *db,
 	case RHYTHMDB_EVENT_DB_LOAD:
 	case RHYTHMDB_EVENT_DB_SAVED:
 	case RHYTHMDB_EVENT_QUERY_COMPLETE:
-	case RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED:
-	case RHYTHMDB_EVENT_FILE_DELETED:
 		break;
 	case RHYTHMDB_EVENT_ENTRY_SET:
 		g_value_unset (&result->change.new);
@@ -2219,14 +2217,14 @@ rhythmdb_process_stat_event (RhythmDB *db,
 			if (entry->mtime == new_mtime && (new_size == 0 || entry->file_size == new_size)) {
 				rb_debug ("not modified: %s", rb_refstring_get (event->real_uri));
 			} else {
-				RhythmDBEvent *new_event;
-
 				rb_debug ("changed: %s", rb_refstring_get (event->real_uri));
-				new_event = g_slice_new0 (RhythmDBEvent);
-				new_event->db = db;
-				new_event->uri = rb_refstring_ref (event->real_uri);
-				new_event->type = RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED;
-				rhythmdb_push_event (db, new_event);
+				action = g_slice_new0 (RhythmDBAction);
+				action->type = RHYTHMDB_ACTION_LOAD;
+				action->uri = rb_refstring_ref (event->real_uri);
+				action->data.types.entry_type = event->entry_type;
+				action->data.types.ignore_type = event->ignore_type;
+				action->data.types.error_type = event->error_type;
+				g_async_queue_push (db->priv->action_queue, action);
 			}
 		} else {
 			/* push a LOAD action */
@@ -2635,36 +2633,6 @@ rhythmdb_process_queued_entry_set_event (RhythmDB *db,
 }
 
 static void
-rhythmdb_process_file_created_or_modified (RhythmDB *db,
-					   RhythmDBEvent *event)
-{
-	RhythmDBAction *action;
-
-	action = g_slice_new0 (RhythmDBAction);
-	action->type = RHYTHMDB_ACTION_LOAD;
-	action->uri = rb_refstring_ref (event->uri);
-	action->data.types.entry_type = RHYTHMDB_ENTRY_TYPE_INVALID;
-	action->data.types.ignore_type = RHYTHMDB_ENTRY_TYPE_IGNORE;
-	action->data.types.error_type = RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR;
-	g_async_queue_push (db->priv->action_queue, action);
-}
-
-static void
-rhythmdb_process_file_deleted (RhythmDB *db,
-			       RhythmDBEvent *event)
-{
-	RhythmDBEntry *entry = rhythmdb_entry_lookup_by_location_refstring (db, event->uri);
-
-	g_hash_table_remove (db->priv->changed_files, event->uri);
-
-	if (entry) {
-		rb_debug ("deleting entry for %s", rb_refstring_get (event->uri));
-		rhythmdb_entry_set_visibility (db, entry, FALSE);
-		rhythmdb_commit (db);
-	}
-}
-
-static void
 rhythmdb_process_one_event (RhythmDBEvent *event, RhythmDB *db)
 {
 	gboolean free = TRUE;
@@ -2722,14 +2690,6 @@ rhythmdb_process_one_event (RhythmDBEvent *event, RhythmDB *db)
 		rb_debug ("processing RHYTHMDB_EVENT_QUERY_COMPLETE");
 		rhythmdb_read_leave (db);
 		break;
-	case RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED:
-		rb_debug ("processing RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED");
-		rhythmdb_process_file_created_or_modified (db, event);
-		break;
-	case RHYTHMDB_EVENT_FILE_DELETED:
-		rb_debug ("processing RHYTHMDB_EVENT_FILE_DELETED");
-		rhythmdb_process_file_deleted (db, event);
-		break;
 	}
 	if (free)
 		rhythmdb_event_free (db, event);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]