[libsoup] Add SoupCookieJarDB to replace SoupCookieJarSqlite



commit ade7a484f33f223defad9acb50396058767781e1
Author: Dan Winship <danw gnome org>
Date:   Tue Dec 11 18:43:42 2012 +0100

    Add SoupCookieJarDB to replace SoupCookieJarSqlite
    
    Move SoupCookieJarSqlite (and its sqlite3 dependency) into libsoup
    from libsoup-gnome, but rename it to SoupCookieJarDB so libsoup-gnome
    can keep using the old name. SoupCookieJarSqlite is now just a
    wrapper around SoupCookieJarDB.

 configure.ac                            |   14 +-
 docs/reference/libsoup-2.4-docs.sgml    |    2 +-
 docs/reference/libsoup-2.4-sections.txt |   27 ++--
 libsoup/Makefile.am                     |    6 +-
 libsoup/libsoup-2.4.sym                 |    2 +
 libsoup/soup-cookie-jar-db.c            |  337 +++++++++++++++++++++++++++++++
 libsoup/soup-cookie-jar-db.h            |   46 +++++
 libsoup/soup-cookie-jar-sqlite.c        |  298 +--------------------------
 libsoup/soup-cookie-jar-sqlite.h        |   13 +-
 libsoup/soup.h                          |    1 +
 10 files changed, 419 insertions(+), 327 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3f5097c..fe5403b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,10 @@ PKG_CHECK_MODULES(XML, libxml-2.0)
 AC_SUBST(XML_CFLAGS)
 AC_SUBST(XML_LIBS)
 
+PKG_CHECK_MODULES(SQLITE, sqlite3)
+AC_SUBST(SQLITE_CFLAGS)
+AC_SUBST(SQLITE_LIBS)
+
 dnl ***********************
 dnl *** Check for Win32 ***
 dnl ***********************
@@ -142,18 +146,8 @@ AM_CONDITIONAL(BUILD_LIBSOUP_GNOME, test $with_gnome != no)
 
 if test $with_gnome != no; then
 	AC_DEFINE(HAVE_GNOME, 1, [Defined if GNOME support is enabled])
-
-	PKG_CHECK_MODULES(SQLITE, sqlite3, :, [AC_MSG_ERROR(dnl
-[Could not find sqlite3 devel files:
-
-$SQLITE_PKG_ERRORS
-
-Pass "--without-gnome" to configure if you want to build libsoup
-without GNOME support.])])
 fi
 AC_SUBST(HAVE_GNOME)
-AC_SUBST(SQLITE_CFLAGS)
-AC_SUBST(SQLITE_LIBS)
 
 
 dnl ***************
diff --git a/docs/reference/libsoup-2.4-docs.sgml b/docs/reference/libsoup-2.4-docs.sgml
index 3f24676..1273eca 100644
--- a/docs/reference/libsoup-2.4-docs.sgml
+++ b/docs/reference/libsoup-2.4-docs.sgml
@@ -49,6 +49,7 @@
     <xi:include href="xml/soup-content-sniffer.xml"/>
     <xi:include href="xml/soup-cookie-jar.xml"/>
     <xi:include href="xml/soup-cookie-jar-text.xml"/>
+    <xi:include href="xml/soup-cookie-jar-db.xml"/>
     <xi:include href="xml/soup-logger.xml"/>
     <xi:include href="xml/soup-proxy-uri-resolver.xml"/>
     <xi:include href="xml/soup-proxy-resolver-default.xml"/>
@@ -64,7 +65,6 @@
   <chapter>
     <title>GNOME integration</title>
     <xi:include href="xml/soup-gnome-features.xml"/>
-    <xi:include href="xml/soup-cookie-jar-sqlite.xml"/>
   </chapter>
 
   <chapter>
diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt
index 43388ef..f8e6dbf 100644
--- a/docs/reference/libsoup-2.4-sections.txt
+++ b/docs/reference/libsoup-2.4-sections.txt
@@ -973,22 +973,21 @@ soup_cookie_jar_text_get_type
 </SECTION>
 
 <SECTION>
-<INCLUDE>libsoup/soup-gnome.h</INCLUDE>
-<FILE>soup-cookie-jar-sqlite</FILE>
-<TITLE>SoupCookieJarSqlite</TITLE>
-SoupCookieJarSqlite
-soup_cookie_jar_sqlite_new
+<FILE>soup-cookie-jar-db</FILE>
+<TITLE>SoupCookieJarDB</TITLE>
+SoupCookieJarDB
+soup_cookie_jar_db_new
 <SUBSECTION>
-SOUP_COOKIE_JAR_SQLITE_FILENAME
+SOUP_COOKIE_JAR_DB_FILENAME
 <SUBSECTION Standard>
-SoupCookieJarSqliteClass
-SOUP_COOKIE_JAR_SQLITE
-SOUP_COOKIE_JAR_SQLITE_CLASS
-SOUP_COOKIE_JAR_SQLITE_GET_CLASS
-SOUP_TYPE_COOKIE_JAR_SQLITE
-SOUP_IS_COOKIE_JAR_SQLITE
-SOUP_IS_COOKIE_JAR_SQLITE_CLASS
-soup_cookie_jar_sqlite_get_type
+SoupCookieJarDBClass
+SOUP_COOKIE_JAR_DB
+SOUP_COOKIE_JAR_DB_CLASS
+SOUP_COOKIE_JAR_DB_GET_CLASS
+SOUP_TYPE_COOKIE_JAR_DB
+SOUP_IS_COOKIE_JAR_DB
+SOUP_IS_COOKIE_JAR_DB_CLASS
+soup_cookie_jar_db_get_type
 </SECTION>
 
 <SECTION>
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 3a256e0..87629ed 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -34,6 +34,7 @@ soup_headers =			\
 	soup-content-sniffer.h	\
 	soup-cookie.h		\
 	soup-cookie-jar.h	\
+	soup-cookie-jar-db.h	\
 	soup-cookie-jar-text.h	\
 	soup-date.h		\
 	soup-form.h		\
@@ -88,6 +89,7 @@ EXTRA_DIST += libsoup-2.4.sym
 libsoup_2_4_la_LIBADD =			\
 	$(GLIB_LIBS)			\
 	$(XML_LIBS)			\
+	$(SQLITE_LIBS)			\
 	-lz				\
 	$(LIBWS2_32)
 
@@ -127,6 +129,7 @@ libsoup_2_4_la_SOURCES =		\
 	soup-converter-wrapper.c	\
 	soup-cookie.c			\
 	soup-cookie-jar.c		\
+	soup-cookie-jar-db.c		\
 	soup-cookie-jar-text.c		\
 	soup-date.c			\
 	soup-directory-input-stream.h	\
@@ -212,8 +215,7 @@ EXTRA_DIST += libsoup-gnome-2.4.sym
 
 libsoup_gnome_2_4_la_LIBADD =		\
 	libsoup-2.4.la			\
-	$(GLIB_LIBS)			\
-	$(SQLITE_LIBS)
+	$(GLIB_LIBS)
 
 libsoup_gnome_2_4_la_SOURCES =		\
 	soup-cookie-jar-sqlite.c	\
diff --git a/libsoup/libsoup-2.4.sym b/libsoup/libsoup-2.4.sym
index aa302c6..66e5bf7 100644
--- a/libsoup/libsoup-2.4.sym
+++ b/libsoup/libsoup-2.4.sym
@@ -110,6 +110,8 @@ soup_cookie_jar_accept_policy_get_type
 soup_cookie_jar_add_cookie
 soup_cookie_jar_add_cookie_with_first_party
 soup_cookie_jar_all_cookies
+soup_cookie_jar_db_get_type
+soup_cookie_jar_db_new
 soup_cookie_jar_delete_cookie
 soup_cookie_jar_get_accept_policy
 soup_cookie_jar_get_cookie_list
diff --git a/libsoup/soup-cookie-jar-db.c b/libsoup/soup-cookie-jar-db.c
new file mode 100644
index 0000000..8f21baa
--- /dev/null
+++ b/libsoup/soup-cookie-jar-db.c
@@ -0,0 +1,337 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-cookie-jar-db.c: database-based cookie storage
+ *
+ * Using danw's soup-cookie-jar-text as template
+ * Copyright (C) 2008 Diego Escalante Urrelo
+ * Copyright (C) 2009 Collabora Ltd.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <sqlite3.h>
+
+#include "soup-cookie-jar-db.h"
+#include "soup.h"
+
+/**
+ * SECTION:soup-cookie-jar-db
+ * @short_description: Database-based Cookie Jar
+ *
+ * #SoupCookieJarDB is a #SoupCookieJar that reads cookies from and
+ * writes them to a sqlite database in the new Mozilla format.
+ *
+ * (This is identical to <literal>SoupCookieJarSqlite</literal> in
+ * libsoup-gnome; it has just been moved into libsoup proper, and
+ * renamed to avoid conflicting.)
+ **/
+
+enum {
+	PROP_0,
+
+	PROP_FILENAME,
+
+	LAST_PROP
+};
+
+typedef struct {
+	char *filename;
+	sqlite3 *db;
+} SoupCookieJarDBPrivate;
+
+#define SOUP_COOKIE_JAR_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBPrivate))
+
+G_DEFINE_TYPE (SoupCookieJarDB, soup_cookie_jar_db, SOUP_TYPE_COOKIE_JAR)
+
+static void load (SoupCookieJar *jar);
+
+static void
+soup_cookie_jar_db_init (SoupCookieJarDB *db)
+{
+}
+
+static void
+soup_cookie_jar_db_finalize (GObject *object)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (object);
+
+	g_free (priv->filename);
+	g_clear_pointer (&priv->db, sqlite3_close);
+
+	G_OBJECT_CLASS (soup_cookie_jar_db_parent_class)->finalize (object);
+}
+
+static void
+soup_cookie_jar_db_set_property (GObject *object, guint prop_id,
+				 const GValue *value, GParamSpec *pspec)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_FILENAME:
+		priv->filename = g_value_dup_string (value);
+		load (SOUP_COOKIE_JAR (object));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+soup_cookie_jar_db_get_property (GObject *object, guint prop_id,
+				 GValue *value, GParamSpec *pspec)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_FILENAME:
+		g_value_set_string (value, priv->filename);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+/**
+ * soup_cookie_jar_db_new:
+ * @filename: the filename to read to/write from, or %NULL
+ * @read_only: %TRUE if @filename is read-only
+ *
+ * Creates a #SoupCookieJarDB.
+ *
+ * @filename will be read in at startup to create an initial set of
+ * cookies. If @read_only is %FALSE, then the non-session cookies will
+ * be written to @filename when the 'changed' signal is emitted from
+ * the jar. (If @read_only is %TRUE, then the cookie jar will only be
+ * used for this session, and changes made to it will be lost when the
+ * jar is destroyed.)
+ *
+ * Return value: the new #SoupCookieJar
+ *
+ * Since: 2.42
+ **/
+SoupCookieJar *
+soup_cookie_jar_db_new (const char *filename, gboolean read_only)
+{
+	g_return_val_if_fail (filename != NULL, NULL);
+
+	return g_object_new (SOUP_TYPE_COOKIE_JAR_DB,
+			     SOUP_COOKIE_JAR_DB_FILENAME, filename,
+			     SOUP_COOKIE_JAR_READ_ONLY, read_only,
+			     NULL);
+}
+
+#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;"
+#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
+#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);"
+#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;"
+
+enum {
+	COL_ID,
+	COL_NAME,
+	COL_VALUE,
+	COL_HOST,
+	COL_PATH,
+	COL_EXPIRY,
+	COL_LAST_ACCESS,
+	COL_SECURE,
+	COL_HTTP_ONLY,
+	N_COL,
+};
+
+static int
+callback (void *data, int argc, char **argv, char **colname)
+{
+	SoupCookie *cookie = NULL;
+	SoupCookieJar *jar = SOUP_COOKIE_JAR (data);
+
+	char *name, *value, *host, *path;
+	gulong expire_time;
+	time_t now;
+	int max_age;
+	gboolean http_only = FALSE, secure = FALSE;
+
+	now = time (NULL);
+
+	name = argv[COL_NAME];
+	value = argv[COL_VALUE];
+	host = argv[COL_HOST];
+	path = argv[COL_PATH];
+	expire_time = strtoul (argv[COL_EXPIRY], NULL, 10);
+
+	if (now >= expire_time)
+		return 0;
+	max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
+
+	http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0);
+	secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0);
+
+	cookie = soup_cookie_new (name, value, host, path, max_age);
+
+	if (secure)
+		soup_cookie_set_secure (cookie, TRUE);
+	if (http_only)
+		soup_cookie_set_http_only (cookie, TRUE);
+
+	soup_cookie_jar_add_cookie (jar, cookie);
+
+	return 0;
+}
+
+static void
+try_create_table (sqlite3 *db)
+{
+	char *error = NULL;
+
+	if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) {
+		g_warning ("Failed to execute query: %s", error);
+		sqlite3_free (error);
+	}
+}
+
+static void
+exec_query_with_try_create_table (sqlite3 *db,
+				  const char *sql,
+				  int (*callback)(void*,int,char**,char**),
+				  void *argument)
+{
+	char *error = NULL;
+	gboolean try_create = TRUE;
+
+try_exec:
+	if (sqlite3_exec (db, sql, callback, argument, &error)) {
+		if (try_create) {
+			try_create = FALSE;
+			try_create_table (db);
+			sqlite3_free (error);
+			error = NULL;
+			goto try_exec;
+		} else {
+			g_warning ("Failed to execute query: %s", error);
+			sqlite3_free (error);
+		}
+	}
+}
+
+/* Follows sqlite3 convention; returns TRUE on error */
+static gboolean
+open_db (SoupCookieJar *jar)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar);
+
+	char *error = NULL;
+
+	if (sqlite3_open (priv->filename, &priv->db)) {
+		sqlite3_close (priv->db);
+		priv->db = NULL;
+		g_warning ("Can't open %s", priv->filename);
+		return TRUE;
+	}
+
+	if (sqlite3_exec (priv->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) {
+		g_warning ("Failed to execute query: %s", error);
+		sqlite3_free (error);
+	}
+
+	return FALSE;
+}
+
+static void
+load (SoupCookieJar *jar)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar);
+
+	if (priv->db == NULL) {
+		if (open_db (jar))
+			return;
+	}
+
+	exec_query_with_try_create_table (priv->db, QUERY_ALL, callback, jar);
+}
+
+static void
+soup_cookie_jar_db_changed (SoupCookieJar *jar,
+			    SoupCookie    *old_cookie,
+			    SoupCookie    *new_cookie)
+{
+	SoupCookieJarDBPrivate *priv =
+		SOUP_COOKIE_JAR_DB_GET_PRIVATE (jar);
+	char *query;
+
+	if (priv->db == NULL) {
+		if (open_db (jar))
+			return;
+	}
+
+	if (old_cookie) {
+		query = sqlite3_mprintf (QUERY_DELETE,
+					 old_cookie->name,
+					 old_cookie->domain);
+		exec_query_with_try_create_table (priv->db, query, NULL, NULL);
+		sqlite3_free (query);
+	}
+
+	if (new_cookie && new_cookie->expires) {
+		gulong expires;
+		
+		expires = (gulong)soup_date_to_time_t (new_cookie->expires);
+		query = sqlite3_mprintf (QUERY_INSERT, 
+					 new_cookie->name,
+					 new_cookie->value,
+					 new_cookie->domain,
+					 new_cookie->path,
+					 expires,
+					 new_cookie->secure,
+					 new_cookie->http_only);
+		exec_query_with_try_create_table (priv->db, query, NULL, NULL);
+		sqlite3_free (query);
+	}
+}
+
+static gboolean
+soup_cookie_jar_db_is_persistent (SoupCookieJar *jar)
+{
+	return TRUE;
+}
+
+static void
+soup_cookie_jar_db_class_init (SoupCookieJarDBClass *db_class)
+{
+	SoupCookieJarClass *cookie_jar_class =
+		SOUP_COOKIE_JAR_CLASS (db_class);
+	GObjectClass *object_class = G_OBJECT_CLASS (db_class);
+
+	g_type_class_add_private (db_class, sizeof (SoupCookieJarDBPrivate));
+
+	cookie_jar_class->is_persistent = soup_cookie_jar_db_is_persistent;
+	cookie_jar_class->changed       = soup_cookie_jar_db_changed;
+
+	object_class->finalize     = soup_cookie_jar_db_finalize;
+	object_class->set_property = soup_cookie_jar_db_set_property;
+	object_class->get_property = soup_cookie_jar_db_get_property;
+
+	/**
+	 * SOUP_COOKIE_JAR_DB_FILENAME:
+	 *
+	 * Alias for the #SoupCookieJarDB:filename property. (The
+	 * cookie-storage filename.)
+	 **/
+	g_object_class_install_property (
+		object_class, PROP_FILENAME,
+		g_param_spec_string (SOUP_COOKIE_JAR_DB_FILENAME,
+				     "Filename",
+				     "Cookie-storage filename",
+				     NULL,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libsoup/soup-cookie-jar-db.h b/libsoup/soup-cookie-jar-db.h
new file mode 100644
index 0000000..1a98901
--- /dev/null
+++ b/libsoup/soup-cookie-jar-db.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Diego Escalante Urrelo
+ */
+
+#ifndef SOUP_COOKIE_JAR_DB_H
+#define SOUP_COOKIE_JAR_DB_H 1
+
+#include <libsoup/soup-cookie-jar.h>
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_COOKIE_JAR_DB            (soup_cookie_jar_db_get_type ())
+#define SOUP_COOKIE_JAR_DB(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDB))
+#define SOUP_COOKIE_JAR_DB_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBClass))
+#define SOUP_IS_COOKIE_JAR_DB(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_COOKIE_JAR_DB))
+#define SOUP_IS_COOKIE_JAR_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_COOKIE_JAR_DB))
+#define SOUP_COOKIE_JAR_DB_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_COOKIE_JAR_DB, SoupCookieJarDBClass))
+
+typedef struct {
+	SoupCookieJar parent;
+
+} SoupCookieJarDB;
+
+typedef struct {
+	SoupCookieJarClass parent_class;
+
+	/* Padding for future expansion */
+	void (*_libsoup_reserved1) (void);
+	void (*_libsoup_reserved2) (void);
+	void (*_libsoup_reserved3) (void);
+	void (*_libsoup_reserved4) (void);
+} SoupCookieJarDBClass;
+
+#define SOUP_COOKIE_JAR_DB_FILENAME  "filename"
+
+SOUP_AVAILABLE_IN_2_42
+GType soup_cookie_jar_db_get_type (void);
+
+SOUP_AVAILABLE_IN_2_42
+SoupCookieJar *soup_cookie_jar_db_new (const char *filename,
+				       gboolean    read_only);
+
+G_END_DECLS
+
+#endif /* SOUP_COOKIE_JAR_DB_H */
diff --git a/libsoup/soup-cookie-jar-sqlite.c b/libsoup/soup-cookie-jar-sqlite.c
index 97e6a0e..705e047 100644
--- a/libsoup/soup-cookie-jar-sqlite.c
+++ b/libsoup/soup-cookie-jar-sqlite.c
@@ -1,10 +1,8 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * soup-cookie-jar-sqlite.c: ff sqlite-based cookie storage
+ * soup-cookie-jar-sqlite.c: deprecated version of sqlite-based cookie storage
  *
- * Using danw's soup-cookie-jar-text as template
- * Copyright (C) 2008 Diego Escalante Urrelo
- * Copyright (C) 2009 Collabora Ltd.
+ * Copyright 2012 Red Hat, Inc.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -13,18 +11,11 @@
 
 #include <stdlib.h>
 
-#include <sqlite3.h>
+/* Avoid deprecation warnings */
+#define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_40
 
-#include "soup-cookie-jar-sqlite.h"
 #include "soup.h"
-
-/**
- * SECTION:soup-cookie-jar-sqlite
- * @short_description: SQLite-based Cookie Jar
- *
- * #SoupCookieJarSqlite is a #SoupCookieJar that reads cookies from and
- * writes them to an SQLite file in the new Mozilla format.
- **/
+#include "soup-cookie-jar-sqlite.h"
 
 enum {
 	PROP_0,
@@ -34,89 +25,13 @@ enum {
 	LAST_PROP
 };
 
-typedef struct {
-	char *filename;
-	sqlite3 *db;
-} SoupCookieJarSqlitePrivate;
-
-#define SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_COOKIE_JAR_SQLITE, SoupCookieJarSqlitePrivate))
-
-G_DEFINE_TYPE (SoupCookieJarSqlite, soup_cookie_jar_sqlite, SOUP_TYPE_COOKIE_JAR)
-
-static void load (SoupCookieJar *jar);
+G_DEFINE_TYPE (SoupCookieJarSqlite, soup_cookie_jar_sqlite, SOUP_TYPE_COOKIE_JAR_DB)
 
 static void
 soup_cookie_jar_sqlite_init (SoupCookieJarSqlite *sqlite)
 {
 }
 
-static void
-soup_cookie_jar_sqlite_finalize (GObject *object)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object);
-
-	g_free (priv->filename);
-
-	if (priv->db)
-		sqlite3_close (priv->db);
-
-	G_OBJECT_CLASS (soup_cookie_jar_sqlite_parent_class)->finalize (object);
-}
-
-static void
-soup_cookie_jar_sqlite_set_property (GObject *object, guint prop_id,
-				     const GValue *value, GParamSpec *pspec)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object);
-
-	switch (prop_id) {
-	case PROP_FILENAME:
-		priv->filename = g_value_dup_string (value);
-		load (SOUP_COOKIE_JAR (object));
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-soup_cookie_jar_sqlite_get_property (GObject *object, guint prop_id,
-				     GValue *value, GParamSpec *pspec)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (object);
-
-	switch (prop_id) {
-	case PROP_FILENAME:
-		g_value_set_string (value, priv->filename);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-/**
- * soup_cookie_jar_sqlite_new:
- * @filename: the filename to read to/write from, or %NULL
- * @read_only: %TRUE if @filename is read-only
- *
- * Creates a #SoupCookieJarSqlite.
- *
- * @filename will be read in at startup to create an initial set of
- * cookies. If @read_only is %FALSE, then the non-session cookies will
- * be written to @filename when the 'changed' signal is emitted from
- * the jar. (If @read_only is %TRUE, then the cookie jar will only be
- * used for this session, and changes made to it will be lost when the
- * jar is destroyed.)
- *
- * Return value: the new #SoupCookieJar
- *
- * Since: 2.26
- **/
 SoupCookieJar *
 soup_cookie_jar_sqlite_new (const char *filename, gboolean read_only)
 {
@@ -128,208 +43,7 @@ soup_cookie_jar_sqlite_new (const char *filename, gboolean read_only)
 			     NULL);
 }
 
-#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;"
-#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
-#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);"
-#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;"
-
-enum {
-	COL_ID,
-	COL_NAME,
-	COL_VALUE,
-	COL_HOST,
-	COL_PATH,
-	COL_EXPIRY,
-	COL_LAST_ACCESS,
-	COL_SECURE,
-	COL_HTTP_ONLY,
-	N_COL,
-};
-
-static int
-callback (void *data, int argc, char **argv, char **colname)
-{
-	SoupCookie *cookie = NULL;
-	SoupCookieJar *jar = SOUP_COOKIE_JAR (data);
-
-	char *name, *value, *host, *path;
-	gulong expire_time;
-	time_t now;
-	int max_age;
-	gboolean http_only = FALSE, secure = FALSE;
-
-	now = time (NULL);
-
-	name = argv[COL_NAME];
-	value = argv[COL_VALUE];
-	host = argv[COL_HOST];
-	path = argv[COL_PATH];
-	expire_time = strtoul (argv[COL_EXPIRY], NULL, 10);
-
-	if (now >= expire_time)
-		return 0;
-	max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
-
-	http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0);
-	secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0);
-
-	cookie = soup_cookie_new (name, value, host, path, max_age);
-
-	if (secure)
-		soup_cookie_set_secure (cookie, TRUE);
-	if (http_only)
-		soup_cookie_set_http_only (cookie, TRUE);
-
-	soup_cookie_jar_add_cookie (jar, cookie);
-
-	return 0;
-}
-
-static void
-try_create_table (sqlite3 *db)
-{
-	char *error = NULL;
-
-	if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) {
-		g_warning ("Failed to execute query: %s", error);
-		sqlite3_free (error);
-	}
-}
-
-static void
-exec_query_with_try_create_table (sqlite3 *db,
-				  const char *sql,
-				  int (*callback)(void*,int,char**,char**),
-				  void *argument)
-{
-	char *error = NULL;
-	gboolean try_create = TRUE;
-
-try_exec:
-	if (sqlite3_exec (db, sql, callback, argument, &error)) {
-		if (try_create) {
-			try_create = FALSE;
-			try_create_table (db);
-			sqlite3_free (error);
-			error = NULL;
-			goto try_exec;
-		} else {
-			g_warning ("Failed to execute query: %s", error);
-			sqlite3_free (error);
-		}
-	}
-}
-
-/* Follows sqlite3 convention; returns TRUE on error */
-static gboolean
-open_db (SoupCookieJar *jar)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar);
-
-	char *error = NULL;
-
-	if (sqlite3_open (priv->filename, &priv->db)) {
-		sqlite3_close (priv->db);
-		priv->db = NULL;
-		g_warning ("Can't open %s", priv->filename);
-		return TRUE;
-	}
-
-	if (sqlite3_exec (priv->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) {
-		g_warning ("Failed to execute query: %s", error);
-		sqlite3_free (error);
-	}
-
-	return FALSE;
-}
-
-static void
-load (SoupCookieJar *jar)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar);
-
-	if (priv->db == NULL) {
-		if (open_db (jar))
-			return;
-	}
-
-	exec_query_with_try_create_table (priv->db, QUERY_ALL, callback, jar);
-}
-
-static void
-soup_cookie_jar_sqlite_changed (SoupCookieJar *jar,
-				SoupCookie    *old_cookie,
-				SoupCookie    *new_cookie)
-{
-	SoupCookieJarSqlitePrivate *priv =
-		SOUP_COOKIE_JAR_SQLITE_GET_PRIVATE (jar);
-	char *query;
-
-	if (priv->db == NULL) {
-		if (open_db (jar))
-			return;
-	}
-
-	if (old_cookie) {
-		query = sqlite3_mprintf (QUERY_DELETE,
-					 old_cookie->name,
-					 old_cookie->domain);
-		exec_query_with_try_create_table (priv->db, query, NULL, NULL);
-		sqlite3_free (query);
-	}
-
-	if (new_cookie && new_cookie->expires) {
-		gulong expires;
-		
-		expires = (gulong)soup_date_to_time_t (new_cookie->expires);
-		query = sqlite3_mprintf (QUERY_INSERT, 
-					 new_cookie->name,
-					 new_cookie->value,
-					 new_cookie->domain,
-					 new_cookie->path,
-					 expires,
-					 new_cookie->secure,
-					 new_cookie->http_only);
-		exec_query_with_try_create_table (priv->db, query, NULL, NULL);
-		sqlite3_free (query);
-	}
-}
-
-static gboolean
-soup_cookie_jar_sqlite_is_persistent (SoupCookieJar *jar)
-{
-	return TRUE;
-}
-
 static void
 soup_cookie_jar_sqlite_class_init (SoupCookieJarSqliteClass *sqlite_class)
 {
-	SoupCookieJarClass *cookie_jar_class =
-		SOUP_COOKIE_JAR_CLASS (sqlite_class);
-	GObjectClass *object_class = G_OBJECT_CLASS (sqlite_class);
-
-	g_type_class_add_private (sqlite_class, sizeof (SoupCookieJarSqlitePrivate));
-
-	cookie_jar_class->is_persistent = soup_cookie_jar_sqlite_is_persistent;
-	cookie_jar_class->changed       = soup_cookie_jar_sqlite_changed;
-
-	object_class->finalize     = soup_cookie_jar_sqlite_finalize;
-	object_class->set_property = soup_cookie_jar_sqlite_set_property;
-	object_class->get_property = soup_cookie_jar_sqlite_get_property;
-
-	/**
-	 * SOUP_COOKIE_JAR_SQLITE_FILENAME:
-	 *
-	 * Alias for the #SoupCookieJarSqlite:filename property. (The
-	 * cookie-storage filename.)
-	 **/
-	g_object_class_install_property (
-		object_class, PROP_FILENAME,
-		g_param_spec_string (SOUP_COOKIE_JAR_SQLITE_FILENAME,
-				     "Filename",
-				     "Cookie-storage filename",
-				     NULL,
-				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
diff --git a/libsoup/soup-cookie-jar-sqlite.h b/libsoup/soup-cookie-jar-sqlite.h
index 97cdf33..adc2786 100644
--- a/libsoup/soup-cookie-jar-sqlite.h
+++ b/libsoup/soup-cookie-jar-sqlite.h
@@ -6,7 +6,7 @@
 #ifndef SOUP_COOKIE_JAR_SQLITE_H
 #define SOUP_COOKIE_JAR_SQLITE_H 1
 
-#include <libsoup/soup-cookie-jar.h>
+#include <libsoup/soup-cookie-jar-db.h>
 
 G_BEGIN_DECLS
 
@@ -18,26 +18,23 @@ G_BEGIN_DECLS
 #define SOUP_COOKIE_JAR_SQLITE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_COOKIE_JAR_SQLITE, SoupCookieJarSqliteClass))
 
 typedef struct {
-	SoupCookieJar parent;
+	SoupCookieJarDB parent;
 
 } SoupCookieJarSqlite;
 
 typedef struct {
-	SoupCookieJarClass parent_class;
+	SoupCookieJarDBClass parent_class;
 
-	/* Padding for future expansion */
-	void (*_libsoup_reserved1) (void);
-	void (*_libsoup_reserved2) (void);
-	void (*_libsoup_reserved3) (void);
-	void (*_libsoup_reserved4) (void);
 } SoupCookieJarSqliteClass;
 
 #define SOUP_COOKIE_JAR_SQLITE_FILENAME  "filename"
 
 SOUP_AVAILABLE_IN_2_26
+SOUP_DEPRECATED_IN_2_42_FOR(soup_cookie_jar_db_get_type)
 GType soup_cookie_jar_sqlite_get_type (void);
 
 SOUP_AVAILABLE_IN_2_26
+SOUP_DEPRECATED_IN_2_42_FOR(soup_cookie_jar_db_new)
 SoupCookieJar *soup_cookie_jar_sqlite_new (const char *filename,
 					   gboolean    read_only);
 
diff --git a/libsoup/soup.h b/libsoup/soup.h
index b1b7472..fd836fe 100644
--- a/libsoup/soup.h
+++ b/libsoup/soup.h
@@ -20,6 +20,7 @@ extern "C" {
 #include <libsoup/soup-content-sniffer.h>
 #include <libsoup/soup-cookie.h>
 #include <libsoup/soup-cookie-jar.h>
+#include <libsoup/soup-cookie-jar-db.h>
 #include <libsoup/soup-cookie-jar-text.h>
 #include <libsoup/soup-date.h>
 #include <libsoup/soup-enum-types.h>



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