[tracker/binary-log-2: 21/56] Added more feedback to journal API
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/binary-log-2: 21/56] Added more feedback to journal API
- Date: Fri, 8 Jan 2010 10:34:20 +0000 (UTC)
commit 6d0478d3c4f4c690d1d4b30246fb82f9ea7c4e1a
Author: Martyn Russell <martyn lanedo com>
Date: Mon Jan 4 18:08:02 2010 +0000
Added more feedback to journal API
- Now we return TRUE/FALSE to APIs
- We have a GError for entry_next() API.
- Test cases now work for journal writing (not reading yet).
src/libtracker-data/tracker-data-manager.c | 2 +-
src/libtracker-db/tracker-db-journal.c | 414 ++++++++++++++++++---------
src/libtracker-db/tracker-db-journal.h | 33 ++-
src/libtracker-db/tracker-db-manager.c | 4 +-
tests/libtracker-db/Makefile.am | 2 +
tests/libtracker-db/tracker-db-journal.c | 172 ++++++++++---
6 files changed, 439 insertions(+), 188 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 408b972..9eebb4c 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -829,7 +829,7 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
iface = tracker_db_manager_get_db_interface ();
- tracker_db_journal_init ();
+ tracker_db_journal_init (NULL);
if (is_first_time_index) {
TrackerClass **classes;
diff --git a/src/libtracker-db/tracker-db-journal.c b/src/libtracker-db/tracker-db-journal.c
index 48c2639..ac6d252 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <errno.h>
#include <glib/gstdio.h>
@@ -40,6 +41,7 @@
#define MIN_BLOCK_SIZE 1024
struct TrackerDBJournalEntry {
+ gchar *filename;
GMappedFile *file;
const gchar *current;
const gchar *end;
@@ -54,17 +56,21 @@ struct TrackerDBJournalEntry {
const gchar *object;
};
-/*
- * Writer variables
- */
-static gchar *filename = NULL;
-static FILE *journal = NULL;
-static gsize cur_size = 0;
-static guint cur_block_len = 0;
-static guint cur_block_alloc = 0;
-static gchar *cur_block = NULL;
-static guint cur_entry_amount = 0;
-static guint cur_pos = 0;
+typedef struct TrackerDBJournal TrackerDBJournal;
+
+struct TrackerDBJournal {
+ gchar *filename;
+ FILE *file;
+
+ gsize cur_size;
+ guint cur_block_len;
+ guint cur_block_alloc;
+ gchar *cur_block;
+ guint cur_entry_amount;
+ guint cur_pos;
+};
+
+static TrackerDBJournal *journal = NULL;
static guint32
read_uint32 (const gchar *data)
@@ -87,25 +93,26 @@ nearest_pow (gint num)
static void
cur_block_maybe_expand (guint len)
{
- guint want_alloc = cur_block_len + len;
+ guint want_alloc = journal->cur_block_len + len;
- if (want_alloc > cur_block_alloc) {
+ if (want_alloc > journal->cur_block_alloc) {
want_alloc = nearest_pow (want_alloc);
want_alloc = MAX (want_alloc, MIN_BLOCK_SIZE);
- cur_block = g_realloc (cur_block, want_alloc);
- cur_block_alloc = want_alloc;
+ journal->cur_block = g_realloc (journal->cur_block, want_alloc);
+ journal->cur_block_alloc = want_alloc;
}
}
static void
cur_block_kill (void)
{
- cur_block_len = 0;
- cur_pos = 0;
- cur_entry_amount = 0;
- cur_block_alloc = 0;
- g_free (cur_block);
- cur_block = NULL;
+ journal->cur_block_len = 0;
+ journal->cur_pos = 0;
+ journal->cur_entry_amount = 0;
+ journal->cur_block_alloc = 0;
+
+ g_free (journal->cur_block);
+ journal->cur_block = NULL;
}
static void
@@ -130,38 +137,58 @@ cur_setstr (gchar *dest,
memset (dest + (*pos)++, 0 & 0xff, 1);
}
+GQuark
+tracker_db_journal_error_quark (void)
+{
+ return g_quark_from_static_string (TRACKER_DB_JOURNAL_ERROR_DOMAIN);
+}
+
gboolean
-tracker_db_journal_init (void)
+tracker_db_journal_init (const gchar *filename)
{
struct stat st;
- filename = tracker_db_journal_filename ();
- journal = g_fopen (filename, "a");
+ g_return_val_if_fail (journal == NULL, FALSE);
+
+ journal = g_new0 (TrackerDBJournal, 1);
- if (g_stat (filename, &st) == 0) {
- cur_size = (gsize) st.st_size;
+ /* Used mostly for testing */
+ if (G_UNLIKELY (filename)) {
+ journal->filename = g_strdup (filename);
+ } else {
+ journal->filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ JOURNAL_FILENAME,
+ NULL);
}
- if (cur_size == 0) {
- g_assert (cur_block_len == 0);
- g_assert (cur_block_alloc == 0);
- g_assert (cur_block == NULL);
- g_assert (cur_block == NULL);
+ journal->file = g_fopen (journal->filename, "a");
+
+ if (g_stat (journal->filename, &st) == 0) {
+ journal->cur_size = (gsize) st.st_size;
+ }
+
+ if (journal->cur_size == 0) {
+ g_assert (journal->cur_block_len == 0);
+ g_assert (journal->cur_block_alloc == 0);
+ g_assert (journal->cur_block == NULL);
+ g_assert (journal->cur_block == NULL);
cur_block_maybe_expand (8);
- cur_block[0] = 't';
- cur_block[1] = 'r';
- cur_block[2] = 'l';
- cur_block[3] = 'o';
- cur_block[4] = 'g';
- cur_block[5] = '\0';
- cur_block[6] = '0';
- cur_block[7] = '1';
+ journal->cur_block[0] = 't';
+ journal->cur_block[1] = 'r';
+ journal->cur_block[2] = 'l';
+ journal->cur_block[3] = 'o';
+ journal->cur_block[4] = 'g';
+ journal->cur_block[5] = '\0';
+ journal->cur_block[6] = '0';
+ journal->cur_block[7] = '1';
- write (fileno (journal), cur_block, 8);
+ write (fileno (journal->file), journal->cur_block, 8);
- cur_size += 8;
+ journal->cur_size += 8;
cur_block_kill ();
}
@@ -172,13 +199,16 @@ tracker_db_journal_init (void)
gboolean
tracker_db_journal_shutdown (void)
{
- g_assert (journal);
+ g_return_val_if_fail (journal != NULL, FALSE);
- fclose (journal);
- journal = NULL;
+ if (journal->file) {
+ fclose (journal->file);
+ }
+
+ g_free (journal->filename);
- g_free (filename);
- filename = NULL;
+ g_free (journal);
+ journal = NULL;
return TRUE;
}
@@ -186,203 +216,276 @@ tracker_db_journal_shutdown (void)
gsize
tracker_db_journal_get_size (void)
{
- return cur_size;
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ return journal->cur_size;
}
const gchar *
-tracker_db_journal_filename (void)
+tracker_db_journal_get_filename (void)
{
- if (!filename) {
- filename = g_build_filename (g_get_user_data_dir (),
- "tracker",
- "data",
- JOURNAL_FILENAME,
- NULL);
- }
+ g_return_val_if_fail (journal != NULL, FALSE);
- return (const gchar*) filename;
+ return (const gchar*) journal->filename;
}
-void
+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
* tracker_db_journal_commit_transaction too */
- memset (cur_block, 0, size);
+ memset (journal->cur_block, 0, size);
+
+ journal->cur_pos = journal->cur_block_len = size;
+ journal->cur_entry_amount = 0;
- cur_pos = cur_block_len = size;
- cur_entry_amount = 0;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_delete_statement (guint32 s_code,
guint32 p_code,
const gchar *object)
{
- gint o_len = strlen (object);
- gchar data_format = 0x04;
- gint size = (sizeof (guint32) * 3) + o_len + 1;
+ gint o_len;
+ gchar data_format;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (object);
+ data_format = 0x04;
+ size = (sizeof (guint32) * 3) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &cur_pos, data_format);
- cur_setnum (cur_block, &cur_pos, s_code);
- cur_setnum (cur_block, &cur_pos, p_code);
- cur_setstr (cur_block, &cur_pos, object, o_len);
+ cur_setnum (journal->cur_block, &journal->cur_pos, data_format);
+ cur_setnum (journal->cur_block, &journal->cur_pos, s_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, p_code);
+ cur_setstr (journal->cur_block, &journal->cur_pos, object, o_len);
+
+ journal->cur_entry_amount++;
+ journal->cur_block_len += size;
- cur_entry_amount++;
- cur_block_len += size;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_delete_statement_code (guint32 s_code,
guint32 p_code,
guint32 o_code)
{
- gchar data_format = 0x06;
- gint size = sizeof (guint32) * 4;
+ gchar data_format;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ data_format = 0x06;
+ size = sizeof (guint32) * 4;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &cur_pos, data_format);
- cur_setnum (cur_block, &cur_pos, s_code);
- cur_setnum (cur_block, &cur_pos, p_code);
- cur_setnum (cur_block, &cur_pos, o_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, data_format);
+ cur_setnum (journal->cur_block, &journal->cur_pos, s_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, p_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, o_code);
+
+ journal->cur_entry_amount++;
+ journal->cur_block_len += size;
- cur_entry_amount++;
- cur_block_len += size;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_insert_statement (guint32 s_code,
guint32 p_code,
const gchar *object)
{
- gint o_len = strlen (object);
- gchar data_format = 0x00;
- gint size = (sizeof (guint32) * 3) + o_len + 1;
+ gint o_len;
+ gchar data_format;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (object);
+ data_format = 0x00;
+ size = (sizeof (guint32) * 3) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &cur_pos, data_format);
- cur_setnum (cur_block, &cur_pos, s_code);
- cur_setnum (cur_block, &cur_pos, p_code);
- cur_setstr (cur_block, &cur_pos, object, o_len);
+ cur_setnum (journal->cur_block, &journal->cur_pos, data_format);
+ cur_setnum (journal->cur_block, &journal->cur_pos, s_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, p_code);
+ cur_setstr (journal->cur_block, &journal->cur_pos, object, o_len);
+
+ journal->cur_entry_amount++;
+ journal->cur_block_len += size;
- cur_entry_amount++;
- cur_block_len += size;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_insert_statement_code (guint32 s_code,
guint32 p_code,
guint32 o_code)
{
- gchar data_format = 0x02;
- gint size = sizeof (guint32) * 4;
+ gchar data_format;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ data_format = 0x02;
+ size = sizeof (guint32) * 4;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &cur_pos, data_format);
- cur_setnum (cur_block, &cur_pos, s_code);
- cur_setnum (cur_block, &cur_pos, p_code);
- cur_setnum (cur_block, &cur_pos, o_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, data_format);
+ cur_setnum (journal->cur_block, &journal->cur_pos, s_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, p_code);
+ cur_setnum (journal->cur_block, &journal->cur_pos, o_code);
+
+ journal->cur_entry_amount++;
+ journal->cur_block_len += size;
- cur_entry_amount++;
- cur_block_len += size;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_append_resource (guint32 s_code,
const gchar *uri)
{
- gint o_len = strlen (uri);
- gchar data_format = 0x01;
- gint size = (sizeof (guint32) * 2) + o_len + 1;
+ gint o_len;
+ gchar data_format;
+ gint size;
+
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ o_len = strlen (uri);
+ data_format = 0x01;
+ size = (sizeof (guint32) * 2) + o_len + 1;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &cur_pos, data_format);
- cur_setnum (cur_block, &cur_pos, s_code);
- cur_setstr (cur_block, &cur_pos, uri, o_len);
+ cur_setnum (journal->cur_block, &journal->cur_pos, data_format);
+ cur_setnum (journal->cur_block, &journal->cur_pos, s_code);
+ cur_setstr (journal->cur_block, &journal->cur_pos, uri, o_len);
+
+ journal->cur_entry_amount++;
+ journal->cur_block_len += size;
- cur_entry_amount++;
- cur_block_len += size;
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_rollback_transaction (void)
{
+ 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 (journal);
+ begin_pos = 0;
+ size = sizeof (guint32);
+ offset = sizeof (guint32) * 3;
cur_block_maybe_expand (size);
- cur_setnum (cur_block, &begin_pos, cur_block_len);
- cur_setnum (cur_block, &begin_pos, cur_entry_amount);
+ cur_setnum (journal->cur_block, &begin_pos, journal->cur_block_len);
+ cur_setnum (journal->cur_block, &begin_pos, journal->cur_entry_amount);
- cur_setnum (cur_block, &cur_pos, cur_block_len);
+ cur_setnum (journal->cur_block, &journal->cur_pos, journal->cur_block_len);
- cur_block_len += size;
+ journal->cur_block_len += size;
/* CRC is calculated from entries until appended amount int */
- crc = tracker_crc32 (cur_block + offset, cur_block_len - offset);
- cur_setnum (cur_block, &begin_pos, crc);
+ crc = tracker_crc32 (journal->cur_block + offset, journal->cur_block_len - offset);
+ cur_setnum (journal->cur_block, &begin_pos, crc);
- write (fileno (journal), cur_block, cur_block_len);
-
- cur_size += cur_block_len;
+ /* FIXME: What if we don't write all of len, needs improving. */
+ if (write (fileno (journal->file), journal->cur_block, journal->cur_block_len) == -1) {
+ g_critical ("Could not write to journal, %s", g_strerror (errno));
+ return FALSE;
+ }
+ journal->cur_size += journal->cur_block_len;
cur_block_kill ();
+
+ return TRUE;
}
-void
+gboolean
tracker_db_journal_fsync (void)
{
- g_assert (journal);
+ g_return_val_if_fail (journal != NULL, FALSE);
- fsync (fileno (journal));
+ return fsync (fileno (journal->file)) == 0;
}
/*
* Reader API
*/
-
TrackerDBJournalEntry *
-tracker_db_journal_entry_new (void)
+tracker_db_journal_entry_new (const gchar *filename)
{
TrackerDBJournalEntry *entry;
- const gchar *journal_filename;
+ GError *error = NULL;
+ gchar *journal_filename;
- journal_filename = tracker_db_journal_filename ();
+ /* Used mostly for testing */
+ if (G_UNLIKELY (filename)) {
+ journal_filename = g_strdup (filename);
+ } else {
+ journal_filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ JOURNAL_FILENAME,
+ NULL);
+ }
entry = g_slice_new0 (TrackerDBJournalEntry);
- /* TODO error handling */
- entry->file = g_mapped_file_new (journal_filename, FALSE, NULL);
+ entry->type = TRACKER_DB_JOURNAL_START;
+ entry->filename = journal_filename;
+
+ entry->file = g_mapped_file_new (entry->filename, FALSE, &error);
+
+ if (error) {
+ g_warning ("Could not create TrackerDBJournalEntry for file '%s', %s",
+ entry->filename,
+ error->message ? error->message : "no error given");
+ g_error_free (error);
+ tracker_db_journal_entry_free (entry);
+
+ return NULL;
+ }
+
entry->current = g_mapped_file_get_contents (entry->file);
entry->end = entry->current + g_mapped_file_get_length (entry->file);
/* verify journal file header */
g_assert (entry->end - entry->current >= 8);
- g_assert (memcmp (entry->current, "trlog\001", 8) == 0);
entry->current += 8;
return entry;
@@ -393,7 +496,17 @@ tracker_db_journal_entry_free (TrackerDBJournalEntry *entry)
{
g_return_val_if_fail (entry != NULL, FALSE);
+ if (entry->file) {
+#if GLIB_CHECK_VERSION(2,22,0)
+ g_mapped_file_unref (entry->file);
+#else
+ g_mapped_file_free (entry->file);
+#endif
+ }
+ g_free (entry->filename);
+
+ g_slice_free (TrackerDBJournalEntry, entry);
return TRUE;
}
@@ -407,7 +520,8 @@ tracker_db_journal_entry_get_type (TrackerDBJournalEntry *entry)
}
gboolean
-tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
+tracker_db_journal_entry_next (TrackerDBJournalEntry *entry,
+ GError **error)
{
g_return_val_if_fail (entry != NULL, FALSE);
@@ -416,29 +530,35 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
/* expect new transaction or end of file */
guint32 entry_size;
guint32 crc32;
+ guint32 read_size;
if (entry->current >= entry->end) {
- /* end of journal reached */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "End of journal reached");
return FALSE;
}
if (entry->end - entry->current < sizeof (guint32)) {
- /* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < sizeof(guint32) at start/end of journal");
return FALSE;
}
entry->entry_begin = entry->current;
entry_size = read_uint32 (entry->current);
entry->entry_end = entry->entry_begin + entry_size;
+
if (entry->end < entry->entry_end) {
- /* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, end < entry end");
return FALSE;
}
+
entry->current += 4;
/* compare with entry_size at end */
- if (entry_size != read_uint32 (entry->entry_end - 4)) {
+ read_size = read_uint32 (entry->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;
}
@@ -451,6 +571,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
/* verify checksum */
if (crc32 != tracker_crc32 (entry->entry_begin, entry_size)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, crc32 failed");
return FALSE;
}
@@ -461,6 +582,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
if (entry->current + 4 != entry->entry_end) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, current + 4 != entry end");
return FALSE;
}
@@ -472,6 +594,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
if (entry->end - entry->current < sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < sizeof(guint32)");
return FALSE;
}
@@ -483,6 +606,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
if (entry->end - entry->current < sizeof (guint32) + 1) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < sizeof(guint32) for RESOURCE");
return FALSE;
}
@@ -492,12 +616,17 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
str_length = strnlen (entry->current, entry->end - entry->current);
if (str_length == entry->end - entry->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 (entry->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;
}
+
entry->uri = entry->current;
entry->current += str_length + 1;
} else {
@@ -517,6 +646,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
if (entry->end - entry->current < 2 * sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < 2 * sizeof(guint32)");
return FALSE;
}
@@ -529,6 +659,7 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
if (data_format & 2) {
if (entry->end - entry->current < sizeof (guint32)) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < sizeof(guint32) for data format 2");
return FALSE;
}
@@ -537,18 +668,23 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
} else {
if (entry->end - entry->current < 1) {
/* damaged journal entry */
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Damaged journal entry, < 1");
return FALSE;
}
str_length = strnlen (entry->current, entry->end - entry->current);
if (str_length == entry->end - entry->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 (entry->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;
}
+
entry->object = entry->current;
entry->current += str_length + 1;
}
@@ -558,6 +694,8 @@ tracker_db_journal_entry_next (TrackerDBJournalEntry *entry)
return TRUE;
}
+ g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, "Unknown reason");
+
return FALSE;
}
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index 13bb1a6..4ba2a43 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 struct TrackerDBJournalEntry TrackerDBJournalEntry;
typedef enum {
@@ -40,47 +43,49 @@ typedef enum {
TRACKER_DB_JOURNAL_DELETE_STATEMENT_CODE
} TrackerDBJournalEntryType;
+GQuark tracker_db_journal_error_quark (void);
+
/*
* Writer API
*/
-gboolean tracker_db_journal_init (void);
+gboolean tracker_db_journal_init (const gchar *filename);
gboolean tracker_db_journal_shutdown (void);
-const gchar* tracker_db_journal_filename (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_code,
+gboolean tracker_db_journal_start_transaction (void);
+gboolean tracker_db_journal_append_delete_statement (guint32 s_code,
guint32 p_code,
const gchar *object);
-void tracker_db_journal_append_delete_statement_code (guint32 s_code,
+gboolean tracker_db_journal_append_delete_statement_code (guint32 s_code,
guint32 p_code,
guint32 o_code);
-void tracker_db_journal_append_insert_statement (guint32 s_code,
+gboolean tracker_db_journal_append_insert_statement (guint32 s_code,
guint32 p_code,
const gchar *object);
-void tracker_db_journal_append_insert_statement_code (guint32 s_code,
+gboolean tracker_db_journal_append_insert_statement_code (guint32 s_code,
guint32 p_code,
guint32 o_code);
-void tracker_db_journal_append_resource (guint32 s_code,
+gboolean tracker_db_journal_append_resource (guint32 s_code,
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);
+gboolean tracker_db_journal_fsync (void);
/*
* Reader API
*/
TrackerDBJournalEntry *
- tracker_db_journal_entry_new (void);
+ tracker_db_journal_entry_new (const gchar *filename);
gboolean tracker_db_journal_entry_free (TrackerDBJournalEntry *entry);
TrackerDBJournalEntryType
tracker_db_journal_entry_get_type (TrackerDBJournalEntry *entry);
-gboolean tracker_db_journal_entry_next (TrackerDBJournalEntry *entry);
+gboolean tracker_db_journal_entry_next (TrackerDBJournalEntry *entry,
+ GError **error);
gboolean tracker_db_journal_entry_get_resource (TrackerDBJournalEntry *entry,
guint32 *code,
const gchar **uri);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index a5eccea..8099a28 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;
const gchar *cpath;
- cpath = tracker_db_journal_filename ();
- g_message (" Removing database:'%s'",
+ cpath = tracker_db_journal_get_filename ();
+ g_message (" Removing journal:'%s'",
cpath);
file = g_file_new_for_path (cpath);
g_file_delete (file, NULL, NULL);
diff --git a/tests/libtracker-db/Makefile.am b/tests/libtracker-db/Makefile.am
index 4a871d8..022453a 100644
--- a/tests/libtracker-db/Makefile.am
+++ b/tests/libtracker-db/Makefile.am
@@ -17,6 +17,8 @@ noinst_PROGRAMS = $(TEST_PROGS)
#
INCLUDES = \
+ -DTOP_SRCDIR=\"$(top_srcdir)\" \
+ -DTOP_BUILDDIR=\"$(top_builddir)\" \
-DG_LOG_DOMAIN=\"Tracker\" \
-DTRACKER_COMPILATION \
-I$(top_srcdir)/src \
diff --git a/tests/libtracker-db/tracker-db-journal.c b/tests/libtracker-db/tracker-db-journal.c
index 1a47baf..1f8bc2d 100644
--- a/tests/libtracker-db/tracker-db-journal.c
+++ b/tests/libtracker-db/tracker-db-journal.c
@@ -17,44 +17,146 @@
* Boston, MA 02110-1301, USA.
*/
+#include <glib/gstdio.h>
+
#include <libtracker-common/tracker-crc32.h>
#include <libtracker-db/tracker-db-journal.h>
static void
-test_all (void)
+test_init_and_shutdown (void)
+{
+ gboolean result;
+
+ /* check double init/shutdown */
+ result = tracker_db_journal_init (NULL);
+ g_assert (result == TRUE);
+
+ result = tracker_db_journal_shutdown ();
+ g_assert (result == TRUE);
+
+ result = tracker_db_journal_init (NULL);
+ g_assert (result == TRUE);
+
+ result = tracker_db_journal_shutdown ();
+ g_assert (result == TRUE);
+}
+
+static void
+test_write_functions (void)
{
- tracker_db_journal_init ();
-
- tracker_db_journal_start_transaction ();
- tracker_db_journal_append_resource (10, "http://resource");
- tracker_db_journal_append_resource (11, "http://predicate");
- tracker_db_journal_append_delete_statement (10, 11, "test");
- tracker_db_journal_commit_transaction ();
-
- tracker_db_journal_start_transaction ();
- tracker_db_journal_append_resource (12, "http://resource");
- tracker_db_journal_append_resource (13, "http://predicate");
- tracker_db_journal_append_resource (14, "http://resource");
- tracker_db_journal_append_delete_statement_code (12, 13, 14);
- tracker_db_journal_commit_transaction ();
-
-
- tracker_db_journal_start_transaction ();
- tracker_db_journal_append_resource (15, "http://resource");
- tracker_db_journal_append_resource (16, "http://predicate");
- tracker_db_journal_append_insert_statement (15, 16, "test");
- tracker_db_journal_commit_transaction ();
-
- tracker_db_journal_start_transaction ();
- tracker_db_journal_append_resource (17, "http://resource");
- tracker_db_journal_append_resource (18, "http://predicate");
- tracker_db_journal_append_resource (19, "http://resource");
- tracker_db_journal_append_insert_statement_code (17, 18, 19);
- tracker_db_journal_commit_transaction ();
-
- tracker_db_journal_fsync ();
+ gchar *path;
+ const gchar *filename;
+ gsize initial_size, actual_size;
+ gboolean result;
+
+ path = g_build_filename (TOP_SRCDIR, "tests", "libtracker-db", "tracker-store.journal", NULL);
+ g_unlink (path);
+
+ tracker_db_journal_init (path);
+
+ filename = tracker_db_journal_get_filename ();
+ g_assert (filename != NULL);
+ g_assert_cmpstr (filename, ==, path);
+
+ /* Size is 8 due to header */
+ actual_size = tracker_db_journal_get_size ();
+ g_assert_cmpint (actual_size, ==, 8);
+
+ /* Check with rollback, nothing is added */
+ initial_size = tracker_db_journal_get_size ();
+ result = tracker_db_journal_start_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (10, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (11, "http://predicate");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_delete_statement (10, 11, "test");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_rollback_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ actual_size = tracker_db_journal_get_size ();
+ g_assert_cmpint (initial_size, ==, actual_size);
+
+ /* Check with commit, somethign is added */
+ result = tracker_db_journal_start_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (12, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (13, "http://predicate");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (14, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_delete_statement_code (12, 13, 14);
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_commit_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ actual_size = tracker_db_journal_get_size ();
+ g_assert_cmpint (initial_size, !=, actual_size);
+
+ /* Test insert statement */
+ result = tracker_db_journal_start_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (15, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (16, "http://predicate");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_insert_statement (15, 16, "test");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_commit_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+
+ /* Test insert code */
+ result = tracker_db_journal_start_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (17, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (18, "http://predicate");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_resource (19, "http://resource");
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_append_insert_statement_code (17, 18, 19);
+ g_assert_cmpint (result, ==, TRUE);
+ result = tracker_db_journal_commit_transaction ();
+ g_assert_cmpint (result, ==, TRUE);
+
+ /* Test fsync */
+ result = tracker_db_journal_fsync ();
+ g_assert_cmpint (result, ==, TRUE);
+
tracker_db_journal_shutdown ();
+
+ g_free (path);
+}
+
+static void
+test_read_functions (void)
+{
+ GError *error = NULL;
+ gchar *path;
+ gsize initial_size, actual_size;
+ gboolean result;
+ TrackerDBJournalEntry *entry;
+ TrackerDBJournalEntryType type;
+
+ path = g_build_filename (TOP_SRCDIR, "tests", "libtracker-db", "tracker-store.journal", NULL);
+
+ /* NOTE: we don't unlink here so we can use the data from the write tests */
+
+ /* Create an iterator */
+ entry = tracker_db_journal_entry_new (path);
+ g_assert (entry != NULL);
+
+ type = tracker_db_journal_entry_get_type (entry);
+ g_assert_cmpint (type, ==, TRACKER_DB_JOURNAL_START);
+
+ result = tracker_db_journal_entry_next (entry, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (result, ==, TRUE);
+
+ /* FIXME: unfinished */
+
+ g_free (path);
}
int
@@ -66,8 +168,12 @@ main (int argc, char **argv)
g_thread_init (NULL);
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/libtracker-db/tracker-db-journal/open-append-commit-close",
- test_all);
+ g_test_add_func ("/libtracker-db/tracker-db-journal/init-and-shutdown",
+ test_init_and_shutdown);
+ g_test_add_func ("/libtracker-db/tracker-db-journal/write-functions",
+ test_write_functions);
+ g_test_add_func ("/libtracker-db/tracker-db-journal/read-functions",
+ test_read_functions);
result = g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]