[epiphany] sync: Migrate timestamps to gint64



commit 89a3e1ea5a4e50006182abcc23c92eae6834c55a
Author: Gabriel Ivascu <gabrielivascu gnome org>
Date:   Tue Dec 12 21:59:30 2017 +0200

    sync: Migrate timestamps to gint64
    
    https://bugzilla.gnome.org/show_bug.cgi?id=790819

 data/org.gnome.epiphany.gschema.xml          |    8 +-
 lib/ephy-profile-utils.h                     |    3 +-
 lib/ephy-sync-utils.c                        |   32 ++--
 lib/ephy-sync-utils.h                        |   16 +-
 lib/sync/ephy-history-manager.c              |    4 +-
 lib/sync/ephy-history-record.c               |    4 +-
 lib/sync/ephy-open-tabs-manager.c            |    4 +-
 lib/sync/ephy-open-tabs-record.c             |    4 +-
 lib/sync/ephy-password-manager.c             |   19 ++--
 lib/sync/ephy-password-record.c              |    7 +-
 lib/sync/ephy-sync-service.c                 |   26 ++--
 lib/sync/ephy-synchronizable-manager.c       |    4 +-
 lib/sync/ephy-synchronizable-manager.h       |    8 +-
 lib/sync/ephy-synchronizable.c               |    8 +-
 lib/sync/ephy-synchronizable.h               |    8 +-
 src/bookmarks/ephy-bookmark.c                |    9 +-
 src/bookmarks/ephy-bookmarks-export.c        |    4 +-
 src/bookmarks/ephy-bookmarks-import.c        |    4 +-
 src/bookmarks/ephy-bookmarks-manager.c       |    8 +-
 src/profile-migrator/ephy-profile-migrator.c |  199 ++++++++++++++++++++++++++
 20 files changed, 291 insertions(+), 88 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index 472e0f5..981968d 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -317,7 +317,7 @@
                        <summary>Enable bookmarks sync</summary>
                        <description>TRUE if bookmarks collection should be synced, FALSE 
otherwise.</description>
                </key>
-               <key type="d" name="sync-bookmarks-time">
+               <key type="x" name="sync-bookmarks-time">
                        <default>0</default>
                        <summary>Bookmarks sync timestamp</summary>
                        <description>The timestamp at which last bookmarks sync was made.</description>
@@ -332,7 +332,7 @@
                        <summary>Enable passwords sync</summary>
                        <description>TRUE if passwords collection should be synced, FALSE 
otherwise.</description>
                </key>
-               <key type="d" name="sync-passwords-time">
+               <key type="x" name="sync-passwords-time">
                        <default>0</default>
                        <summary>Passwords sync timestamp</summary>
                        <description>The timestamp at which last passwords sync was made.</description>
@@ -347,7 +347,7 @@
                        <summary>Enable history sync</summary>
                        <description>TRUE if history collection should be synced, FALSE 
otherwise.</description>
                </key>
-               <key type="d" name="sync-history-time">
+               <key type="x" name="sync-history-time">
                        <default>0</default>
                        <summary>History sync timestamp</summary>
                        <description>The timestamp at which last history sync was made.</description>
@@ -362,7 +362,7 @@
                        <summary>Enable open tabs sync</summary>
                        <description>TRUE if open tabs collection should be synced, FALSE 
otherwise.</description>
                </key>
-               <key type="d" name="sync-open-tabs-time">
+               <key type="x" name="sync-open-tabs-time">
                        <default>0</default>
                        <summary>Open tabs sync timestamp</summary>
                        <description>The timestamp at which last open tabs sync was made.</description>
diff --git a/lib/ephy-profile-utils.h b/lib/ephy-profile-utils.h
index 9b97968..32dd8f3 100644
--- a/lib/ephy-profile-utils.h
+++ b/lib/ephy-profile-utils.h
@@ -24,12 +24,13 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_PROFILE_MIGRATION_VERSION 23
+#define EPHY_PROFILE_MIGRATION_VERSION 25
 #define EPHY_INSECURE_PASSWORDS_MIGRATION_VERSION 11
 #define EPHY_SETTINGS_MIGRATION_VERSION 16
 #define EPHY_FIREFOX_SYNC_PASSWORDS_MIGRATION_VERSION 19
 #define EPHY_TARGET_ORIGIN_MIGRATION_VERSION 21
 #define EPHY_SYNC_DEVICE_ID_MIGRATION_VERSION 23
+#define EPHY_PASSWORDS_TIMESTAMP_MIGRATION_VERSION 25
 
 #define EPHY_BOOKMARKS_FILE     "bookmarks.gvdb"
 #define EPHY_HISTORY_FILE       "ephy-history.db"
diff --git a/lib/ephy-sync-utils.c b/lib/ephy-sync-utils.c
index 12be8c6..62d708d 100644
--- a/lib/ephy-sync-utils.c
+++ b/lib/ephy-sync-utils.c
@@ -395,15 +395,15 @@ ephy_sync_utils_bookmarks_sync_is_enabled (void)
 }
 
 void
-ephy_sync_utils_set_bookmarks_sync_time (double time)
+ephy_sync_utils_set_bookmarks_sync_time (gint64 time)
 {
-  g_settings_set_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_BOOKMARKS_TIME, time);
+  g_settings_set_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_BOOKMARKS_TIME, time);
 }
 
-double
+gint64
 ephy_sync_utils_get_bookmarks_sync_time (void)
 {
-  return g_settings_get_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_BOOKMARKS_TIME);
+  return g_settings_get_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_BOOKMARKS_TIME);
 }
 
 void
@@ -425,15 +425,15 @@ ephy_sync_utils_passwords_sync_is_enabled (void)
 }
 
 void
-ephy_sync_utils_set_passwords_sync_time (double time)
+ephy_sync_utils_set_passwords_sync_time (gint64 time)
 {
-  g_settings_set_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_PASSWORDS_TIME, time);
+  g_settings_set_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_PASSWORDS_TIME, time);
 }
 
-double
+gint64
 ephy_sync_utils_get_passwords_sync_time (void)
 {
-  return g_settings_get_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_PASSWORDS_TIME);
+  return g_settings_get_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_PASSWORDS_TIME);
 }
 
 void
@@ -455,15 +455,15 @@ ephy_sync_utils_history_sync_is_enabled (void)
 }
 
 void
-ephy_sync_utils_set_history_sync_time (double time)
+ephy_sync_utils_set_history_sync_time (gint64 time)
 {
-  g_settings_set_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_HISTORY_TIME, time);
+  g_settings_set_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_HISTORY_TIME, time);
 }
 
-double
+gint64
 ephy_sync_utils_get_history_sync_time (void)
 {
-  return g_settings_get_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_HISTORY_TIME);
+  return g_settings_get_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_HISTORY_TIME);
 }
 
 void
@@ -485,13 +485,13 @@ ephy_sync_utils_open_tabs_sync_is_enabled (void)
 }
 
 void
-ephy_sync_utils_set_open_tabs_sync_time (double time)
+ephy_sync_utils_set_open_tabs_sync_time (gint64 time)
 {
-  g_settings_set_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_OPEN_TABS_TIME, time);
+  g_settings_set_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_OPEN_TABS_TIME, time);
 }
 
-double
+gint64
 ephy_sync_utils_get_open_tabs_sync_time (void)
 {
-  return g_settings_get_double (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_OPEN_TABS_TIME);
+  return g_settings_get_int64 (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_OPEN_TABS_TIME);
 }
diff --git a/lib/ephy-sync-utils.h b/lib/ephy-sync-utils.h
index d4e2a3b..f6f4e46 100644
--- a/lib/ephy-sync-utils.h
+++ b/lib/ephy-sync-utils.h
@@ -79,25 +79,25 @@ guint     ephy_sync_utils_get_sync_frequency            (void);
 gboolean  ephy_sync_utils_sync_with_firefox             (void);
 
 gboolean  ephy_sync_utils_bookmarks_sync_is_enabled     (void);
-void      ephy_sync_utils_set_bookmarks_sync_time       (double time);
-double    ephy_sync_utils_get_bookmarks_sync_time       (void);
+void      ephy_sync_utils_set_bookmarks_sync_time       (gint64 time);
+gint64    ephy_sync_utils_get_bookmarks_sync_time       (void);
 void      ephy_sync_utils_set_bookmarks_sync_is_initial (gboolean is_initial);
 gboolean  ephy_sync_utils_get_bookmarks_sync_is_initial (void);
 
 gboolean  ephy_sync_utils_passwords_sync_is_enabled     (void);
-void      ephy_sync_utils_set_passwords_sync_time       (double time);
-double    ephy_sync_utils_get_passwords_sync_time       (void);
+void      ephy_sync_utils_set_passwords_sync_time       (gint64 time);
+gint64    ephy_sync_utils_get_passwords_sync_time       (void);
 void      ephy_sync_utils_set_passwords_sync_is_initial (gboolean is_initial);
 gboolean  ephy_sync_utils_get_passwords_sync_is_initial (void);
 
 gboolean  ephy_sync_utils_history_sync_is_enabled       (void);
-void      ephy_sync_utils_set_history_sync_time         (double time);
-double    ephy_sync_utils_get_history_sync_time         (void);
+void      ephy_sync_utils_set_history_sync_time         (gint64 time);
+gint64    ephy_sync_utils_get_history_sync_time         (void);
 void      ephy_sync_utils_set_history_sync_is_initial   (gboolean is_initial);
 gboolean  ephy_sync_utils_get_history_sync_is_initial   (void);
 
 gboolean  ephy_sync_utils_open_tabs_sync_is_enabled     (void);
-void      ephy_sync_utils_set_open_tabs_sync_time       (double time);
-double    ephy_sync_utils_get_open_tabs_sync_time       (void);
+void      ephy_sync_utils_set_open_tabs_sync_time       (gint64 time);
+gint64    ephy_sync_utils_get_open_tabs_sync_time       (void);
 
 G_END_DECLS
diff --git a/lib/sync/ephy-history-manager.c b/lib/sync/ephy-history-manager.c
index 3c12c6f..3983b5a 100644
--- a/lib/sync/ephy-history-manager.c
+++ b/lib/sync/ephy-history-manager.c
@@ -228,7 +228,7 @@ synchronizable_manager_set_is_initial_sync (EphySynchronizableManager *manager,
   ephy_sync_utils_set_history_sync_is_initial (is_initial);
 }
 
-static double
+static gint64
 synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 {
   return ephy_sync_utils_get_history_sync_time ();
@@ -236,7 +236,7 @@ synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 
 static void
 synchronizable_manager_set_sync_time (EphySynchronizableManager *manager,
-                                      double                     sync_time)
+                                      gint64                     sync_time)
 {
   ephy_sync_utils_set_history_sync_time (sync_time);
 }
diff --git a/lib/sync/ephy-history-record.c b/lib/sync/ephy-history-record.c
index 62883a1..c28b9c6 100644
--- a/lib/sync/ephy-history-record.c
+++ b/lib/sync/ephy-history-record.c
@@ -382,7 +382,7 @@ synchronizable_get_id (EphySynchronizable *synchronizable)
   return ephy_history_record_get_id (EPHY_HISTORY_RECORD (synchronizable));
 }
 
-static double
+static gint64
 synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 {
   /* No implementation.
@@ -393,7 +393,7 @@ synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 
 static void
 synchronizable_set_server_time_modified (EphySynchronizable *synchronizable,
-                                         double              server_time_modified)
+                                         gint64              server_time_modified)
 {
   /* No implementation.
    * We don't care about the server time modified of history records.
diff --git a/lib/sync/ephy-open-tabs-manager.c b/lib/sync/ephy-open-tabs-manager.c
index e16b1ff..861a460 100644
--- a/lib/sync/ephy-open-tabs-manager.c
+++ b/lib/sync/ephy-open-tabs-manager.c
@@ -212,7 +212,7 @@ synchronizable_manager_set_is_initial_sync (EphySynchronizableManager *manager,
   /* Initial sync will always be true. */
 }
 
-static double
+static gint64
 synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 {
   return ephy_sync_utils_get_open_tabs_sync_time ();
@@ -220,7 +220,7 @@ synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 
 static void
 synchronizable_manager_set_sync_time (EphySynchronizableManager *manager,
-                                      double                     sync_time)
+                                      gint64                     sync_time)
 {
   ephy_sync_utils_set_open_tabs_sync_time (sync_time);
 }
diff --git a/lib/sync/ephy-open-tabs-record.c b/lib/sync/ephy-open-tabs-record.c
index 394ac0f..7e322b7 100644
--- a/lib/sync/ephy-open-tabs-record.c
+++ b/lib/sync/ephy-open-tabs-record.c
@@ -282,7 +282,7 @@ synchronizable_get_id (EphySynchronizable *synchronizable)
   return EPHY_OPEN_TABS_RECORD (synchronizable)->id;
 }
 
-static double
+static gint64
 synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 {
   /* No implementation.
@@ -293,7 +293,7 @@ synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 
 static void
 synchronizable_set_server_time_modified (EphySynchronizable *synchronizable,
-                                         double              server_time_modified)
+                                         gint64              server_time_modified)
 {
   /* No implementation.
    * We don't care about the server time modified of open tabs records.
diff --git a/lib/sync/ephy-password-manager.c b/lib/sync/ephy-password-manager.c
index fb10005..250a416 100644
--- a/lib/sync/ephy-password-manager.c
+++ b/lib/sync/ephy-password-manager.c
@@ -27,6 +27,7 @@
 #include "ephy-synchronizable-manager.h"
 
 #include <glib/gi18n.h>
+#include <inttypes.h>
 #include <stdio.h>
 
 const SecretSchema *
@@ -188,7 +189,7 @@ get_attributes_table (const char *id,
                       const char *username,
                       const char *username_field,
                       const char *password_field,
-                      double      server_time_modified)
+                      gint64      server_time_modified)
 {
   GHashTable *attributes = secret_attributes_build (EPHY_FORM_PASSWORD_SCHEMA, NULL);
 
@@ -219,7 +220,7 @@ get_attributes_table (const char *id,
   if (server_time_modified >= 0)
     g_hash_table_insert (attributes,
                          g_strdup (SERVER_TIME_MODIFIED_KEY),
-                         g_strdup_printf ("%.2lf", server_time_modified));
+                         g_strdup_printf ("%"PRId64, server_time_modified));
 
   return attributes;
 }
@@ -391,7 +392,7 @@ ephy_password_manager_store_record (EphyPasswordManager *self,
   const char *username_field;
   const char *password_field;
   char *label;
-  double modified;
+  gint64 modified;
 
   g_assert (EPHY_IS_PASSWORD_MANAGER (self));
   g_assert (EPHY_IS_PASSWORD_RECORD (record));
@@ -529,7 +530,7 @@ secret_service_search_cb (SecretService  *service,
     const char *password_field = g_hash_table_lookup (attributes, PASSWORD_FIELD_KEY);
     const char *timestamp = g_hash_table_lookup (attributes, SERVER_TIME_MODIFIED_KEY);
     const char *password = secret_value_get (value, NULL);
-    double server_time_modified;
+    gint64 server_time_modified;
     EphyPasswordRecord *record;
 
     LOG ("Found password record for (%s, %s, %s, %s, %s)",
@@ -545,7 +546,7 @@ secret_service_search_cb (SecretService  *service,
                                        username_field, password_field,
                                        secret_item_get_created (item) * 1000,
                                        secret_item_get_modified (item) * 1000);
-    sscanf (timestamp, "%lf", &server_time_modified);
+    server_time_modified = g_ascii_strtod (timestamp, NULL);
     ephy_synchronizable_set_server_time_modified (EPHY_SYNCHRONIZABLE (record),
                                                   server_time_modified);
     records = g_list_prepend (records, record);
@@ -741,7 +742,7 @@ synchronizable_manager_set_is_initial_sync (EphySynchronizableManager *manager,
   ephy_sync_utils_set_passwords_sync_is_initial (is_initial);
 }
 
-static double
+static gint64
 synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 {
   return ephy_sync_utils_get_passwords_sync_time ();
@@ -749,7 +750,7 @@ synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 
 static void
 synchronizable_manager_set_sync_time (EphySynchronizableManager *manager,
-                                      double                     sync_time)
+                                      gint64                     sync_time)
 {
   ephy_sync_utils_set_passwords_sync_time (sync_time);
 }
@@ -878,8 +879,8 @@ ephy_password_manager_handle_initial_merge (EphyPasswordManager *self,
   const char *remote_password_field;
   guint64 remote_timestamp;
   guint64 local_timestamp;
-  double remote_server_time_modified;
-  double local_server_time_modified;
+  gint64 remote_server_time_modified;
+  gint64 local_server_time_modified;
 
   g_assert (EPHY_IS_PASSWORD_MANAGER (self));
 
diff --git a/lib/sync/ephy-password-record.c b/lib/sync/ephy-password-record.c
index 7e2d374..314474f 100644
--- a/lib/sync/ephy-password-record.c
+++ b/lib/sync/ephy-password-record.c
@@ -35,8 +35,7 @@ struct _EphyPasswordRecord {
   char    *password_field;
   guint64  time_created;
   guint64  time_password_changed;
-
-  double   server_time_modified;
+  gint64   server_time_modified;
 };
 
 static void json_serializable_iface_init (JsonSerializableIface *iface);
@@ -400,7 +399,7 @@ synchronizable_get_id (EphySynchronizable *synchronizable)
   return ephy_password_record_get_id (EPHY_PASSWORD_RECORD (synchronizable));
 }
 
-static double
+static gint64
 synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 {
   return EPHY_PASSWORD_RECORD (synchronizable)->server_time_modified;
@@ -408,7 +407,7 @@ synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 
 static void
 synchronizable_set_server_time_modified (EphySynchronizable *synchronizable,
-                                         double              server_time_modified)
+                                         gint64              server_time_modified)
 {
   EPHY_PASSWORD_RECORD (synchronizable)->server_time_modified = server_time_modified;
 }
diff --git a/lib/sync/ephy-sync-service.c b/lib/sync/ephy-sync-service.c
index 9348cd1..ab4fa34 100644
--- a/lib/sync/ephy-sync-service.c
+++ b/lib/sync/ephy-sync-service.c
@@ -30,7 +30,9 @@
 
 #include <glib/gi18n.h>
 #include <json-glib/json-glib.h>
+#include <inttypes.h>
 #include <libsoup/soup.h>
+#include <math.h>
 #include <string.h>
 
 struct _EphySyncService {
@@ -97,8 +99,8 @@ typedef struct {
   char                *endpoint;
   char                *method;
   char                *request_body;
-  double               modified_since;
-  double               unmodified_since;
+  gint64               modified_since;
+  gint64               unmodified_since;
   SoupSessionCallback  callback;
   gpointer             user_data;
 } StorageRequestAsyncData;
@@ -145,8 +147,8 @@ static StorageRequestAsyncData *
 storage_request_async_data_new (const char          *endpoint,
                                 const char          *method,
                                 const char          *request_body,
-                                double               modified_since,
-                                double               unmodified_since,
+                                gint64               modified_since,
+                                gint64               unmodified_since,
                                 SoupSessionCallback  callback,
                                 gpointer             user_data)
 {
@@ -539,12 +541,12 @@ ephy_sync_service_send_storage_request (EphySyncService         *self,
     soup_message_headers_append (msg->request_headers, "content-type", content_type);
 
   if (data->modified_since >= 0) {
-    if_modified_since = g_strdup_printf ("%.2lf", data->modified_since);
+    if_modified_since = g_strdup_printf ("%"PRId64, data->modified_since);
     soup_message_headers_append (msg->request_headers, "X-If-Modified-Since", if_modified_since);
   }
 
   if (data->unmodified_since >= 0) {
-    if_unmodified_since = g_strdup_printf ("%.2lf", data->unmodified_since);
+    if_unmodified_since = g_strdup_printf ("%"PRId64, data->unmodified_since);
     soup_message_headers_append (msg->request_headers, "X-If-Unmodified-Since", if_unmodified_since);
   }
 
@@ -1040,8 +1042,8 @@ ephy_sync_service_queue_storage_request (EphySyncService     *self,
                                          const char          *endpoint,
                                          const char          *method,
                                          const char          *request_body,
-                                         double               modified_since,
-                                         double               unmodified_since,
+                                         gint64               modified_since,
+                                         gint64               unmodified_since,
                                          SoupSessionCallback  callback,
                                          gpointer             user_data)
 {
@@ -1236,7 +1238,7 @@ upload_synchronizable_cb (SoupSession *session,
                           gpointer     user_data)
 {
   SyncAsyncData *data = (SyncAsyncData *)user_data;
-  double time_modified;
+  gint64 time_modified;
 
   /* Code 412 means that there is a more recent version on the server.
    * Download it.
@@ -1246,7 +1248,7 @@ upload_synchronizable_cb (SoupSession *session,
     ephy_sync_service_download_synchronizable (data->service, data->manager, data->synchronizable);
   } else if (msg->status_code == 200) {
     LOG ("Successfully uploaded to server");
-    time_modified = g_ascii_strtod (msg->response_body->data, NULL);
+    time_modified = ceil (g_ascii_strtod (msg->response_body->data, NULL));
     ephy_synchronizable_set_server_time_modified (data->synchronizable, time_modified);
     ephy_synchronizable_manager_save (data->manager, data->synchronizable);
   } else {
@@ -1271,7 +1273,7 @@ ephy_sync_service_upload_synchronizable (EphySyncService           *self,
   char *id_safe;
   const char *collection;
   const char *id;
-  double time_modified;
+  gint64 time_modified;
 
   g_assert (EPHY_IS_SYNC_SERVICE (self));
   g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
@@ -1583,7 +1585,7 @@ ephy_sync_service_sync_collection (EphySyncService           *self,
   if (is_initial) {
     endpoint = g_strdup_printf ("storage/%s?full=true", collection);
   } else {
-    endpoint = g_strdup_printf ("storage/%s?newer=%.2lf&full=true", collection,
+    endpoint = g_strdup_printf ("storage/%s?newer=%"PRId64"&full=true", collection,
                                 ephy_synchronizable_manager_get_sync_time (manager));
   }
 
diff --git a/lib/sync/ephy-synchronizable-manager.c b/lib/sync/ephy-synchronizable-manager.c
index fb34211..71eb1c4 100644
--- a/lib/sync/ephy-synchronizable-manager.c
+++ b/lib/sync/ephy-synchronizable-manager.c
@@ -150,7 +150,7 @@ ephy_synchronizable_manager_set_is_initial_sync (EphySynchronizableManager *mana
  *
  * Return value: the timestamp of @manager's collection last sync.
  **/
-double
+gint64
 ephy_synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 {
   EphySynchronizableManagerInterface *iface;
@@ -170,7 +170,7 @@ ephy_synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
  **/
 void
 ephy_synchronizable_manager_set_sync_time (EphySynchronizableManager *manager,
-                                           double                     sync_time)
+                                           gint64                     sync_time)
 {
   EphySynchronizableManagerInterface *iface;
 
diff --git a/lib/sync/ephy-synchronizable-manager.h b/lib/sync/ephy-synchronizable-manager.h
index 04243d4..ebc473f 100644
--- a/lib/sync/ephy-synchronizable-manager.h
+++ b/lib/sync/ephy-synchronizable-manager.h
@@ -40,9 +40,9 @@ struct _EphySynchronizableManagerInterface {
   gboolean             (*is_initial_sync)         (EphySynchronizableManager *manager);
   void                 (*set_is_initial_sync)     (EphySynchronizableManager *manager,
                                                    gboolean                   is_initial);
-  double               (*get_sync_time)           (EphySynchronizableManager *manager);
+  gint64               (*get_sync_time)           (EphySynchronizableManager *manager);
   void                 (*set_sync_time)           (EphySynchronizableManager *manager,
-                                                   double                     sync_time);
+                                                   gint64                     sync_time);
   void                 (*add)                     (EphySynchronizableManager *manager,
                                                    EphySynchronizable        *synchronizable);
   void                 (*remove)                  (EphySynchronizableManager *manager,
@@ -62,9 +62,9 @@ GType               ephy_synchronizable_manager_get_synchronizable_type (EphySyn
 gboolean            ephy_synchronizable_manager_is_initial_sync         (EphySynchronizableManager *manager);
 void                ephy_synchronizable_manager_set_is_initial_sync     (EphySynchronizableManager *manager,
                                                                          gboolean                   
is_initial);
-double              ephy_synchronizable_manager_get_sync_time           (EphySynchronizableManager *manager);
+gint64              ephy_synchronizable_manager_get_sync_time           (EphySynchronizableManager *manager);
 void                ephy_synchronizable_manager_set_sync_time           (EphySynchronizableManager *manager,
-                                                                         double                     
sync_time);
+                                                                         gint64                     
sync_time);
 void                ephy_synchronizable_manager_add                     (EphySynchronizableManager *manager,
                                                                          EphySynchronizable        
*synchronizable);
 void                ephy_synchronizable_manager_remove                  (EphySynchronizableManager *manager,
diff --git a/lib/sync/ephy-synchronizable.c b/lib/sync/ephy-synchronizable.c
index 77cb8be..4ac07e8 100644
--- a/lib/sync/ephy-synchronizable.c
+++ b/lib/sync/ephy-synchronizable.c
@@ -21,6 +21,8 @@
 #include "config.h"
 #include "ephy-synchronizable.h"
 
+#include <math.h>
+
 G_DEFINE_INTERFACE (EphySynchronizable, ephy_synchronizable, JSON_TYPE_SERIALIZABLE);
 
 static void
@@ -59,7 +61,7 @@ ephy_synchronizable_get_id (EphySynchronizable *synchronizable)
  *
  * Return value: @synchronizable's last modification time
  **/
-double
+gint64
 ephy_synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 {
   EphySynchronizableInterface *iface;
@@ -79,7 +81,7 @@ ephy_synchronizable_get_server_time_modified (EphySynchronizable *synchronizable
  **/
 void
 ephy_synchronizable_set_server_time_modified (EphySynchronizable *synchronizable,
-                                              double              server_time_modified)
+                                              gint64              server_time_modified)
 {
   EphySynchronizableInterface *iface;
 
@@ -191,7 +193,7 @@ ephy_synchronizable_from_bso (JsonNode            *bso,
   }
 
   ephy_synchronizable_set_server_time_modified (EPHY_SYNCHRONIZABLE (object),
-                                                server_time_modified);
+                                                ceil (server_time_modified));
 
 out:
   if (node)
diff --git a/lib/sync/ephy-synchronizable.h b/lib/sync/ephy-synchronizable.h
index a4b44da..d88a42d 100644
--- a/lib/sync/ephy-synchronizable.h
+++ b/lib/sync/ephy-synchronizable.h
@@ -35,17 +35,17 @@ struct _EphySynchronizableInterface {
   GTypeInterface parent_iface;
 
   const char * (*get_id)                   (EphySynchronizable  *synchronizable);
-  double       (*get_server_time_modified) (EphySynchronizable  *synchronizable);
+  gint64       (*get_server_time_modified) (EphySynchronizable  *synchronizable);
   void         (*set_server_time_modified) (EphySynchronizable  *synchronizable,
-                                            double               time_modified);
+                                            gint64               time_modified);
   JsonNode *   (*to_bso)                   (EphySynchronizable  *synchronizable,
                                             SyncCryptoKeyBundle *bundle);
 };
 
 const char *ephy_synchronizable_get_id                    (EphySynchronizable  *synchronizable);
-double      ephy_synchronizable_get_server_time_modified  (EphySynchronizable  *synchronizable);
+gint64      ephy_synchronizable_get_server_time_modified  (EphySynchronizable  *synchronizable);
 void        ephy_synchronizable_set_server_time_modified  (EphySynchronizable  *synchronizable,
-                                                           double               time_modified);
+                                                           gint64               time_modified);
 JsonNode   *ephy_synchronizable_to_bso                    (EphySynchronizable  *synchronizable,
                                                            SyncCryptoKeyBundle *bundle);
 /* This can't be an interface method because we lack the EphySynchronizable object. */
diff --git a/src/bookmarks/ephy-bookmark.c b/src/bookmarks/ephy-bookmark.c
index d84e6e9..390472e 100644
--- a/src/bookmarks/ephy-bookmark.c
+++ b/src/bookmarks/ephy-bookmark.c
@@ -39,14 +39,13 @@ struct _EphyBookmark {
   GSequence   *tags;
   gint64       time_added;
 
-  /* Firefox Sync specific fields.
-   * Time modified timestamp must be double to match server's precision. */
+  /* Firefox Sync specific fields. */
   char        *id;
   char        *type;
   char        *parent_id;
   char        *parent_name;
   gboolean     load_in_sidebar;
-  double       server_time_modified;
+  gint64       server_time_modified;
 };
 
 static void json_serializable_iface_init (JsonSerializableIface *iface);
@@ -596,7 +595,7 @@ synchronizable_get_id (EphySynchronizable *synchronizable)
   return ephy_bookmark_get_id (EPHY_BOOKMARK (synchronizable));
 }
 
-static double
+static gint64
 synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 {
   return EPHY_BOOKMARK (synchronizable)->server_time_modified;
@@ -604,7 +603,7 @@ synchronizable_get_server_time_modified (EphySynchronizable *synchronizable)
 
 static void
 synchronizable_set_server_time_modified (EphySynchronizable *synchronizable,
-                                         double              server_time_modified)
+                                         gint64              server_time_modified)
 {
   EPHY_BOOKMARK (synchronizable)->server_time_modified = server_time_modified;
 }
diff --git a/src/bookmarks/ephy-bookmarks-export.c b/src/bookmarks/ephy-bookmarks-export.c
index ae54187..47f55d7 100644
--- a/src/bookmarks/ephy-bookmarks-export.c
+++ b/src/bookmarks/ephy-bookmarks-export.c
@@ -42,12 +42,12 @@ build_variant (EphyBookmark *bookmark)
   GSequence *tags;
   GSequenceIter *iter;
 
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(xssdbas)"));
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(xssxbas)"));
 
   g_variant_builder_add (&builder, "x", ephy_bookmark_get_time_added (bookmark));
   g_variant_builder_add (&builder, "s", ephy_bookmark_get_title (bookmark));
   g_variant_builder_add (&builder, "s", ephy_bookmark_get_id (bookmark));
-  g_variant_builder_add (&builder, "d", ephy_synchronizable_get_server_time_modified (EPHY_SYNCHRONIZABLE 
(bookmark)));
+  g_variant_builder_add (&builder, "x", ephy_synchronizable_get_server_time_modified (EPHY_SYNCHRONIZABLE 
(bookmark)));
   g_variant_builder_add (&builder, "b", ephy_bookmark_is_uploaded (bookmark));
 
   g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
diff --git a/src/bookmarks/ephy-bookmarks-import.c b/src/bookmarks/ephy-bookmarks-import.c
index b8cfd0a..c942ab3 100644
--- a/src/bookmarks/ephy-bookmarks-import.c
+++ b/src/bookmarks/ephy-bookmarks-import.c
@@ -58,13 +58,13 @@ get_bookmarks_from_table (GvdbTable *table)
     const char *title;
     gint64 time_added;
     char *id;
-    double server_time_modified;
+    gint64 server_time_modified;
     gboolean is_uploaded;
 
     /* Obtain the corresponding GVariant. */
     value = gvdb_table_get_value (table, list[i]);
 
-    g_variant_get (value, "(x&s&sdbas)",
+    g_variant_get (value, "(x&s&sxbas)",
                    &time_added, &title, &id,
                    &server_time_modified, &is_uploaded, &iter);
 
diff --git a/src/bookmarks/ephy-bookmarks-manager.c b/src/bookmarks/ephy-bookmarks-manager.c
index b39310b..8b5202a 100644
--- a/src/bookmarks/ephy-bookmarks-manager.c
+++ b/src/bookmarks/ephy-bookmarks-manager.c
@@ -685,7 +685,7 @@ synchronizable_manager_set_is_initial_sync (EphySynchronizableManager *manager,
   ephy_sync_utils_set_bookmarks_sync_is_initial (is_initial);
 }
 
-static double
+static gint64
 synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 {
   return ephy_sync_utils_get_bookmarks_sync_time ();
@@ -693,7 +693,7 @@ synchronizable_manager_get_sync_time (EphySynchronizableManager *manager)
 
 static void
 synchronizable_manager_set_sync_time (EphySynchronizableManager *manager,
-                                      double                     sync_time)
+                                      gint64                     sync_time)
 {
   ephy_sync_utils_set_bookmarks_sync_time (sync_time);
 }
@@ -739,7 +739,7 @@ ephy_bookmarks_manager_handle_initial_merge (EphyBookmarksManager *self,
   GSequence *bookmarks;
   GSequenceIter *iter;
   GHashTable *dont_upload;
-  double timestamp;
+  gint64 timestamp;
 
   g_assert (EPHY_IS_BOOKMARKS_MANAGER (self));
 
@@ -830,7 +830,7 @@ ephy_bookmarks_manager_handle_regular_merge (EphyBookmarksManager *self,
 {
   GPtrArray *to_upload;
   EphyBookmark *bookmark;
-  double timestamp;
+  gint64 timestamp;
 
   g_assert (EPHY_IS_BOOKMARKS_MANAGER (self));
 
diff --git a/src/profile-migrator/ephy-profile-migrator.c b/src/profile-migrator/ephy-profile-migrator.c
index 227b545..42c8128 100644
--- a/src/profile-migrator/ephy-profile-migrator.c
+++ b/src/profile-migrator/ephy-profile-migrator.c
@@ -34,16 +34,20 @@
 #include "ephy-sync-utils.h"
 #include "ephy-uri-tester-shared.h"
 #include "ephy-web-app-utils.h"
+#include "gvdb-builder.h"
+#include "gvdb-reader.h"
 
 #include <errno.h>
 #include <fcntl.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
+#include <inttypes.h>
 #include <libsecret/secret.h>
 #include <libsoup/soup.h>
 #include <libxml/HTMLtree.h>
 #include <libxml/xmlreader.h>
 #include <locale.h>
+#include <math.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <webkit2/webkit2.h>
@@ -970,6 +974,199 @@ migrate_sync_device_info (void)
   json_object_unref (device);
 }
 
+static GVariant *
+convert_bookmark_timestamp (GVariant *value)
+{
+  GVariantBuilder builder;
+  GVariantIter *iter;
+  gboolean is_uploaded;
+  gint64 time_added;
+  gint64 timestamp_i;
+  double timestamp_d;
+  const char *title;
+  const char *id;
+  char *tag;
+
+  g_variant_get (value, "(x&s&sdbas)",
+                 &time_added, &title, &id,
+                 &timestamp_d, &is_uploaded, &iter);
+  timestamp_i = ceil (timestamp_d);
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(xssxbas)"));
+  g_variant_builder_add (&builder, "x", time_added);
+  g_variant_builder_add (&builder, "s", title);
+  g_variant_builder_add (&builder, "s", id);
+  g_variant_builder_add (&builder, "x", timestamp_i);
+  g_variant_builder_add (&builder, "b", is_uploaded);
+
+  g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
+  while (g_variant_iter_next (iter, "s", &tag)) {
+    g_variant_builder_add (&builder, "s", tag);
+    g_free (tag);
+  }
+  g_variant_builder_close (&builder);
+
+  g_variant_iter_free (iter);
+
+  return g_variant_builder_end (&builder);
+}
+
+static void
+migrate_bookmarks_timestamp (void)
+{
+  GvdbTable *root_table_in = NULL;
+  GvdbTable *bookmarks_table_in = NULL;
+  GvdbTable *tags_table_in = NULL;
+  GHashTable *root_table_out = NULL;
+  GHashTable *bookmarks_table_out = NULL;
+  GHashTable *tags_table_out = NULL;
+  GError *error = NULL;
+  char **tags = NULL;
+  char **urls = NULL;
+  char *filename;
+  int length;
+
+  filename = g_build_filename (ephy_dot_dir (), EPHY_BOOKMARKS_FILE, NULL);
+  root_table_in = gvdb_table_new (filename, TRUE, &error);
+  if (error) {
+    g_warning ("Failed to create Gvdb table: %s", error->message);
+    goto out;
+  }
+
+  bookmarks_table_in = gvdb_table_get_table (root_table_in, "bookmarks");
+  if (!bookmarks_table_in) {
+    g_warning ("Failed to find bookmarks inner table");
+    goto out;
+  }
+
+  tags_table_in = gvdb_table_get_table (root_table_in, "tags");
+  if (!tags_table_in) {
+    g_warning ("Failed to find tags inner table");
+    goto out;
+  }
+
+  root_table_out = gvdb_hash_table_new (NULL, NULL);
+  bookmarks_table_out = gvdb_hash_table_new (root_table_out, "bookmarks");
+  tags_table_out = gvdb_hash_table_new (root_table_out, "tags");
+
+  tags = gvdb_table_get_names (tags_table_in, &length);
+  for (int i = 0; i < length; i++)
+    gvdb_hash_table_insert (tags_table_out, tags[i]);
+
+  urls = gvdb_table_get_names (bookmarks_table_in, &length);
+  for (int i = 0; i < length; i++) {
+    GVariant *value = gvdb_table_get_value (bookmarks_table_in, urls[i]);
+    GVariant *new_value = convert_bookmark_timestamp (value);
+    GvdbItem *item = gvdb_hash_table_insert (bookmarks_table_out, urls[i]);
+    gvdb_item_set_value (item, new_value);
+    g_variant_unref (value);
+  }
+
+  gvdb_table_write_contents (root_table_out, filename, FALSE, NULL);
+
+out:
+  if (error)
+    g_error_free (error);
+  if (root_table_out)
+    g_hash_table_unref (root_table_out);
+  if (bookmarks_table_out)
+    g_hash_table_unref (bookmarks_table_out);
+  if (tags_table_out)
+    g_hash_table_unref (tags_table_out);
+  if (root_table_in)
+    gvdb_table_free (root_table_in);
+  if (bookmarks_table_in)
+    gvdb_table_free (bookmarks_table_in);
+  if (tags_table_in)
+    gvdb_table_free (tags_table_in);
+  g_strfreev (urls);
+  g_strfreev (tags);
+  g_free (filename);
+}
+
+static void
+migrate_passwords_timestamp (void)
+{
+  GHashTable *attributes;
+  GHashTable *attrs;
+  SecretItem *item;
+  SecretValue *value;
+  GList *passwords = NULL;
+  GError *error = NULL;
+  const char *origin;
+  const char *username;
+  const char *timestamp;
+  char *label;
+  double timestamp_d;
+  gint64 timestamp_i;
+  int default_profile_migration_version;
+
+  /* We want this migration to run only once. */
+  default_profile_migration_version = ephy_profile_utils_get_migration_version_for_profile_dir 
(ephy_default_dot_dir ());
+  if (default_profile_migration_version >= EPHY_PASSWORDS_TIMESTAMP_MIGRATION_VERSION)
+    return;
+
+  attributes = secret_attributes_build (EPHY_FORM_PASSWORD_SCHEMA, NULL);
+  passwords = secret_service_search_sync (NULL, EPHY_FORM_PASSWORD_SCHEMA, attributes,
+                                          SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | 
SECRET_SEARCH_LOAD_SECRETS,
+                                          NULL, &error);
+  if (error) {
+    g_warning ("Failed to search the password schema: %s", error->message);
+    goto out;
+  }
+
+  secret_service_clear_sync (NULL, EPHY_FORM_PASSWORD_SCHEMA,
+                             attributes, NULL, &error);
+  if (error) {
+    g_warning ("Failed to clear the password schema: %s", error->message);
+    goto out;
+  }
+
+  for (GList *p = passwords; p && p->data; p = p->next) {
+    item = (SecretItem *)p->data;
+    value = secret_item_get_secret (item);
+
+    if (!value)
+      continue;
+
+    attrs = secret_item_get_attributes (item);
+    origin = g_hash_table_lookup (attrs, ORIGIN_KEY);
+    username = g_hash_table_lookup (attrs, USERNAME_KEY);
+    timestamp = g_hash_table_lookup (attrs, SERVER_TIME_MODIFIED_KEY);
+
+    if (!origin || !timestamp)
+      goto next;
+
+    timestamp_d = g_ascii_strtod (timestamp, NULL);
+    timestamp_i = (gint64)ceil (timestamp_d);
+    g_hash_table_insert (attrs, g_strdup (SERVER_TIME_MODIFIED_KEY), g_strdup_printf ("%"PRId64, 
timestamp_i));
+
+    if (username)
+      label = g_strdup_printf ("Password for %s in a form in %s", username, origin);
+    else
+      label = g_strdup_printf ("Password in a form in %s", origin);
+
+    secret_service_store_sync (NULL, EPHY_FORM_PASSWORD_SCHEMA,
+                               attrs, NULL, label,
+                               value, NULL, &error);
+    if (error) {
+      g_warning ("Failed to store password: %s", error->message);
+      g_clear_pointer (&error, g_error_free);
+    }
+
+    g_free (label);
+next:
+    g_hash_table_unref (attrs);
+    secret_value_unref (value);
+  }
+
+out:
+  if (error)
+    g_error_free (error);
+  g_hash_table_unref (attributes);
+  g_list_free_full (passwords, g_object_unref);
+}
+
 static void
 migrate_nothing (void)
 {
@@ -1007,6 +1204,8 @@ const EphyProfileMigrator migrators[] = {
   /* 21 */ migrate_passwords_add_target_origin,
   /* 22 */ migrate_sync_settings_path,
   /* 23 */ migrate_sync_device_info,
+  /* 24 */ migrate_bookmarks_timestamp,
+  /* 25 */ migrate_passwords_timestamp,
 };
 
 static gboolean



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