[tracker/cursor] Added a TrackerDBCursor API
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/cursor] Added a TrackerDBCursor API
- Date: Wed, 26 Aug 2009 14:14:39 +0000 (UTC)
commit 764db61ba8bde2e548e01c743298285a375571c3
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 26 16:13:36 2009 +0200
Added a TrackerDBCursor API
src/libtracker-db/tracker-db-interface-sqlite.c | 211 +++++++++++++++++++++++
src/libtracker-db/tracker-db-interface.c | 63 +++++++
src/libtracker-db/tracker-db-interface.h | 41 +++++
3 files changed, 315 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 50a5dc7..97e44d4 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -30,14 +30,36 @@
#include "tracker-db-interface-sqlite.h"
+#define TRACKER_TYPE_DB_CURSOR_SQLITE (tracker_db_cursor_sqlite_get_type ())
+#define TRACKER_DB_CURSOR_SQLITE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DB_CURSOR_SQLITE, TrackerDBCursorSqlite))
+#define TRACKER_DB_CURSOR_SQLITE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DB_CURSOR_SQLITE, TrackerDBCursorSqliteClass))
+#define TRACKER_IS_DB_CURSOR_SQLITE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DB_CURSOR_SQLITE))
+#define TRACKER_IS_DB_CURSOR_SQLITE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((o), TRACKER_TYPE_DB_CURSOR_SQLITE))
+#define TRACKER_DB_CURSOR_SQLITE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DB_CURSOR_SQLITE, TrackerDBCursorSqliteClass))
+
+
#define TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_INTERFACE_SQLITE, TrackerDBInterfaceSqlitePrivate))
#define TRACKER_DB_STATEMENT_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_STATEMENT_SQLITE, TrackerDBStatementSqlitePrivate))
+#define TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_CURSOR_SQLITE, TrackerDBCursorSqlitePrivate))
+
typedef struct TrackerDBInterfaceSqlitePrivate TrackerDBInterfaceSqlitePrivate;
typedef struct TrackerDBStatementSqlitePrivate TrackerDBStatementSqlitePrivate;
+typedef struct TrackerDBCursorSqlitePrivate TrackerDBCursorSqlitePrivate;
typedef struct SqliteFunctionData SqliteFunctionData;
typedef struct SqliteAggregateData SqliteAggregateData;
+typedef struct TrackerDBCursorSqlite TrackerDBCursorSqlite;
+typedef struct TrackerDBCursorSqliteClass TrackerDBCursorSqliteClass;
+
+
+struct TrackerDBCursorSqlite {
+ GObject parent_instance;
+};
+
+struct TrackerDBCursorSqliteClass {
+ GObjectClass parent_class;
+};
struct TrackerDBInterfaceSqlitePrivate {
gchar *filename;
@@ -58,6 +80,12 @@ struct TrackerDBStatementSqlitePrivate {
sqlite3_stmt *stmt;
};
+struct TrackerDBCursorSqlitePrivate {
+ TrackerDBInterfaceSqlite *db_interface;
+ sqlite3_stmt *stmt;
+ gboolean finished, owns_stmt;
+};
+
struct SqliteFunctionData {
TrackerDBInterface *interface;
TrackerDBFunc func;
@@ -71,13 +99,19 @@ struct SqliteAggregateData {
};
+GType tracker_db_cursor_sqlite_get_type (void);
+
static void tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface);
static void tracker_db_statement_sqlite_iface_init (TrackerDBStatementIface *iface);
+static void tracker_db_cursor_sqlite_iface_init (TrackerDBCursorIface *iface);
static void tracker_db_interface_sqlite_disconnect (TrackerDBInterface *db_interface);
static void tracker_db_interface_sqlite_reconnect (TrackerDBInterface *db_interface);
static TrackerDBStatementSqlite * tracker_db_statement_sqlite_new (TrackerDBInterfaceSqlite *db_interface,
sqlite3_stmt *sqlite_stmt);
+static TrackerDBCursor * tracker_db_cursor_sqlite_new (TrackerDBInterfaceSqlite *db_interface,
+ sqlite3_stmt *sqlite_stmt,
+ gboolean owns_stmt);
static void tracker_db_statement_sqlite_reset (TrackerDBStatementSqlite *stmt);
enum {
@@ -95,6 +129,10 @@ G_DEFINE_TYPE_WITH_CODE (TrackerDBStatementSqlite, tracker_db_statement_sqlite,
G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DB_STATEMENT,
tracker_db_statement_sqlite_iface_init))
+G_DEFINE_TYPE_WITH_CODE (TrackerDBCursorSqlite, tracker_db_cursor_sqlite, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DB_CURSOR,
+ tracker_db_cursor_sqlite_iface_init))
+
void
tracker_db_interface_sqlite_enable_shared_cache (void)
{
@@ -649,6 +687,7 @@ create_result_set_from_stmt (TrackerDBInterfaceSqlite *interface,
return result_set;
}
+
static TrackerDBResultSet *
tracker_db_interface_sqlite_execute_query (TrackerDBInterface *db_interface,
GError **error,
@@ -687,6 +726,38 @@ tracker_db_interface_sqlite_execute_query (TrackerDBInterface *db_interface,
return result_set;
}
+
+static TrackerDBCursor *
+tracker_db_interface_sqlite_start_cursor (TrackerDBInterface *db_interface,
+ GError **error,
+ const gchar *query)
+{
+ TrackerDBInterfaceSqlitePrivate *priv;
+ TrackerDBCursor *cursor;
+ sqlite3_stmt *stmt;
+ int retval;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+ retval = sqlite3_prepare_v2 (priv->db, query, -1, &stmt, NULL);
+
+ if (retval != SQLITE_OK) {
+ g_set_error (error, TRACKER_DB_INTERFACE_ERROR,
+ TRACKER_DB_QUERY_ERROR, "%s",
+ sqlite3_errmsg (priv->db));
+ return NULL;
+ } else if (stmt == NULL) {
+ g_set_error (error, TRACKER_DB_INTERFACE_ERROR,
+ TRACKER_DB_QUERY_ERROR,
+ "Could not prepare SQL statement:'%s'", query);
+ return NULL;
+ }
+
+ cursor = tracker_db_cursor_sqlite_new (TRACKER_DB_INTERFACE_SQLITE (db_interface), stmt, TRUE);
+
+ return cursor;
+}
+
static void
tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface)
{
@@ -694,6 +765,7 @@ tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface)
iface->execute_query = tracker_db_interface_sqlite_execute_query;
iface->disconnect = tracker_db_interface_sqlite_disconnect;
iface->reconnect = tracker_db_interface_sqlite_reconnect;
+ iface->start_cursor = tracker_db_interface_sqlite_start_cursor;
}
TrackerDBInterface *
@@ -843,6 +915,49 @@ tracker_db_statement_sqlite_new (TrackerDBInterfaceSqlite *db_interface,
}
static void
+tracker_db_cursor_sqlite_finalize (GObject *object)
+{
+ TrackerDBCursorSqlitePrivate *priv;
+
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (object);
+
+ sqlite3_finalize (priv->stmt);
+
+ G_OBJECT_CLASS (tracker_db_cursor_sqlite_parent_class)->finalize (object);
+}
+
+static void
+tracker_db_cursor_sqlite_class_init (TrackerDBCursorSqliteClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = tracker_db_cursor_sqlite_finalize;
+
+ g_type_class_add_private (object_class,
+ sizeof (TrackerDBCursorSqlitePrivate));
+}
+
+static TrackerDBCursor *
+tracker_db_cursor_sqlite_new (TrackerDBInterfaceSqlite *db_interface,
+ sqlite3_stmt *sqlite_stmt,
+ gboolean owns_stmt)
+{
+ TrackerDBCursor *cursor;
+ TrackerDBCursorSqlitePrivate *priv;
+
+ cursor = g_object_new (TRACKER_TYPE_DB_CURSOR_SQLITE, NULL);
+
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (cursor);
+
+ priv->db_interface = db_interface;
+ priv->stmt = sqlite_stmt;
+ priv->finished = FALSE;
+ priv->owns_stmt = owns_stmt;
+
+ return cursor;
+}
+
+static void
tracker_db_statement_sqlite_bind_double (TrackerDBStatement *stmt,
int index,
double value)
@@ -893,6 +1008,74 @@ tracker_db_statement_sqlite_bind_text (TrackerDBStatement *stmt,
}
static void
+tracker_db_cursor_sqlite_set_rewind (TrackerDBCursor *cursor)
+{
+ TrackerDBCursorSqlitePrivate *priv;
+
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (cursor);
+
+ sqlite3_reset (priv->stmt);
+}
+
+static gboolean
+tracker_db_cursor_sqlite_set_iter_next (TrackerDBCursor *cursor)
+{
+ TrackerDBCursorSqlitePrivate *priv;
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (cursor);
+
+ if (!priv->finished) {
+ guint result;
+
+ result = sqlite3_step (priv->stmt);
+ priv->finished = (result != SQLITE_OK || result != SQLITE_ROW);
+ }
+
+ return (!priv->finished);
+}
+
+static guint
+tracker_db_cursor_sqlite_get_n_columns (TrackerDBCursor *cursor)
+{
+ TrackerDBCursorSqlitePrivate *priv;
+
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (cursor);
+
+ return sqlite3_column_count (priv->stmt);
+}
+
+static void
+tracker_db_cursor_sqlite_get_value (TrackerDBCursor *cursor, guint column, GValue *value)
+{
+ TrackerDBCursorSqlitePrivate *priv;
+ gint col_type;
+
+ priv = TRACKER_DB_CURSOR_SQLITE_GET_PRIVATE (cursor);
+
+ col_type = sqlite3_column_type (priv->stmt, column);
+
+ switch (col_type) {
+ case SQLITE_TEXT:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, (gchar *) sqlite3_column_text (priv->stmt, column));
+ break;
+ case SQLITE_INTEGER:
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, sqlite3_column_int (priv->stmt, column));
+ break;
+ case SQLITE_FLOAT:
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, sqlite3_column_double (priv->stmt, column));
+ break;
+ case SQLITE_NULL:
+ /* just ignore NULLs */
+ break;
+ default:
+ g_critical ("Unknown sqlite3 database column type:%d", col_type);
+ }
+
+}
+
+static void
tracker_db_interface_sqlite_disconnect (TrackerDBInterface *db_interface)
{
TrackerDBInterfaceSqlitePrivate *priv;
@@ -924,6 +1107,18 @@ tracker_db_statement_sqlite_execute (TrackerDBStatement *stmt,
return create_result_set_from_stmt (priv->db_interface, priv->stmt, error);
}
+static TrackerDBCursor *
+tracker_db_statement_sqlite_start_cursor (TrackerDBStatement *stmt,
+ GError **error)
+{
+ TrackerDBStatementSqlitePrivate *priv;
+
+ priv = TRACKER_DB_STATEMENT_SQLITE_GET_PRIVATE (stmt);
+
+ return tracker_db_cursor_sqlite_new (priv->db_interface, priv->stmt, FALSE);
+}
+
+
static void
tracker_db_statement_sqlite_iface_init (TrackerDBStatementIface *iface)
{
@@ -932,6 +1127,17 @@ tracker_db_statement_sqlite_iface_init (TrackerDBStatementIface *iface)
iface->bind_int64 = tracker_db_statement_sqlite_bind_int64;
iface->bind_text = tracker_db_statement_sqlite_bind_text;
iface->execute = tracker_db_statement_sqlite_execute;
+ iface->start_cursor = tracker_db_statement_sqlite_start_cursor;
+}
+
+
+static void
+tracker_db_cursor_sqlite_iface_init (TrackerDBCursorIface *iface)
+{
+ iface->set_rewind = tracker_db_cursor_sqlite_set_rewind;
+ iface->set_iter_next = tracker_db_cursor_sqlite_set_iter_next;
+ iface->get_n_columns = tracker_db_cursor_sqlite_get_n_columns;
+ iface->get_value = tracker_db_cursor_sqlite_get_value;
}
static void
@@ -940,6 +1146,11 @@ tracker_db_statement_sqlite_init (TrackerDBStatementSqlite *stmt)
}
static void
+tracker_db_cursor_sqlite_init (TrackerDBCursorSqlite *cursor)
+{
+}
+
+static void
tracker_db_statement_sqlite_reset (TrackerDBStatementSqlite *stmt)
{
TrackerDBStatementSqlitePrivate *priv;
diff --git a/src/libtracker-db/tracker-db-interface.c b/src/libtracker-db/tracker-db-interface.c
index c7123b2..5f0e022 100644
--- a/src/libtracker-db/tracker-db-interface.c
+++ b/src/libtracker-db/tracker-db-interface.c
@@ -95,6 +95,25 @@ tracker_db_statement_get_type (void)
return type;
}
+GType
+tracker_db_cursor_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ type = g_type_register_static_simple (G_TYPE_INTERFACE,
+ "TrackerDBCursor",
+ sizeof (TrackerDBCursorIface),
+ NULL,
+ 0, NULL, 0);
+
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+
/* Boxed type for blobs */
static gpointer
blob_copy (gpointer boxed)
@@ -442,6 +461,50 @@ tracker_db_statement_execute (TrackerDBStatement *stmt,
return ensure_result_set_state (result_set);
}
+TrackerDBCursor *
+tracker_db_statement_start_cursor (TrackerDBStatement *stmt,
+ GError **error)
+{
+ g_return_val_if_fail (TRACKER_IS_DB_STATEMENT (stmt), NULL);
+
+ return TRACKER_DB_STATEMENT_GET_IFACE (stmt)->start_cursor (stmt, error);
+}
+
+/* TrackerDBCursor API */
+
+void
+tracker_cursor_set_rewind (TrackerDBCursor *cursor)
+{
+ g_return_if_fail (TRACKER_IS_DB_CURSOR (cursor));
+
+ TRACKER_DB_CURSOR_GET_IFACE (cursor)->set_rewind (cursor);
+}
+
+gboolean
+tracker_cursor_set_iter_next (TrackerDBCursor *cursor)
+{
+ g_return_val_if_fail (TRACKER_IS_DB_CURSOR (cursor), FALSE);
+
+ return TRACKER_DB_CURSOR_GET_IFACE (cursor)->set_iter_next (cursor);
+}
+
+guint
+tracker_db_cursor_get_n_columns (TrackerDBCursor *cursor)
+{
+ g_return_val_if_fail (TRACKER_IS_DB_CURSOR (cursor), 0);
+
+ return TRACKER_DB_CURSOR_GET_IFACE (cursor)->get_n_columns (cursor);
+}
+
+void
+tracker_db_cursor_get_value (TrackerDBCursor *cursor, guint column, GValue *value)
+{
+ g_return_if_fail (TRACKER_IS_DB_CURSOR (cursor));
+
+ TRACKER_DB_CURSOR_GET_IFACE (cursor)->get_value (cursor, column, value);
+}
+
+
/* TrackerDBResultSet semiprivate API */
TrackerDBResultSet *
_tracker_db_result_set_new (guint columns)
diff --git a/src/libtracker-db/tracker-db-interface.h b/src/libtracker-db/tracker-db-interface.h
index 3d2cde4..1a1f672 100644
--- a/src/libtracker-db/tracker-db-interface.h
+++ b/src/libtracker-db/tracker-db-interface.h
@@ -35,6 +35,11 @@ G_BEGIN_DECLS
#define TRACKER_IS_DB_STATEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_DB_STATEMENT))
#define TRACKER_DB_STATEMENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TRACKER_TYPE_DB_STATEMENT, TrackerDBStatementIface))
+#define TRACKER_TYPE_DB_CURSOR (tracker_db_cursor_get_type ())
+#define TRACKER_DB_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_DB_CURSOR, TrackerDBCursor))
+#define TRACKER_IS_DB_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_DB_CURSOR))
+#define TRACKER_DB_CURSOR_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TRACKER_TYPE_DB_CURSOR, TrackerDBCursorIface))
+
#define TRACKER_TYPE_DB_RESULT_SET (tracker_db_result_set_get_type ())
#define TRACKER_DB_RESULT_SET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DB_RESULT_SET, TrackerDbResultSet))
#define TRACKER_DB_RESULT_SET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DB_RESULT_SET, TrackerDbResultSetClass))
@@ -57,6 +62,8 @@ typedef struct TrackerDBStatement TrackerDBStatement;
typedef struct TrackerDBStatementIface TrackerDBStatementIface;
typedef struct TrackerDBResultSet TrackerDBResultSet;
typedef struct TrackerDBResultSetClass TrackerDBResultSetClass;
+typedef struct TrackerDBCursor TrackerDBCursor;
+typedef struct TrackerDBCursorIface TrackerDBCursorIface;
struct TrackerDBInterfaceIface {
GTypeInterface iface;
@@ -66,6 +73,9 @@ struct TrackerDBInterfaceIface {
TrackerDBResultSet * (* execute_query) (TrackerDBInterface *interface,
GError **error,
const gchar *query);
+ TrackerDBCursor * (* start_cursor) (TrackerDBInterface *interface,
+ GError **error,
+ const gchar *query);
void (* disconnect) (TrackerDBInterface *interface);
void (* reconnect) (TrackerDBInterface *interface);
@@ -88,6 +98,8 @@ struct TrackerDBStatementIface {
void (* bind_int64) (TrackerDBStatement *stmt,
int index,
gint64 value);
+ TrackerDBCursor * (* start_cursor) (TrackerDBStatement *stmt,
+ GError **error);
};
struct TrackerDBResultSet {
@@ -103,6 +115,7 @@ GQuark tracker_db_interface_error_quark (void);
GType tracker_db_interface_get_type (void);
GType tracker_db_statement_get_type (void);
+GType tracker_db_cursor_get_type (void);
GType tracker_db_result_set_get_type (void);
GType tracker_db_blob_get_type (void);
@@ -120,6 +133,11 @@ TrackerDBResultSet * tracker_db_interface_execute_query (TrackerDBInterface *
const gchar *query,
...) G_GNUC_PRINTF (3, 4);
+TrackerDBCursor * tracker_db_interface_start_cursor (TrackerDBInterface *interface,
+ GError **error,
+ const gchar *query,
+ ...) G_GNUC_PRINTF (3, 4);
+
gboolean tracker_db_interface_start_transaction (TrackerDBInterface *interface);
gboolean tracker_db_interface_end_transaction (TrackerDBInterface *interface);
void tracker_db_interface_disconnect (TrackerDBInterface *interface);
@@ -140,6 +158,9 @@ void tracker_db_statement_bind_text (TrackerDBStatement *stmt,
TrackerDBResultSet * tracker_db_statement_execute (TrackerDBStatement *stmt,
GError **error);
+TrackerDBCursor * tracker_db_statement_start_cursor (TrackerDBStatement *stmt,
+ GError **error);
+
/* Semi private TrackerDBResultSet functions */
TrackerDBResultSet * _tracker_db_result_set_new (guint cols);
void _tracker_db_result_set_append (TrackerDBResultSet *result_set);
@@ -159,6 +180,26 @@ guint tracker_db_result_set_get_n_columns (TrackerDBResultSet *result_set);
guint tracker_db_result_set_get_n_rows (TrackerDBResultSet *result_set);
+struct TrackerDBCursorIface {
+ GTypeInterface iface;
+
+ void (*set_rewind) (TrackerDBCursor *cursor);
+ gboolean (*set_iter_next) (TrackerDBCursor *cursor);
+ guint (*get_n_columns) (TrackerDBCursor *cursor);
+ void (*get_value) (TrackerDBCursor *cursor,
+ guint column,
+ GValue *value);
+};
+
+/* Functions to deal with a cursor */
+void tracker_cursor_set_rewind (TrackerDBCursor *cursor);
+gboolean tracker_cursor_set_iter_next (TrackerDBCursor *cursor);
+guint tracker_db_cursor_get_n_columns (TrackerDBCursor *cursor);
+void tracker_db_cursor_get_value (TrackerDBCursor *cursor,
+ guint column,
+ GValue *value);
+
+
G_END_DECLS
#endif /* __TRACKER_DB_INTERFACE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]