[tracker/binary-log-2: 14/47] Create TrackerDBJournalEntry for iterating through it
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/binary-log-2: 14/47] Create TrackerDBJournalEntry for iterating through it
- Date: Mon, 11 Jan 2010 16:35:25 +0000 (UTC)
commit a5e06255df46f3eb708a53dc56aacf1a07fc88aa
Author: Martyn Russell <martyn lanedo com>
Date: Mon Jan 4 15:37:06 2010 +0000
Create TrackerDBJournalEntry for iterating through it
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).
Journal whitespace fixes
libtracker-db: Fixed Philip's comments:
- Revert writer variables to static vars (don't alloc)
- Don't use g_slice for TrackerDBJournalEntry, use g_new instead.
- the g_assert(memcpy()...) for the journal header was removed because
it failed, this has been re-added using: g_assert_cmpint for each
character and it works.
libtracker-db: Improve db journal reader GErrors
libtracker-db: Use global structure for journal reader and use s/entry/reader/ for API
src/libtracker-data/tracker-data-manager.c | 2 +-
src/libtracker-db/tracker-db-journal.c | 507 +++++++++++++++++++---------
src/libtracker-db/tracker-db-journal.h | 42 ++-
src/libtracker-db/tracker-db-manager.c | 4 +-
tests/libtracker-db/Makefile.am | 2 +
tests/libtracker-db/tracker-db-journal.c | 174 ++++++++--
6 files changed, 521 insertions(+), 210 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 7cead83..0810d16 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -830,7 +830,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 c7c666d..e4ff221 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -29,6 +29,9 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <errno.h>
+
+#include <glib/gstdio.h>
#include <libtracker-common/tracker-crc32.h>
@@ -38,6 +41,7 @@
#define MIN_BLOCK_SIZE 1024
static struct {
+ gchar *filename;
GMappedFile *file;
const gchar *current;
const gchar *end;
@@ -50,18 +54,19 @@ static struct {
guint32 p_code;
guint32 o_code;
const gchar *object;
-} journal_reader;
+} reader;
-static gchar *filename = NULL;
+static gchar *journal_filename = NULL;
static FILE *journal = NULL;
-static gsize current_size = 0;
+
+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;
-static guint32
+static guint32
read_uint32 (const gchar *data)
{
return data[0] << 24 |
@@ -99,13 +104,14 @@ cur_block_kill (void)
cur_pos = 0;
cur_entry_amount = 0;
cur_block_alloc = 0;
+
g_free (cur_block);
cur_block = NULL;
}
static void
-cur_setnum (gchar *dest,
- guint *pos,
+cur_setnum (gchar *dest,
+ guint *pos,
guint32 val)
{
memset (dest + (*pos)++, val >> 24 & 0xff, 1);
@@ -115,9 +121,9 @@ cur_setnum (gchar *dest,
}
static void
-cur_setstr (gchar *dest,
- guint *pos,
- const gchar *str,
+cur_setstr (gchar *dest,
+ guint *pos,
+ const gchar *str,
gsize len)
{
memcpy (dest + *pos, str, len);
@@ -125,19 +131,37 @@ 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 = fopen (filename, "a");
+ g_return_val_if_fail (journal == NULL, FALSE);
- if (stat (filename, &st) == 0) {
- current_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 (current_size == 0) {
+ journal = g_fopen (journal_filename, "a");
+
+ if (g_stat (journal_filename, &st) == 0) {
+ cur_size = (gsize) st.st_size;
+ }
+
+ if (cur_size == 0) {
g_assert (cur_block_len == 0);
g_assert (cur_block_alloc == 0);
g_assert (cur_block == NULL);
@@ -156,7 +180,7 @@ tracker_db_journal_init (void)
write (fileno (journal), cur_block, 8);
- current_size += 8;
+ cur_size += 8;
cur_block_kill ();
}
@@ -167,13 +191,15 @@ 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) {
+ fclose (journal);
+ journal = NULL;
+ }
- g_free (filename);
- filename = NULL;
+ g_free (journal_filename);
+ journal_filename = NULL;
return TRUE;
}
@@ -181,48 +207,55 @@ tracker_db_journal_shutdown (void)
gsize
tracker_db_journal_get_size (void)
{
- return current_size;
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ return 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
+ /* 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);
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);
@@ -233,15 +266,22 @@ tracker_db_journal_append_delete_statement (guint32 s_code,
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);
@@ -252,16 +292,24 @@ tracker_db_journal_append_delete_statement_code (guint32 s_code,
cur_entry_amount++;
cur_block_len += size;
+
+ return TRUE;
}
-void
-tracker_db_journal_append_insert_statement (guint32 s_code,
- guint32 p_code,
+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);
@@ -272,15 +320,22 @@ tracker_db_journal_append_insert_statement (guint32 s_code,
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);
@@ -291,15 +346,23 @@ tracker_db_journal_append_insert_statement_code (guint32 s_code,
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);
@@ -309,23 +372,33 @@ tracker_db_journal_append_resource (guint32 s_code,
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_assert (journal);
+ g_return_val_if_fail (journal != NULL, FALSE);
+
+ begin_pos = 0;
+ size = sizeof (guint32);
+ offset = sizeof (guint32) * 3;
cur_block_maybe_expand (size);
@@ -341,244 +414,368 @@ tracker_db_journal_commit_transaction (void)
crc = tracker_crc32 (cur_block + offset, cur_block_len - offset);
cur_setnum (cur_block, &begin_pos, crc);
- write (fileno (journal), cur_block, cur_block_len);
-
- current_size += cur_block_len;
+ /* FIXME: What if we don't write all of len, needs improving. */
+ if (write (fileno (journal), cur_block, cur_block_len) == -1) {
+ g_critical ("Could not write to journal, %s", g_strerror (errno));
+ return FALSE;
+ }
+ cur_size += 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)) == 0;
}
/*
* Reader API
*/
-
gboolean
-tracker_db_journal_entry_init (void)
+tracker_db_journal_reader_init (const gchar *filename)
{
- const gchar *journal_filename;
+ GError *error = NULL;
+ gchar *filename_used;
+
+ g_return_val_if_fail (reader.file == NULL, FALSE);
+
+ /* Used mostly for testing */
+ if (G_UNLIKELY (filename)) {
+ filename_used = g_strdup (filename);
+ } else {
+ 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);
- journal_filename = tracker_db_journal_filename ();
+ 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 (journal_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;
+}
+
+gboolean
+tracker_db_journal_reader_shutdown (void)
+{
+ 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_code = 0;
+ reader.p_code = 0;
+ reader.o_code = 0;
+ reader.object = NULL;
return TRUE;
}
TrackerDBJournalEntryType
-tracker_db_journal_entry_get_type (void)
+tracker_db_journal_reader_get_type (void)
{
- return journal_reader.type;
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+
+ return reader.type;
}
gboolean
-tracker_db_journal_entry_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) {
+ 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;
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;
+ data_format = read_uint32 (reader.current);
+ reader.current += 4;
if (data_format == 1) {
- journal_reader.type = TRACKER_DB_JOURNAL_RESOURCE;
+ 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_code = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.s_code = 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_CODE;
+ reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT_CODE;
} 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_CODE;
+ reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT_CODE;
} 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_code = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.s_code = read_uint32 (reader.current);
+ reader.current += 4;
- journal_reader.p_code = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.p_code = read_uint32 (reader.current);
+ reader.current += 4;
if (data_format & 2) {
- 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) for data format 2",
+ (gint) (reader.end - reader.current));
return FALSE;
}
- journal_reader.o_code = read_uint32 (journal_reader.current);
- journal_reader.current += 4;
+ reader.o_code = 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;
}
gboolean
-tracker_db_journal_entry_get_resource (guint32 *code,
- const gchar **uri)
+tracker_db_journal_reader_get_resource (guint32 *code,
+ const gchar **uri)
{
- g_return_val_if_fail (journal_reader.type == TRACKER_DB_JOURNAL_RESOURCE, FALSE);
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ g_return_val_if_fail (reader.type == TRACKER_DB_JOURNAL_RESOURCE, FALSE);
- *code = journal_reader.s_code;
- *uri = journal_reader.uri;
+ *code = reader.s_code;
+ *uri = reader.uri;
return TRUE;
}
gboolean
-tracker_db_journal_entry_get_statement (guint32 *s_code,
- guint32 *p_code,
- const gchar **object)
+tracker_db_journal_reader_get_statement (guint32 *s_code,
+ guint32 *p_code,
+ const gchar **object)
{
- g_return_val_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_code = journal_reader.s_code;
- *p_code = journal_reader.p_code;
- *object = journal_reader.object;
+ *s_code = reader.s_code;
+ *p_code = reader.p_code;
+ *object = reader.object;
return TRUE;
}
gboolean
-tracker_db_journal_entry_get_statement_code (guint32 *s_code,
- guint32 *p_code,
- guint32 *o_code)
+tracker_db_journal_reader_get_statement_code (guint32 *s_code,
+ guint32 *p_code,
+ guint32 *o_code)
{
- g_return_val_if_fail (journal_reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT_CODE ||
- journal_reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT_CODE,
+ g_return_val_if_fail (reader.file != NULL, FALSE);
+ g_return_val_if_fail (reader.type == TRACKER_DB_JOURNAL_INSERT_STATEMENT_CODE ||
+ reader.type == TRACKER_DB_JOURNAL_DELETE_STATEMENT_CODE,
FALSE);
- *s_code = journal_reader.s_code;
- *p_code = journal_reader.p_code;
- *o_code = journal_reader.o_code;
+ *s_code = reader.s_code;
+ *p_code = reader.p_code;
+ *o_code = reader.o_code;
return TRUE;
}
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index 2bf68da..8894ebe 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,52 +41,53 @@ 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
*/
-
-gboolean tracker_db_journal_entry_init (void);
+gboolean tracker_db_journal_reader_init (const gchar *filename);
+gboolean tracker_db_journal_reader_shutdown (void);
TrackerDBJournalEntryType
- tracker_db_journal_entry_get_type (void);
+ tracker_db_journal_reader_get_type (void);
-gboolean tracker_db_journal_entry_next (void);
-gboolean tracker_db_journal_entry_get_resource (guint32 *code,
+gboolean tracker_db_journal_reader_next (GError **error);
+gboolean tracker_db_journal_reader_get_resource (guint32 *code,
const gchar **uri);
-gboolean tracker_db_journal_entry_get_statement (guint32 *s_code,
+gboolean tracker_db_journal_reader_get_statement (guint32 *s_code,
guint32 *p_code,
const gchar **object);
-gboolean tracker_db_journal_entry_get_statement_code (guint32 *s_code,
+gboolean tracker_db_journal_reader_get_statement_code (guint32 *s_code,
guint32 *p_code,
guint32 *o_code);
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..4db0916 100644
--- a/tests/libtracker-db/tracker-db-journal.c
+++ b/tests/libtracker-db/tracker-db-journal.c
@@ -17,44 +17,148 @@
* 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;
+ 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 */
+ result = tracker_db_journal_reader_init (path);
+ g_assert_cmpint (result, ==, TRUE);
+
+ type = tracker_db_journal_reader_get_type ();
+ g_assert_cmpint (type, ==, TRACKER_DB_JOURNAL_START);
+
+ result = tracker_db_journal_reader_next (&error);
+ g_assert_no_error (error);
+ g_assert_cmpint (result, ==, TRUE);
+
+ /* FIXME: unfinished */
+
+ result = tracker_db_journal_reader_shutdown ();
+ g_assert_cmpint (result, ==, TRUE);
+
+ g_free (path);
}
int
@@ -66,8 +170,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]