[gnome-logs] Move category matches to model using query API



commit b2505ca31a57e77afc6822ca6134399f9705d15d
Author: Pranav Ganorkar <pranavg189 gmail com>
Date:   Fri May 27 15:39:50 2016 +0530

    Move category matches to model using query API
    
    Query struct is populated with the corresponding category matches.
    It is parsed in the journal model to finally apply the matches with
    gl_journal_set_matches(). After applying the matches, the model is
    repopulated accordingly.

 src/gl-eventviewlist.c |  114 ++++++++++++++++++++++++--------------
 src/gl-journal-model.c |  144 ++++++++++++++++++++++++++++++++++++++---------
 src/gl-journal-model.h |    7 ++
 3 files changed, 194 insertions(+), 71 deletions(-)
---
diff --git a/src/gl-eventviewlist.c b/src/gl-eventviewlist.c
index b33eb3a..ae03146 100644
--- a/src/gl-eventviewlist.c
+++ b/src/gl-eventviewlist.c
@@ -714,7 +714,7 @@ gl_event_list_view_create_row_widget (gpointer item,
 }
 
 static gchar *
-create_uid_match_string (void)
+get_uid_match_field_value (void)
 {
     GCredentials *creds;
     uid_t uid;
@@ -724,25 +724,43 @@ create_uid_match_string (void)
     uid = g_credentials_get_unix_user (creds, NULL);
 
     if (uid != -1)
-        str = g_strdup_printf ("_UID=%d", uid);
+        str = g_strdup_printf ("%d", uid);
 
     g_object_unref (creds);
     return str;
 }
 
-static void
-on_notify_category (GlCategoryList *list,
-                    GParamSpec *pspec,
-                    gpointer user_data)
+/* Get Boot ID for current boot match */
+static gchar *
+get_current_boot_id (const gchar *boot_match)
 {
+    gchar *boot_value;
+
+    boot_value = strchr (boot_match, '=') + 1;
+
+    return g_strdup (boot_value);
+}
+
+/* Create query object according to category and set it on journal model */
+static GlQuery *
+create_query_object (GlJournalModel *model,
+                     GlCategoryList *list,
+                     const gchar *current_boot_match)
+{
+    GlQuery *query;
+    gchar *boot_id;
     GlCategoryListFilter filter;
-    GlEventViewList *view;
-    GlEventViewListPrivate *priv;
-    GSettings *settings;
-    gint sort_order;
 
-    view = GL_EVENT_VIEW_LIST (user_data);
-    priv = gl_event_view_list_get_instance_private (view);
+    /* Create new query object */
+    query = gl_query_new ();
+
+    /* Get current boot id */
+    boot_id = get_current_boot_id (current_boot_match);
+
+    /* Add boot match for all the categories */
+    gl_query_add_match (query, "_BOOT_ID", boot_id);
+
+    /* Add exact matches according to selected category */
     filter = gl_category_list_get_category (list);
 
     switch (filter)
@@ -750,19 +768,16 @@ on_notify_category (GlCategoryList *list,
         case GL_CATEGORY_LIST_FILTER_IMPORTANT:
             {
               /* Alert or emergency priority. */
-              const gchar * query[] = { "PRIORITY=0", "PRIORITY=1", "PRIORITY=2", "PRIORITY=3", NULL, NULL };
-
-              query[4] = priv->boot_match;
-              gl_journal_model_set_matches (priv->journal_model, query);
+              gl_query_add_match (query, "PRIORITY", "0");
+              gl_query_add_match (query, "PRIORITY", "1");
+              gl_query_add_match (query, "PRIORITY", "2");
+              gl_query_add_match (query, "PRIORITY", "3");
             }
             break;
 
         case GL_CATEGORY_LIST_FILTER_ALL:
             {
-                const gchar *query[] = { NULL, NULL };
 
-                query[0] = priv->boot_match;
-                gl_journal_model_set_matches (priv->journal_model, query);
             }
             break;
 
@@ -770,18 +785,14 @@ on_notify_category (GlCategoryList *list,
             /* Allow all _TRANSPORT != kernel. Attempt to filter by only processes
              * owned by the same UID. */
             {
-                gchar *uid_str = NULL;
-                const gchar *query[] = { "_TRANSPORT=journal",
-                                         "_TRANSPORT=stdout",
-                                         "_TRANSPORT=syslog",
-                                         NULL,
-                                         NULL,
-                                         NULL };
-
-                uid_str = create_uid_match_string ();
-                query[3] = uid_str;
-                query[4] = priv->boot_match;
-                gl_journal_model_set_matches (priv->journal_model, query);
+                gchar *uid_str;
+
+                uid_str = get_uid_match_field_value ();
+
+                gl_query_add_match (query, "_TRANSPORT", "journal");
+                gl_query_add_match (query, "_TRANSPORT", "stdout");
+                gl_query_add_match (query, "_TRANSPORT", "syslog");
+                gl_query_add_match (query, "_UID", uid_str);
 
                 g_free (uid_str);
             }
@@ -789,28 +800,20 @@ on_notify_category (GlCategoryList *list,
 
         case GL_CATEGORY_LIST_FILTER_SYSTEM:
             {
-                const gchar *query[] = { "_TRANSPORT=kernel", NULL, NULL };
-
-                query[1] = priv->boot_match;
-                gl_journal_model_set_matches (priv->journal_model, query);
+                gl_query_add_match (query, "_TRANSPORT", "kernel");
             }
             break;
 
         case GL_CATEGORY_LIST_FILTER_HARDWARE:
             {
-                const gchar *query[] = { "_TRANSPORT=kernel", "_KERNEL_DEVICE", NULL, NULL };
-
-                query[2] = priv->boot_match;
-                gl_journal_model_set_matches (priv->journal_model, query);
+                gl_query_add_match (query, "_TRANSPORT", "kernel");
+                gl_query_add_match ( query, "_KERNEL_DEVICE", NULL);
             }
             break;
 
         case GL_CATEGORY_LIST_FILTER_SECURITY:
             {
-                const gchar *query[] = { "_AUDIT_SESSION", NULL, NULL };
-
-                query[1] = priv->boot_match;
-                gl_journal_model_set_matches (priv->journal_model, query);
+                gl_query_add_match (query, "_AUDIT_SESSION", NULL);
             }
             break;
 
@@ -818,6 +821,31 @@ on_notify_category (GlCategoryList *list,
             g_assert_not_reached ();
     }
 
+    g_free (boot_id);
+
+    return query;
+}
+
+static void
+on_notify_category (GlCategoryList *list,
+                    GParamSpec *pspec,
+                    gpointer user_data)
+{
+    GlEventViewList *view;
+    GlEventViewListPrivate *priv;
+    GSettings *settings;
+    gint sort_order;
+    GlQuery *query;
+
+    view = GL_EVENT_VIEW_LIST (user_data);
+    priv = gl_event_view_list_get_instance_private (view);
+
+    /* Create the query object */
+    query = create_query_object (priv->journal_model, list, priv->boot_match);
+
+    /* Set the created query on the journal model */
+    gl_journal_model_take_query (priv->journal_model, query);
+
     settings = g_settings_new (SETTINGS_SCHEMA);
     sort_order = g_settings_get_enum (settings, SORT_ORDER);
     g_object_unref (settings);
diff --git a/src/gl-journal-model.c b/src/gl-journal-model.c
index 41b445b..a533335 100644
--- a/src/gl-journal-model.c
+++ b/src/gl-journal-model.c
@@ -35,6 +35,8 @@ struct _GlJournalModel
     GlJournal *journal;
     GPtrArray *entries;
 
+    GlQuery *query;
+
     guint n_entries_to_fetch;
     gboolean fetched_all;
     guint idle_source;
@@ -203,34 +205,6 @@ gl_journal_model_new (void)
     return g_object_new (GL_TYPE_JOURNAL_MODEL, NULL);
 }
 
-/**
- * gl_journal_model_set_matches:
- * @model: a #GlJournalModel
- * @matches: new matches
- *
- * Changes @model's filter matches to @matches. This resets all items in
- * the model, as they have to be requeried from the journal.
- */
-void
-gl_journal_model_set_matches (GlJournalModel      *model,
-                              const gchar * const *matches)
-{
-    g_return_if_fail (GL_IS_JOURNAL_MODEL (model));
-    g_return_if_fail (matches != NULL);
-
-    gl_journal_model_stop_idle (model);
-    model->fetched_all = FALSE;
-    if (model->entries->len > 0)
-    {
-        g_list_model_items_changed (G_LIST_MODEL (model), 0, model->entries->len, 0);
-        g_ptr_array_remove_range (model->entries, 0, model->entries->len);
-    }
-
-    gl_journal_set_matches (model->journal, matches);
-
-    gl_journal_model_fetch_more_entries (model, FALSE);
-}
-
 /* Free the given @queryitem */
 static void
 gl_query_item_free (GlQueryItem *queryitem)
@@ -276,6 +250,120 @@ gl_query_item_new (const gchar *field_name,
     return queryitem;
 }
 
+static gchar *
+gl_query_item_create_match_string (GlQueryItem *queryitem)
+{
+    gchar *str;
+
+    if (queryitem->field_value)
+    {
+        str = g_strdup_printf ("%s=%s", queryitem->field_name, queryitem->field_value);
+    }
+    else
+    {
+        str = g_strdup (queryitem->field_name);
+    }
+
+    return str;
+}
+
+static void
+get_exact_match_string (GlQueryItem *queryitem, GPtrArray *matches)
+{
+    gchar *match;
+
+    match = gl_query_item_create_match_string (queryitem);
+
+    g_ptr_array_add (matches, match);
+}
+
+/* Get exact matches from the query object */
+static GPtrArray *
+gl_query_get_exact_matches (GlQuery *query)
+{
+    GPtrArray *matches;
+
+    matches = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
+
+    g_ptr_array_foreach (query->queryitems, (GFunc) get_exact_match_string, matches);
+
+    /* Add NULL terminator to determine end of pointer array */
+    g_ptr_array_add (matches, NULL);
+
+    return matches;
+}
+
+/* Process the newly assigned query and repopulate the journal model */
+static void
+gl_journal_model_process_query (GlJournalModel *model)
+{
+    GPtrArray *category_matches;
+
+    /* Set the exact matches first */
+    category_matches = gl_query_get_exact_matches (model->query);
+
+    gl_journal_set_matches (model->journal, (const gchar * const *) category_matches->pdata);
+
+    /* Start re-population of the journal */
+    gl_journal_model_fetch_more_entries (model, FALSE);
+
+    /* Free array */
+    g_ptr_array_free (category_matches, TRUE);
+}
+
+/**
+ * gl_journal_model_take_query:
+ * @model: a #GlJournalModel
+ * @query: (transfer full) : query object populated from view
+ *
+ * Takes the query object from the view.
+ * Clears the previous entries in the journal model.
+ * Sets query object on the journal model and processes the newly set query.
+ */
+void
+gl_journal_model_take_query (GlJournalModel *model,
+                             GlQuery *query)
+{
+    g_return_if_fail (GL_JOURNAL_MODEL (model));
+
+    gl_journal_model_stop_idle (model);
+    model->fetched_all = FALSE;
+
+    if (model->entries->len > 0)
+    {
+        g_list_model_items_changed (G_LIST_MODEL (model), 0, model->entries->len, 0);
+
+        g_ptr_array_free (model->entries, TRUE);
+
+        model->entries = g_ptr_array_new_with_free_func (g_object_unref);
+    }
+
+    /* Clear the previous query */
+    if (model->query)
+    {
+        gl_query_free (model->query);
+    }
+
+    /* Set new query */
+    model->query = query;
+
+    /* Start processing the new query */
+    gl_journal_model_process_query (model);
+}
+
+/* Add a new queryitem to query */
+void
+gl_query_add_match (GlQuery *query,
+                    const gchar *field_name,
+                    const gchar *field_value)
+{
+    GlQueryItem *queryitem;
+
+    queryitem = gl_query_item_new (field_name, field_value);
+
+    g_ptr_array_add (query->queryitems, queryitem);
+}
+
 gchar *
 gl_journal_model_get_current_boot_time (GlJournalModel *model,
                                         const gchar *boot_match)
diff --git a/src/gl-journal-model.h b/src/gl-journal-model.h
index 1d0686d..97c39ee 100644
--- a/src/gl-journal-model.h
+++ b/src/gl-journal-model.h
@@ -34,6 +34,13 @@ GlJournalModel *        gl_journal_model_new                            (void);
 
 GlQuery *               gl_query_new                                    (void);
 
+void                    gl_journal_model_take_query                     (GlJournalModel *model,
+                                                                         GlQuery *query);
+
+void                    gl_query_add_match                              (GlQuery *query,
+                                                                         const gchar *field_name,
+                                                                         const gchar *field_value);
+
 void                    gl_journal_model_set_matches                    (GlJournalModel      *model,
                                                                          const gchar * const *matches);
 


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