[tracker/binary-log-2: 6/35] libtracker-db: Improve the journal API
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/binary-log-2: 6/35] libtracker-db: Improve the journal API
- Date: Tue, 12 Jan 2010 14:48:39 +0000 (UTC)
commit be45d40696743b94566db4cd930ef0431171dda7
Author: Martyn Russell <martyn lanedo com>
Date: Mon Jan 4 14:33:59 2010 +0000
libtracker-db: Improve the journal API
Added return values in some cases, and make it clearer that there is
an API to iterate the journal and an API to write to it.
Don't use global namespace for #defines for local use
Move local functions above public functions
libtracker-db: Improve db journal reader GErrors
Use an enum not hardcoded values for journal data formats
src/libtracker-db/tracker-db-journal.c | 666 +++++++++++++++++++++-----------
src/libtracker-db/tracker-db-journal.h | 52 ++-
src/libtracker-db/tracker-db-manager.c | 4 +-
3 files changed, 478 insertions(+), 244 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-journal.c b/src/libtracker-db/tracker-db-journal.c
index b0510b6..30d5f5c 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -29,12 +29,33 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <errno.h>
+
+#include <glib/gstdio.h>
#include <libtracker-common/tracker-crc32.h>
#include "tracker-db-journal.h"
+#define JOURNAL_FILENAME "tracker-store.journal"
+#define MIN_BLOCK_SIZE 1024
+
+/*
+ * data_format:
+ * #... 0000 0000 (total size is 4 bytes)
+ * ||`- resource insert (all other bits must be 0 if 1)
+ * |`-- object type (1 = id, 0 = cstring)
+ * `--- operation type (0 = insert, 1 = delete)
+ */
+
+typedef enum {
+ DATA_FORMAT_RESOURCE_INSERT = 1 << 0,
+ DATA_FORMAT_OBJECT_ID = 1 << 1,
+ DATA_FORMAT_OPERATION_DELETE = 1 << 2
+} DataFormat;
+
static struct {
+ gchar *filename;
GMappedFile *file;
const gchar *current;
const gchar *end;
@@ -47,12 +68,12 @@ static struct {
guint32 p_id;
guint32 o_id;
const gchar *object;
-} journal_reader;
+} reader;
static struct {
- gchar *filename;
+ gchar *journal_filename;
FILE *journal;
- gsize current_size;
+ gsize cur_size;
guint cur_block_len;
guint cur_block_alloc;
gchar *cur_block;
@@ -60,86 +81,108 @@ static struct {
guint cur_pos;
} writer;
-#define TRACKER_DB_JOURNAL_LOG_FILENAME "tracker-store.journal"
-#define MIN_BLOCK_SIZE 1024
+static guint32
+read_uint32 (const gchar *data)
+{
+ return data[0] << 24 |
+ data[1] << 16 |
+ data[2] << 8 |
+ data[3];
+}
-gsize
-tracker_db_journal_get_size (void)
+static gint
+nearest_pow (gint num)
{
- return current_size;
+ gint n = 1;
+ while (n < num)
+ n <<= 1;
+ return n;
}
-const gchar *
-tracker_db_journal_filename (void)
+static void
+cur_block_maybe_expand (guint len)
{
- if (!writer.filename) {
- writer.filename = g_build_filename (g_get_user_data_dir (),
- "tracker",
- "data",
- TRACKER_DB_JOURNAL_LOG_FILENAME,
- NULL);
- }
+ guint want_alloc = writer.cur_block_len + len;
- return (const gchar *) filename;
+ if (want_alloc > writer.cur_block_alloc) {
+ want_alloc = nearest_pow (want_alloc);
+ want_alloc = MAX (want_alloc, MIN_BLOCK_SIZE);
+ writer.cur_block = g_realloc (writer.cur_block, want_alloc);
+ writer.cur_block_alloc = want_alloc;
+ }
}
static void
-kill_cur_block (void)
+cur_block_kill (void)
{
writer.cur_block_len = 0;
writer.cur_pos = 0;
writer.cur_entry_amount = 0;
writer.cur_block_alloc = 0;
+
g_free (writer.cur_block);
writer.cur_block = NULL;
}
-static gint
-nearest_pow (gint num)
+static void
+cur_setnum (gchar *dest,
+ guint *pos,
+ guint32 val)
{
- gint n = 1;
- while (n < num)
- n <<= 1;
- return n;
+ memset (dest + (*pos)++, val >> 24 & 0xff, 1);
+ memset (dest + (*pos)++, val >> 16 & 0xff, 1);
+ memset (dest + (*pos)++, val >> 8 & 0xff, 1);
+ memset (dest + (*pos)++, val >> 0 & 0xff, 1);
}
static void
-cur_block_maybe_expand (guint len)
+cur_setstr (gchar *dest,
+ guint *pos,
+ const gchar *str,
+ gsize len)
{
- guint want_alloc = writer.cur_block_len + len;
+ memcpy (dest + *pos, str, len);
+ (*pos) += len;
+ memset (dest + (*pos)++, 0 & 0xff, 1);
+}
- if (want_alloc > writer.cur_block_alloc) {
- want_alloc = nearest_pow (want_alloc);
- want_alloc = MAX (want_alloc, MIN_BLOCK_SIZE);
- writer.cur_block = g_realloc (writer.cur_block, want_alloc);
- writer.cur_block_alloc = want_alloc;
- }
+GQuark
+tracker_db_journal_error_quark (void)
+{
+ return g_quark_from_static_string (TRACKER_DB_JOURNAL_ERROR_DOMAIN);
}
-void
-tracker_db_journal_open (const gchar *filen)
+gboolean
+tracker_db_journal_init (const gchar *filename)
{
struct stat st;
+ g_return_val_if_fail (writer.journal == NULL, FALSE);
+
writer.cur_block_len = 0;
writer.cur_pos = 0;
writer.cur_entry_amount = 0;
writer.cur_block_alloc = 0;
writer.cur_block = NULL;
- if (!filen) {
- tracker_db_journal_filename ();
+ /* Used mostly for testing */
+ if (G_UNLIKELY (filename)) {
+ writer.journal_filename = g_strdup (filename);
} else {
- writer.filename = g_strdup (filen);
+ writer.journal_filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ JOURNAL_FILENAME,
+ NULL);
}
- writer.journal = fopen (writer.filename, "a");
+ writer.journal = g_fopen (writer.journal_filename, "a");
- if (stat (writer.filename, &st) == 0) {
- writer.current_size = (gsize) st.st_size;
+ if (g_stat (writer.journal_filename, &st) == 0) {
+ writer.cur_size = (gsize) st.st_size;
}
- if (writer.current_size == 0) {
+ if (writer.cur_size == 0) {
g_assert (writer.cur_block_len == 0);
g_assert (writer.cur_block_alloc == 0);
g_assert (writer.cur_block == NULL);
@@ -158,163 +201,226 @@ tracker_db_journal_open (const gchar *filen)
write (fileno (writer.journal), writer.cur_block, 8);
- writer.current_size += 8;
+ writer.cur_size += 8;
+
+ cur_block_kill ();
+ }
+
+ return TRUE;
+}
- kill_cur_block ();
+gboolean
+tracker_db_journal_shutdown (void)
+{
+ if (journal == NULL) {
+ return TRUE;
}
+
+ fclose (journal);
+ journal = NULL;
+
+ g_free (journal_filename);
+ journal_filename = NULL;
+
+ return TRUE;
}
-void
+gsize
+tracker_db_journal_get_size (void)
+{
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ return cur_size;
+}
+
+const gchar *
+tracker_db_journal_get_filename (void)
+{
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ return (const gchar*) journal_filename;
+}
+
+gboolean
tracker_db_journal_start_transaction (void)
{
- guint size = sizeof (guint32) * 3;
+ guint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+ size = sizeof (guint32) * 3;
cur_block_maybe_expand (size);
- /* Leave space for size, amount and crc
- * Check and keep in sync the offset variable at
+ /* Leave space for size, amount and crc
+ * Check and keep in sync the offset variable at
* tracker_db_journal_commit_transaction too */
memset (writer.cur_block, 0, size);
writer.cur_pos = writer.cur_block_len = size;
writer.cur_entry_amount = 0;
-}
-
-static void
-cur_setnum (gchar *dest,
- guint *pos,
- guint32 val)
-{
- memset (dest + (*pos)++, val >> 24 & 0xff, 1);
- memset (dest + (*pos)++, val >> 16 & 0xff, 1);
- memset (dest + (*pos)++, val >> 8 & 0xff, 1);
- memset (dest + (*pos)++, val >> 0 & 0xff, 1);
-}
-static void
-cur_setstr (gchar *dest,
- guint *pos,
- const gchar *str,
- gsize len)
-{
- memcpy (dest + *pos, str, len);
- (*pos) += len;
- memset (dest + (*pos)++, 0 & 0xff, 1);
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_delete_statement (guint32 s_id,
guint32 p_id,
const gchar *object)
{
- gint o_len = strlen (object);
- gchar data_format = 0x04;
- gint size = (sizeof (guint32) * 3) + o_len + 1;
+ gint o_len;
+ DataFormat df;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (object);
+ df = DATA_FORMAT_OPERATION_DELETE;
+
+ size = (sizeof (guint32) * 3) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (writer.cur_block, &writer.cur_pos, data_format);
+ cur_setnum (writer.cur_block, &writer.cur_pos, df);
cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
cur_setstr (writer.cur_block, &writer.cur_pos, object, o_len);
writer.cur_entry_amount++;
writer.cur_block_len += size;
-}
+ return TRUE;
+}
-void
+gboolean
tracker_db_journal_append_delete_statement_id (guint32 s_id,
guint32 p_id,
guint32 o_id)
{
- gchar data_format = 0x06;
- gint size = sizeof (guint32) * 4;
+ DataFormat df;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ df = DATA_FORMAT_OPERATION_DELETE | DATA_FORMAT_OBJECT_ID;
+ size = sizeof (guint32) * 4;
cur_block_maybe_expand (size);
- cur_setnum (writer.cur_block, &writer.cur_pos, data_format);
+ cur_setnum (writer.cur_block, &writer.cur_pos, df);
cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
cur_setnum (writer.cur_block, &writer.cur_pos, o_id);
writer.cur_entry_amount++;
writer.cur_block_len += size;
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_insert_statement (guint32 s_id,
guint32 p_id,
const gchar *object)
{
- gint o_len = strlen (object);
- gchar data_format = 0x00;
- gint size = (sizeof (guint32) * 3) + o_len + 1;
+ gint o_len;
+ DataFormat df;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (object);
+ df = 0x00;
+ size = (sizeof (guint32) * 3) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (writer.cur_block, &writer.cur_pos, data_format);
+ cur_setnum (writer.cur_block, &writer.cur_pos, df);
cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
cur_setstr (writer.cur_block, &writer.cur_pos, object, o_len);
writer.cur_entry_amount++;
writer.cur_block_len += size;
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_insert_statement_id (guint32 s_id,
guint32 p_id,
guint32 o_id)
{
- gchar data_format = 0x02;
- gint size = sizeof (guint32) * 4;
+ DataFormat df;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ df = DATA_FORMAT_OBJECT_ID;
+ size = sizeof (guint32) * 4;
cur_block_maybe_expand (size);
- cur_setnum (writer.cur_block, &writer.cur_pos, data_format);
+ cur_setnum (writer.cur_block, &writer.cur_pos, df);
cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
cur_setnum (writer.cur_block, &writer.cur_pos, o_id);
writer.cur_entry_amount++;
writer.cur_block_len += size;
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_resource (guint32 s_id,
const gchar *uri)
{
- gint o_len = strlen (uri);
- gchar data_format = 0x01;
- gint size = (sizeof (guint32) * 2) + o_len + 1;
+ gint o_len;
+ DataFormat df;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (uri);
+ df = DATA_FORMAT_RESOURCE_INSERT;
+ size = (sizeof (guint32) * 2) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (writer.cur_block, &writer.cur_pos, data_format);
+ cur_setnum (writer.cur_block, &writer.cur_pos, df);
cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
cur_setstr (writer.cur_block, &writer.cur_pos, uri, o_len);
writer.cur_entry_amount++;
writer.cur_block_len += size;
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_rollback_transaction (void)
{
- kill_cur_block ();
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ cur_block_kill ();
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_commit_transaction (void)
{
guint32 crc;
- guint begin_pos = 0;
- guint size = sizeof (guint32);
- guint offset = sizeof(guint32) * 3;
+ guint begin_pos;
+ guint size;
+ guint offset;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
- g_assert (writer.journal);
+ begin_pos = 0;
+ size = sizeof (guint32);
+ offset = sizeof (guint32) * 3;
cur_block_maybe_expand (size);
@@ -330,253 +436,367 @@ tracker_db_journal_commit_transaction (void)
crc = tracker_crc32 (writer.cur_block + offset, writer.cur_block_len - offset);
cur_setnum (writer.cur_block, &begin_pos, crc);
- write (fileno (writer.journal), writer.cur_block, writer.cur_block_len);
+ /* FIXME: What if we don't write all of len, needs improving. */
+ if (write (fileno (writer.journal), writer.cur_block, writer.cur_block_len) == -1) {
+ g_critical ("Could not write to journal, %s", g_strerror (errno));
+ return FALSE;
+ }
- writer.current_size += writer.cur_block_len;
+ writer.cur_size += writer.cur_block_len;
+ cur_block_kill ();
- kill_cur_block ();
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_fsync (void)
{
- g_assert (writer.journal);
+ g_return_val_if_fail (writer.journal != NULL, FALSE);
- fsync (fileno (writer.journal));
+ return fsync (fileno (writer.journal)) == 0;
}
-void
-tracker_db_journal_close (void)
+/*
+ * Reader API
+ */
+gboolean
+tracker_db_journal_reader_init (const gchar *filename)
{
- g_assert (writer.journal);
-
- fclose (writer.journal);
- writer.journal = NULL;
+ GError *error = NULL;
+ gchar *filename_used;
- g_free (writer.filename);
- writer.filename = NULL;
-}
+ g_return_val_if_fail (reader.file == NULL, FALSE);
-void
-tracker_db_journal_reader_init (const gchar *filen)
-{
- if (!filen) {
- tracker_db_journal_filename ();
+ /* Used mostly for testing */
+ if (G_UNLIKELY (filename)) {
+ filename_used = g_strdup (filename);
} else {
- filename = g_strdup (filen);
+ filename_used = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ JOURNAL_FILENAME,
+ NULL);
+ }
+
+ reader.type = TRACKER_DB_JOURNAL_START;
+ reader.filename = filename_used;
+ reader.file = g_mapped_file_new (reader.filename, FALSE, &error);
+
+ if (error) {
+ g_warning ("Could not create TrackerDBJournalEntry for file '%s', %s",
+ reader.filename,
+ error->message ? error->message : "no error given");
+ g_error_free (error);
+ tracker_db_journal_reader_shutdown ();
+
+ return FALSE;
}
- /* TODO error handling */
- journal_reader.file = g_mapped_file_new (filename, FALSE, NULL);
- journal_reader.current = g_mapped_file_get_contents (journal_reader.file);
- journal_reader.end = journal_reader.current + g_mapped_file_get_length (journal_reader.file);
+ reader.current = g_mapped_file_get_contents (reader.file);
+ reader.end = reader.current + g_mapped_file_get_length (reader.file);
/* verify journal file header */
- g_assert (journal_reader.end - journal_reader.current >= 8);
- g_assert (memcmp (journal_reader.current, "trlog\001", 8) == 0);
- journal_reader.current += 8;
+ g_assert (reader.end - reader.current >= 8);
+
+ g_assert_cmpint (reader.current[0], ==, 't');
+ g_assert_cmpint (reader.current[1], ==, 'r');
+ g_assert_cmpint (reader.current[2], ==, 'l');
+ g_assert_cmpint (reader.current[3], ==, 'o');
+ g_assert_cmpint (reader.current[4], ==, 'g');
+ g_assert_cmpint (reader.current[5], ==, '\0');
+ g_assert_cmpint (reader.current[6], ==, '0');
+ g_assert_cmpint (reader.current[7], ==, '1');
+
+ reader.current += 8;
+
+ return TRUE;
}
-static guint32 read_uint32 (const gchar *data)
+gboolean
+tracker_db_journal_reader_shutdown (void)
{
- return data[0] << 24 |
- data[1] << 16 |
- data[2] << 8 |
- data[3];
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+
+#if GLIB_CHECK_VERSION(2,22,0)
+ g_mapped_file_unref (reader.file);
+#else
+ g_mapped_file_free (reader.file);
+#endif
+
+ reader.file = NULL;
+
+ g_free (reader.filename);
+ reader.filename = NULL;
+
+ reader.current = NULL;
+ reader.end = NULL;
+ reader.entry_begin = NULL;
+ reader.entry_end = NULL;
+ reader.amount_of_triples = 0;
+ reader.type = TRACKER_DB_JOURNAL_START;
+ reader.uri = NULL;
+ reader.s_id = 0;
+ reader.p_id = 0;
+ reader.o_id = 0;
+ reader.object = NULL;
+
+ return TRUE;
+}
+
+TrackerDBJournalEntryType
+tracker_db_journal_reader_get_type (void)
+{
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+
+ return reader.type;
}
gboolean
-tracker_db_journal_next (void)
+tracker_db_journal_reader_next (GError **error)
{
- if (journal_reader.type == TRACKER_DB_JOURNAL_START ||
- journal_reader.type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
- /* expect new transaction or end of file */
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ if (reader.type == TRACKER_DB_JOURNAL_START ||
+ reader.type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
+ /* expect new transaction or end of file */
guint32 entry_size;
guint32 crc32;
+ guint32 read_size;
- if (journal_reader.current >= journal_reader.end) {
- /* end of journal reached */
+ if (reader.current >= reader.end) {
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "End of journal reached");
return FALSE;
}
- if (journal_reader.end - journal_reader.current < sizeof (guint32)) {
- /* damaged journal entry */
+ if (reader.end - reader.current < sizeof (guint32)) {
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, < sizeof(guint32) at start/end of journal");
return FALSE;
}
- journal_reader.entry_begin = journal_reader.current;
- entry_size = read_uint32 (journal_reader.current);
- journal_reader.entry_end = journal_reader.entry_begin + entry_size;
- if (journal_reader.end < journal_reader.entry_end) {
- /* damaged journal entry */
+ reader.entry_begin = reader.current;
+ entry_size = read_uint32 (reader.current);
+ reader.entry_end = reader.entry_begin + entry_size;
+
+ if (reader.end < reader.entry_end) {
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, end < entry end");
return FALSE;
}
- journal_reader.current += 4;
+
+ reader.current += 4;
/* compare with entry_size at end */
- if (entry_size != read_uint32 (journal_reader.entry_end - 4)) {
+ read_size = read_uint32 (reader.entry_end - 4);
+
+ if (entry_size != read_size) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d != %d (size != size read)",
+ entry_size,
+ read_size);
return FALSE;
}
- journal_reader.amount_of_triples = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.amount_of_triples = read_uint32 (reader.current);
+ reader.current += 4;
- crc32 = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ crc32 = read_uint32 (reader.current);
+ reader.current += 4;
/* verify checksum */
- if (crc32 != tracker_crc32 (journal_reader.entry_begin, entry_size)) {
+ if (crc32 != tracker_crc32 (reader.entry_begin, entry_size)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, crc32 failed");
return FALSE;
}
- journal_reader.type = TRACKER_DB_JOURNAL_START_TRANSACTION;
+ reader.type = TRACKER_DB_JOURNAL_START_TRANSACTION;
return TRUE;
- } else if (journal_reader.amount_of_triples == 0) {
+ } else if (reader.amount_of_triples == 0) {
/* end of transaction */
- if (journal_reader.current + 4 != journal_reader.entry_end) {
+ if (reader.current + 4 != reader.entry_end) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %p != %p (end of transaction with 0 triples)",
+ reader.current + 4,
+ reader.entry_end);
return FALSE;
}
- journal_reader.type = TRACKER_DB_JOURNAL_END_TRANSACTION;
+ reader.type = TRACKER_DB_JOURNAL_END_TRANSACTION;
return TRUE;
} else {
- guint32 data_format;
+ DataFormat df;
gsize str_length;
- if (journal_reader.end - journal_reader.current < sizeof (guint32)) {
+ if (reader.end - reader.current < sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d < sizeof(guint32)",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- data_format = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ df = read_uint32 (reader.current);
+ reader.current += 4;
- if (data_format == 1) {
- journal_reader.type = TRACKER_DB_JOURNAL_RESOURCE;
+ if (df == DATA_FORMAT_RESOURCE_INSERT) {
+ reader.type = TRACKER_DB_JOURNAL_RESOURCE;
- if (journal_reader.end - journal_reader.current < sizeof (guint32) + 1) {
+ if (reader.end - reader.current < sizeof (guint32) + 1) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d < sizeof(guint32) + 1 for resource",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- journal_reader.s_id = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.s_id = read_uint32 (reader.current);
+ reader.current += 4;
- str_length = strnlen (journal_reader.current, journal_reader.end - journal_reader.current);
- if (str_length == journal_reader.end - journal_reader.current) {
+ str_length = strnlen (reader.current, reader.end - reader.current);
+ if (str_length == reader.end - reader.current) {
/* damaged journal entry (no terminating '\0' character) */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, no terminating zero found for resource");
return FALSE;
+
}
- if (!g_utf8_validate (journal_reader.current, -1, NULL)) {
+
+ if (!g_utf8_validate (reader.current, -1, NULL)) {
/* damaged journal entry (invalid UTF-8) */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, invalid UTF-8 for resource");
return FALSE;
}
- journal_reader.uri = journal_reader.current;
- journal_reader.current += str_length + 1;
+
+ reader.uri = reader.current;
+ reader.current += str_length + 1;
} else {
- if (data_format & 4) {
- if (data_format & 2) {
- journal_reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID;
+ if (df & DATA_FORMAT_OPERATION_DELETE) {
+ if (df & DATA_FORMAT_OBJECT_ID) {
+ reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID;
} else {
- journal_reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT;
+ reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT;
}
} else {
- if (data_format & 2) {
- journal_reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID;
+ if (df & DATA_FORMAT_OBJECT_ID) {
+ reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID;
} else {
- journal_reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT;
+ reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT;
}
}
- if (journal_reader.end - journal_reader.current < 2 * sizeof (guint32)) {
+ if (reader.end - reader.current < 2 * sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d < 2 * sizeof(guint32)",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- journal_reader.s_id = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.s_id = read_uint32 (reader.current);
+ reader.current += 4;
- journal_reader.p_id = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.p_id = read_uint32 (reader.current);
+ reader.current += 4;
- if (data_format & 2) {
- if (journal_reader.end - journal_reader.current < sizeof (guint32)) {
+ if (df & DATA_FORMAT_OBJECT_ID) {
+ if (reader.end - reader.current < sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d < sizeof(guint32) for data format 2",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- journal_reader.o_id = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.o_id = read_uint32 (reader.current);
+ reader.current += 4;
} else {
- if (journal_reader.end - journal_reader.current < 1) {
+ if (reader.end - reader.current < 1) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, %d < 1",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- str_length = strnlen (journal_reader.current, journal_reader.end - journal_reader.current);
- if (str_length == journal_reader.end - journal_reader.current) {
+ str_length = strnlen (reader.current, reader.end - reader.current);
+ if (str_length == reader.end - reader.current) {
/* damaged journal entry (no terminating '\0' character) */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, no terminating zero found");
return FALSE;
}
- if (!g_utf8_validate (journal_reader.current, -1, NULL)) {
+
+ if (!g_utf8_validate (reader.current, -1, NULL)) {
/* damaged journal entry (invalid UTF-8) */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0,
+ "Damaged journal entry, invalid UTF-8");
return FALSE;
}
- journal_reader.object = journal_reader.current;
- journal_reader.current += str_length + 1;
+
+ reader.object = reader.current;
+ reader.current += str_length + 1;
}
}
- journal_reader.amount_of_triples--;
+ reader.amount_of_triples--;
return TRUE;
}
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Unknown reason");
+
return FALSE;
}
-TrackerDBJournalEntryType
-tracker_db_journal_get_type (void)
+gboolean
+tracker_db_journal_reader_get_resource (guint32 *id,
+ const gchar **uri)
{
- return journal_reader.type;
-}
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ g_return_val_if_fail (reader.type == TRACKER_DB_JOURNAL_RESOURCE, FALSE);
-void
-tracker_db_journal_get_resource (guint32 *id,
- const gchar **uri)
-{
- g_return_if_fail (journal_reader.type == TRACKER_DB_JOURNAL_RESOURCE);
+ *id = reader.s_id;
+ *uri = reader.uri;
- *id = journal_reader.s_id;
- *uri = journal_reader.uri;
+ return TRUE;
}
-void
-tracker_db_journal_get_statement (guint32 *s_id,
- guint32 *p_id,
- const gchar **object)
+gboolean
+tracker_db_journal_reader_get_statement (guint32 *s_id,
+ guint32 *p_id,
+ const gchar **object)
{
- g_return_if_fail (journal_reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT ||
- journal_reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT);
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ g_return_val_if_fail (reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT ||
+ reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT,
+ FALSE);
+
+ *s_id = reader.s_id;
+ *p_id = reader.p_id;
+ *object = reader.object;
- *s_id = journal_reader.s_id;
- *p_id = journal_reader.p_id;
- *object = journal_reader.object;
+ return TRUE;
}
-void
-tracker_db_journal_get_statement_id (guint32 *s_id,
- guint32 *p_id,
- guint32 *o_id)
+gboolean
+tracker_db_journal_reader_get_statement_id (guint32 *s_id,
+ guint32 *p_id,
+ guint32 *o_id)
{
- g_return_if_fail (journal_reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID ||
- journal_reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID);
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ g_return_val_if_fail (reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID ||
+ reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID,
+ FALSE);
+
+ *s_id = reader.s_id;
+ *p_id = reader.p_id;
+ *o_id = reader.o_id;
- *s_id = journal_reader.s_id;
- *p_id = journal_reader.p_id;
- *o_id = journal_reader.o_id;
+ return TRUE;
}
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index 2ebff17..3034234 100644
--- a/src/libtracker-db/tracker-db-journal.h
+++ b/src/libtracker-db/tracker-db-journal.h
@@ -27,6 +27,9 @@
G_BEGIN_DECLS
+#define TRACKER_DB_JOURNAL_ERROR_DOMAIN "TrackerDBJournal"
+#define TRACKER_DB_JOURNAL_ERROR tracker_db_journal_error_quark()
+
typedef enum {
TRACKER_DB_JOURNAL_START,
TRACKER_DB_JOURNAL_START_TRANSACTION,
@@ -38,42 +41,53 @@ typedef enum {
TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID
} TrackerDBJournalEntryType;
-const gchar* tracker_db_journal_filename (void);
-void tracker_db_journal_open (const gchar *filen);
+GQuark tracker_db_journal_error_quark (void);
+
+/*
+ * Writer API
+ */
+gboolean tracker_db_journal_init (const gchar *filename);
+gboolean tracker_db_journal_shutdown (void);
+
+const gchar* tracker_db_journal_get_filename (void);
+gsize tracker_db_journal_get_size (void);
-void tracker_db_journal_start_transaction (void);
-void tracker_db_journal_append_delete_statement (guint32 s_id,
+gboolean tracker_db_journal_start_transaction (void);
+gboolean tracker_db_journal_append_delete_statement (guint32 s_id,
guint32 p_id,
const gchar *object);
-void tracker_db_journal_append_delete_statement_id (guint32 s_id,
+gboolean tracker_db_journal_append_delete_statement_id (guint32 s_id,
guint32 p_id,
guint32 o_id);
-void tracker_db_journal_append_insert_statement (guint32 s_id,
+gboolean tracker_db_journal_append_insert_statement (guint32 s_id,
guint32 p_id,
const gchar *object);
-void tracker_db_journal_append_insert_statement_id (guint32 s_id,
+gboolean tracker_db_journal_append_insert_statement_id (guint32 s_id,
guint32 p_id,
guint32 o_id);
-void tracker_db_journal_append_resource (guint32 s_id,
+gboolean tracker_db_journal_append_resource (guint32 s_id,
const gchar *uri);
-void tracker_db_journal_rollback_transaction (void);
-void tracker_db_journal_commit_transaction (void);
+gboolean tracker_db_journal_rollback_transaction (void);
+gboolean tracker_db_journal_commit_transaction (void);
-void tracker_db_journal_close (void);
-void tracker_db_journal_fsync (void);
-gsize tracker_db_journal_get_size (void);
+gboolean tracker_db_journal_fsync (void);
-void tracker_db_journal_reader_init (const gchar *filen);
-gboolean tracker_db_journal_next (void);
+/*
+ * Reader API
+ */
+gboolean tracker_db_journal_reader_init (const gchar *filename);
+gboolean tracker_db_journal_reader_shutdown (void);
TrackerDBJournalEntryType
- tracker_db_journal_get_type (void);
-void tracker_db_journal_get_resource (guint32 *id,
+ tracker_db_journal_reader_get_type (void);
+
+gboolean tracker_db_journal_reader_next (GError **error);
+gboolean tracker_db_journal_reader_get_resource (guint32 *id,
const gchar **uri);
-void tracker_db_journal_get_statement (guint32 *s_id,
+gboolean tracker_db_journal_reader_get_statement (guint32 *s_id,
guint32 *p_id,
const gchar **object);
-void tracker_db_journal_get_statement_id (guint32 *s_id,
+gboolean tracker_db_journal_reader_get_statement_id (guint32 *s_id,
guint32 *p_id,
guint32 *o_id);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 95f0955..72bceeb 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -865,8 +865,8 @@ db_manager_remove_all (gboolean rm_backup_and_log, gboolean not_meta)
GFile *file;
gchar *cpath;
- cpath = g_strdup (tracker_db_journal_filename ());
- tracker_db_journal_close ();
+ cpath = g_strdup (tracker_db_journal_get_filename ());
+ tracker_db_journal_shutdown ();
g_message (" Removing journal:'%s'",
cpath);
file = g_file_new_for_path (cpath);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]