[evolution-data-server] M!43 - Calendar: Add SExp function to filter with DTSTART



commit a4878be6472adfd0c74f76282fbbce23006a4c47
Author: Helmut Pozimski <helmut pozimski eu>
Date:   Mon Aug 17 19:53:57 2020 +0200

    M!43 - Calendar: Add SExp function to filter with DTSTART
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/merge_requests/43

 src/calendar/libedata-cal/e-cal-backend-sexp.c | 66 +++++++++++++++++++++++++-
 src/calendar/libedata-cal/e-cal-cache.c        | 29 ++++++++++-
 tests/libedata-cal/test-cal-cache-search.c     | 10 ++++
 3 files changed, 103 insertions(+), 2 deletions(-)
---
diff --git a/src/calendar/libedata-cal/e-cal-backend-sexp.c b/src/calendar/libedata-cal/e-cal-backend-sexp.c
index 21da70722d..44ffb2c59d 100644
--- a/src/calendar/libedata-cal/e-cal-backend-sexp.c
+++ b/src/calendar/libedata-cal/e-cal-backend-sexp.c
@@ -1137,6 +1137,69 @@ func_completed_before (ESExp *esexp,
        return result;
 }
 
+/* (starts-before? TIME)
+ *
+ * TIME - time_t
+ *
+ * Returns a boolean indicating whether the component has a start on or
+ * before the given time (i.e. it checks the DTSTART property).
+ */
+static ESExpResult*
+func_starts_before (ESExp *esexp,
+                    gint argc,
+                    ESExpResult **argv,
+                    gpointer data)
+{
+       SearchContext *ctx = data;
+       ESExpResult *result;
+       ECalComponentDateTime *dt;
+       ICalTimezone *zone;
+       ICalTime *itt;
+       gboolean retval = FALSE;
+       time_t reference_time, start_time;
+
+       /* Check argument types */
+
+       if (argc != 1) {
+               e_sexp_fatal_error (
+                       esexp, _("ā€œ%sā€ expects one argument"),
+                       "starts-before");
+               return NULL;
+       }
+
+       if (argv[0]->type != ESEXP_RES_TIME) {
+               e_sexp_fatal_error (
+                       esexp, _("ā€œ%sā€ expects the first "
+                       "argument to be a time_t"),
+                       "starts-before");
+               return NULL;
+       }
+
+       reference_time = argv[0]->value.time;
+
+       dt = e_cal_component_get_dtstart (ctx->comp);
+       if (dt) {
+               itt = e_cal_component_datetime_get_value (dt);
+
+               if (itt) {
+                       /* DTSTART must be in UTC. */
+                       zone = i_cal_timezone_get_utc_timezone ();
+                       start_time = i_cal_time_as_timet_with_zone (itt, zone);
+
+                       /* We want to return TRUE if start_time is before reference_time. */
+                       if (difftime (start_time, reference_time) <= 0) {
+                               retval = TRUE;
+                       }
+               }
+               e_cal_component_datetime_free (dt);
+       }
+
+       result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
+       result->value.boolean = retval;
+
+       return result;
+}
+
 static void
 cal_backend_sexp_finalize (GObject *object)
 {
@@ -1197,7 +1260,8 @@ static struct {
        { "completed-before?", func_completed_before, 0 },
        { "has-attachments?", func_has_attachment, 0 },
        { "percent-complete?", func_percent_complete, 0 },
-       { "occurrences-count?", func_occurrences_count, 0 }
+       { "occurrences-count?", func_occurrences_count, 0 },
+       { "starts-before?", func_starts_before, 0 }
 };
 
 /**
diff --git a/src/calendar/libedata-cal/e-cal-cache.c b/src/calendar/libedata-cal/e-cal-cache.c
index 611a87950c..58c92204bd 100644
--- a/src/calendar/libedata-cal/e-cal-cache.c
+++ b/src/calendar/libedata-cal/e-cal-cache.c
@@ -1521,6 +1521,32 @@ ecc_sexp_func_check_sexp (ESExp *esexp,
        return result;
 }
 
+static ESExpResult *
+ecc_sexp_func_starts_before (ESExp *esexp,
+                             gint argc,
+                             ESExpResult **argv,
+                             gpointer user_data)
+{
+       SExpToSqlContext *ctx = user_data;
+       ESExpResult *result;
+       gchar *date_str;
+
+       g_return_val_if_fail (ctx != NULL, NULL);
+
+       if (argc != 1 ||
+            argv[0]->type != ESEXP_RES_TIME) {
+               return NULL;
+       }
+
+       date_str = ecc_encode_timet_to_sql (ctx->cal_cache, argv[0]->value.time);
+
+       result = e_sexp_result_new (esexp, ESEXP_RES_STRING);
+       result->value.string = g_strdup_printf ("(%s NOT NULL AND %s<='%s')",
+               ECC_COLUMN_OCCUR_START, ECC_COLUMN_OCCUR_START, date_str);
+
+       return result;
+}
+
 static ESExpResult *
 ecc_sexp_func_icheck_sexp (ESExp *esexp,
                           gint argc,
@@ -1579,7 +1605,8 @@ static struct {
        { "completed-before?",          ecc_sexp_func_completed_before, 0 },
        { "has-attachments?",           ecc_sexp_func_has_attachment, 0 },
        { "percent-complete?",          ecc_sexp_func_percent_complete, 0 },
-       { "occurrences-count?",         ecc_sexp_func_check_sexp, 0 }
+       { "occurrences-count?",         ecc_sexp_func_check_sexp, 0 },
+       { "starts-before?",             ecc_sexp_func_starts_before, 0 }
 };
 
 static gboolean
diff --git a/tests/libedata-cal/test-cal-cache-search.c b/tests/libedata-cal/test-cal-cache-search.c
index 500b81a53e..ccf34f7be4 100644
--- a/tests/libedata-cal/test-cal-cache-search.c
+++ b/tests/libedata-cal/test-cal-cache-search.c
@@ -420,6 +420,14 @@ test_search_complex (TCUFixture *fixture,
                ")", "event-3");
 }
 
+static void
+test_search_starts_before (TCUFixture *fixture,
+                              gconstpointer user_data)
+{
+       test_search (fixture, "(starts-before? (make-time \"20170211T000000Z\"))", "!task-9");
+       test_search (fixture, "(starts-before? (make-time \"20170214T000000Z\"))", "task-9");
+}
+
 gint
 main (gint argc,
       gchar **argv)
@@ -474,6 +482,8 @@ main (gint argc,
                tcu_fixture_setup, test_search_occurrences_count, tcu_fixture_teardown);
        g_test_add ("/ECalCache/Search/Complex", TCUFixture, &closure_events,
                tcu_fixture_setup, test_search_complex, tcu_fixture_teardown);
+       g_test_add ("/ECalCache/Search/StartsBefore", TCUFixture, &closure_tasks,
+               tcu_fixture_setup, test_search_starts_before, tcu_fixture_teardown);
 
        return e_test_server_utils_run_full (0);
 }


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