ermetadb_local.c File Reference

#include <glib.h>
#include <string.h>
#include <liberutils/er_error.h>
#include "ermetadb_log.h"
#include "ermetadb.h"
#include "ermetadb_error.h"
#include "ermetadb_private.h"
#include "sqlite3_wrapper.h"
Include dependency graph for ermetadb_local.c:

Go to the source code of this file.

Defines

#define LOCAL_MAX_COLUMNS   12
#define CHECK_LOCAL

Functions

static const char *const * get_local_column_names (const char *table)
static gint64 get_local_id (erMetadb thiz, const char *filename)
int ermetadb_local_remove_annotation (erMetadb thiz, const gint64 annotation_id)
 Remove selected annotation.
static int set_annotation_impl (erMetadb thiz, const gint64 annotation_id, const gchar *annotation_type, const gchar *layer, const gint64 file_position, const gchar *title, const gchar *start_anchor, const gchar *end_anchor, const gchar *data_blob, const guint data_len)
static gint64 find_or_create_filename (erMetadb thiz, const char *filename)
int ermetadb_local_create_annotation (erMetadb thiz, const gchar *filename, gint64 *annotation_id, const gchar *annotation_type, const gchar *layer, const gint64 file_position, const gchar *title, const gchar *start_anchor, const gchar *end_anchor, const gchar *data_blob, const guint data_len)
 Set selected annotation fields for a file or folder.
int ermetadb_local_set_annotation (erMetadb thiz, const gint64 annotation_id, const gchar *annotation_type, const gchar *layer, const gint64 file_position, const gchar *title, const gchar *start_anchor, const gchar *end_anchor, const gchar *data_blob, const guint data_len)
 Set selected annotation fields for a file or folder.
int ermetadb_local_get_annotations (erMetadb thiz, const gint64 *annotation_id_list, long annotation_id_num, metadata_table **values_tbl)
 Get details of the specified list of annotations.
int ermetadb_local_select_annotations (erMetadb thiz, const gchar *filename, const gchar *annotation_type, const gchar *layer, const gint64 file_position_min, const gint64 file_position_max, metadata_table **values_tbl)
 Get basic annotation fields within the specified range for a file or folder Basic annotation fields are the following columns from table annotations: annotation_id, annotation_type, layer, file_position, start_anchor, end_anchor Results are sorted on (1) file_position and (2) annotation_type and (3) layer Application must select from result the annotations it is really interested in, then call ermetadb_local_get_annotations() for the details of these. This avoids retrieving blob data for annotations that are not used by the application. Note that the library can select on file_position only, which is a pretty course selection, while the application can select on start_anchor and end_anchor, which is much more accurate.
static int local_delete_all_annotations (erMetadb thiz, gint64 file_id)
static GString * get_keys (const metadata_table *names_tbl)
int ermetadb_local_remove_application_data (erMetadb thiz, const gchar *filename, const metadata_table *names_tbl)
 Remove selected application_data fields for a file or folder.
int ermetadb_local_set_application_data (erMetadb thiz, const gchar *filename, const metadata_table *values_tbl)
 Set selected application_data fields for a file or folder.
static metadata_tablerotate_keyval_table (const metadata_table *table)
int ermetadb_local_get_application_data (erMetadb thiz, const gchar *filename, const metadata_table *names_tbl, metadata_table **values_tbl)
 Get selected application_data fields for a file or folder.
static int local_delete_all_application_data (erMetadb thiz, gint64 file_id)
static int local_delete_entry (erMetadb thiz, gint64 file_id)
int local_delete_all_data_for_file (erMetadb thiz, const char *filename)
int local_delete_all_data_for_id (erMetadb thiz, gint64 file_id)

Variables

struct {
   const char *   table_name
   const char *   column_names [LOCAL_MAX_COLUMNS+1]
local_database_tables []

Define Documentation

#define CHECK_LOCAL
#define LOCAL_MAX_COLUMNS   12

Copyright (C) 2008 iRex Technologies B.V. All rights reserved.

Definition at line 47 of file ermetadb_local.c.


Function Documentation

int ermetadb_local_create_annotation ( erMetadb  thiz,
const gchar *  filename,
gint64 *  annotation_id,
const gchar *  annotation_type,
const gchar *  layer,
const gint64  file_position,
const gchar *  title,
const gchar *  start_anchor,
const gchar *  end_anchor,
const gchar *  data_blob,
const guint  data_len 
)

Set selected annotation fields for a file or folder.

---------------------------------------------------------------------------

Name : ermetadb_local_create_annotation

Parameters:
[in] thiz - erMetadb object
[in] filename - file or folder to which this annotation belongs
[out] annotation_id - unique id of this annotation
[in] annotation_type - specifies what type of annotation this is
[in] layer - specifies what layer this annotation belongs to or empty string when no layer is applicable
[in] file_position - page number (1, 2, ..) for page-oriented docs like pdf, relative position (0 .. 100,000 for 0 .. 100%) for reflowable content
[in] title - specifies a title for this annotation or NULL when no title is applicable
[in] start_anchor - exact begin position of this annotation in the document or NULL when not relevant
[in] end_anchor - exact end position of this annotation in the document or NULL when not relevant
[in] data_blob - data belonging to this annotation as a blob or NULL when no data Note: caller must release this data after the function returns.
[in] data_len - number of bytes in data_blob or zero when no data
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 282 of file ermetadb_local.c.

References CHECK_LOCAL, ER_FAIL, ER_OK, ERMETADB_FAIL, ERRORPRINTF, find_or_create_filename(), LOGPRINTF, set_annotation_impl(), sql3_begin_transaction(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by save_page_data().

00293 {
00294     LOGPRINTF("file [%s]", filename);
00295 
00296     CHECK_LOCAL
00297     g_assert(filename && filename[0]);
00298     g_assert(annotation_id);
00299 
00300     gint64 anno_id = -1;
00301 
00302     int ret = sql3_begin_transaction(thiz);
00303     if (ret != ER_OK) return ret;
00304 
00305     gint64 file_id = find_or_create_filename(thiz, filename);
00306     if (file_id < 0) {
00307         ret = ER_FAIL;
00308         goto out;
00309     }
00310 
00311     // create an empty annotation
00312     // build query
00313     GString *sql = g_string_new("");  // SQL statements
00314     g_string_printf( sql, "INSERT INTO annotations"
00315                           " (file_id, annotation_type, layer, file_position)"
00316                           " VALUES (%lld, 'dummy', 'dummy', 0 )",
00317                      file_id );
00318 
00319     // execute query
00320     int rc = sql3_execute_query(thiz->database, sql->str, NULL, NULL);
00321     if (rc != ER_OK)
00322     {
00323         ERRORPRINTF("cannot create annotation, sql [%s]", sql->str);
00324         ret = ERMETADB_FAIL;
00325     }
00326     else
00327     {
00328         // retrieve the new annotation_id
00329         anno_id = sqlite3_last_insert_rowid(thiz->database);
00330     }
00331     g_string_free(sql, TRUE);
00332 
00333     // set annotation fields
00334     if (ret == ER_OK)
00335     {
00336         ret = set_annotation_impl( thiz,
00337                                    anno_id,
00338                                    annotation_type,
00339                                    layer,
00340                                    file_position,
00341                                    title,
00342                                    start_anchor,
00343                                    end_anchor,
00344                                    data_blob,
00345                                    data_len        );
00346     }
00347 out:
00348     ret = sql3_commit_or_rollback(thiz, ret);
00349 
00350     *annotation_id = anno_id;
00351     return ret;
00352 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_get_annotations ( erMetadb  thiz,
const gint64 *  annotation_id_list,
long  annotation_id_num,
metadata_table **  values_tbl 
)

Get details of the specified list of annotations.

---------------------------------------------------------------------------

Name : ermetadb_local_get_annotations

Parameters:
[in] thiz - erMetadb object
[in] annotation_id_list - unique id's of these annotations
[in] annotation_id_num - number of unique id's in annotation_id_list
[out] values_tbl - metadata_table holding annotation values one row per annotation_id or NULL on error Caller must use metadata_table_free() to release this table.
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 391 of file ermetadb_local.c.

References CHECK_LOCAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ERRORPRINTF, get_local_column_names(), LOGPRINTF, name, sql3_begin_transaction_readonly(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by load_page_data().

00395 {
00396     LOGPRINTF("entry");
00397 
00398     CHECK_LOCAL
00399     g_return_val_if_fail(  annotation_id_list                , ER_INVALID_PARAMETER );
00400     g_return_val_if_fail(  annotation_id_num >= 0            , ER_INVALID_PARAMETER );
00401     g_return_val_if_fail( (values_tbl && *values_tbl == NULL), ER_INVALID_PARAMETER );
00402 
00403     // get known column names
00404     GString *columns = g_string_new("");
00405     const char* const *name;
00406     for ( name = get_local_column_names( "annotations" ) ; *name ; name++ )
00407     {
00408         if ( strcmp(*name, "file_id" ) != 0 )
00409         {
00410             if (columns->len != 0) g_string_append( columns, ", "  );
00411             g_string_append( columns, *name );
00412         }
00413     }
00414 
00415     metadata_table *result = NULL;
00416 
00417     int ret = sql3_begin_transaction_readonly(thiz);
00418     if (ret != ER_OK) goto out;
00419 
00420     // build sql
00421     const gint64 *p_anno = annotation_id_list;
00422     GString *sql = g_string_new("");  // SQL query
00423     g_string_printf( sql, "SELECT %s"
00424                           " FROM annotations"
00425                           " WHERE annotation_id IN (%lld",
00426                      columns->str,
00427                      *p_anno      );
00428     p_anno++;
00429     int i;
00430     for ( i = 1 ; i < annotation_id_num ; i++ )
00431     {
00432         g_string_append_printf( sql, ", %lld", *p_anno );
00433         p_anno++;
00434     }
00435     g_string_append( sql, ");" );
00436 
00437     // execute query
00438     int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00439     if (rc != ER_OK)
00440     {
00441         ERRORPRINTF("cannot get metadata, sql [%s]", sql->str);
00442         ret = ER_NOT_FOUND;
00443     }
00444     g_string_free(sql, TRUE);
00445 
00446     // NOTE can turn ok into fail!
00447     ret = sql3_commit_or_rollback(thiz, ret);
00448 out:
00449     g_string_free(columns, TRUE);
00450 
00451     *values_tbl = result;
00452     return ret;
00453 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_get_application_data ( erMetadb  thiz,
const gchar *  filename,
const metadata_table names_tbl,
metadata_table **  values_tbl 
)

Get selected application_data fields for a file or folder.

---------------------------------------------------------------------------

Name : ermetadb_local_get_application_data

Parameters:
[in] thiz - erMetadb object
[in] filename - filename of the document or folder
[in] names_tbl - metadata_table holding application keys a single row only, because keys are for one file or folder
[out] values_tbl - metadata_table holding application keys and values a single row only, because keys/values are for one file or folder or NULL on error Caller must use metadata_table_free() to release this table.
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 768 of file ermetadb_local.c.

References CHECK_LOCAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ERMETADB_FAIL, ERRORPRINTF, get_keys(), get_local_id(), LOGPRINTF, metadata_table_free, rotate_keyval_table(), sql3_begin_transaction_readonly(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by load_application_data(), and meta_file_open().

00772 {
00773     LOGPRINTF("file [%s]", filename);
00774 
00775     CHECK_LOCAL
00776     g_assert(filename && filename[0]);
00777     g_return_val_if_fail( names_tbl, ER_INVALID_PARAMETER );
00778     g_return_val_if_fail( (values_tbl && *values_tbl == NULL ), ER_INVALID_PARAMETER );
00779 
00780     gint64 file_id = get_local_id(thiz, filename);
00781     if (file_id < 0) return ER_NOT_FOUND;
00782 
00783     int ret = sql3_begin_transaction_readonly(thiz);
00784     if (ret != ER_OK) return ret;
00785 
00786     // build sql query
00787     GString *keys = get_keys(names_tbl);
00788     GString *sql = g_string_new("");
00789     g_string_printf( sql, "SELECT key, value"
00790                           " FROM application_data"
00791                           " WHERE file_id=%lld"
00792                           "   AND key IN (%s);",
00793                      file_id,
00794                      keys->str );
00795     g_string_free(keys, TRUE);
00796 
00797     // execute query
00798     metadata_table *result = NULL;
00799     int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00800     if (rc != ER_OK)
00801     {
00802         ERRORPRINTF("cannot get application_data, sql [%s]", sql->str);
00803         ret = ERMETADB_FAIL;
00804     }
00805     g_string_free(sql, TRUE);
00806 
00807     // NOTE: ret can become OK here after rollback!
00808     ret = sql3_commit_or_rollback(thiz, ret);
00809 
00810     // rotate result: one row per key-val --> one column per key-val
00811     metadata_table *rotated = NULL;
00812     if (rc == ER_OK && result)
00813     {
00814         rotated = rotate_keyval_table(result);
00815     }
00816     *values_tbl = rotated;
00817 
00818     metadata_table_free(result);
00819     return ret;
00820 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_remove_annotation ( erMetadb  thiz,
const gint64  annotation_id 
)

Remove selected annotation.

---------------------------------------------------------------------------

Name : ermetadb_local_remove_annotation

Parameters:
[in] thiz - erMetadb object
[in] annotation_id - unique id of this annotation
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 141 of file ermetadb_local.c.

References CHECK_LOCAL, ER_OK, ERMETADB_FAIL, ERRORPRINTF, LOGPRINTF, and sql3_execute_query().

Referenced by erscribble_doc_delete_page_impl(), and save_page_data().

00142 {
00143     LOGPRINTF("annotation_id [%lld]", annotation_id);
00144 
00145     CHECK_LOCAL
00146 
00147     char query[255];
00148     sprintf(query, "DELETE FROM annotations WHERE annotation_id = %lld", annotation_id );
00149     int rc = sql3_execute_query(thiz->database, query, NULL, NULL);
00150     if (rc != ER_OK)
00151     {
00152         ERRORPRINTF("cannot delete annotation, sql [%s]", query);
00153         rc = ERMETADB_FAIL;
00154     }
00155     return rc;
00156 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_remove_application_data ( erMetadb  thiz,
const gchar *  filename,
const metadata_table names_tbl 
)

Remove selected application_data fields for a file or folder.

---------------------------------------------------------------------------

Name : ermetadb_local_remove_application_data

Parameters:
[in] thiz - erMetadb object
[in] filename - filename of the document or folder
[in] names_tbl - metadata_table holding application keys a single row only, because keys are for one file or folder
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 569 of file ermetadb_local.c.

References CHECK_LOCAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ERMETADB_FAIL, ERRORPRINTF, get_keys(), get_local_id(), LOGPRINTF, metadata_table_n_rows, sql3_begin_transaction(), sql3_commit_or_rollback(), and sql3_execute_query().

00572 {
00573     LOGPRINTF("file [%s]", filename);
00574 
00575     CHECK_LOCAL
00576     g_assert(filename && filename[0]);
00577     g_return_val_if_fail( names_tbl, ER_INVALID_PARAMETER );
00578     g_return_val_if_fail( (metadata_table_n_rows(names_tbl) == 0), ER_INVALID_PARAMETER );
00579 
00580     gint64 file_id = get_local_id(thiz, filename);
00581     if (file_id < 0) return ER_NOT_FOUND;
00582 
00583     // start transaction
00584     int ret = sql3_begin_transaction(thiz);
00585     if (ret != ER_OK) return ret;
00586 
00587     // build sql query
00588     GString *keys = get_keys(names_tbl);
00589     GString *sql = g_string_new("");
00590     g_string_printf( sql, "DELETE FROM application_data"
00591                           " WHERE file_id=%lld"
00592                           "   AND key IN (%s);",
00593                      file_id, keys->str );
00594     g_string_free(keys, TRUE);
00595 
00596     int rc = sql3_execute_query(thiz->database, sql->str, NULL, NULL);
00597     if (rc != ER_OK)
00598     {
00599         ERRORPRINTF("cannot delete application_data, sql [%s]", sql->str);
00600         ret = ERMETADB_FAIL;
00601     }
00602     g_string_free(sql, TRUE);
00603 
00604     ret = sql3_commit_or_rollback(thiz, ret);
00605     return ret;
00606 }

Here is the call graph for this function:

int ermetadb_local_select_annotations ( erMetadb  thiz,
const gchar *  filename,
const gchar *  annotation_type,
const gchar *  layer,
const gint64  file_position_min,
const gint64  file_position_max,
metadata_table **  values_tbl 
)

Get basic annotation fields within the specified range for a file or folder Basic annotation fields are the following columns from table annotations: annotation_id, annotation_type, layer, file_position, start_anchor, end_anchor Results are sorted on (1) file_position and (2) annotation_type and (3) layer Application must select from result the annotations it is really interested in, then call ermetadb_local_get_annotations() for the details of these. This avoids retrieving blob data for annotations that are not used by the application. Note that the library can select on file_position only, which is a pretty course selection, while the application can select on start_anchor and end_anchor, which is much more accurate.

---------------------------------------------------------------------------

Name : ermetadb_local_select_annotations

Parameters:
[in] thiz - erMetadb object
[in] filename - filename of the document or folder
[in] annotation_type - specifies what type of annotation is requested or NULL to select all annotation types
[in] layer - specifies what layer these annotations belong to or empty string to select annotation to which no layer is applicable or NULL to select all layers
[in] file_position_min - minimum value for file_position of selected annotations or -1 when no minimum selection on file_position
[in] file_position_max - maximum value for file_position of selected annotations or -1 when no maximum selection on file_position
[out] values_tbl - metadata_table holding annotation values one row per annotation or NULL on error Caller must use metadata_table_free() to release this table.
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 457 of file ermetadb_local.c.

References CHECK_LOCAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ERRORPRINTF, get_local_id(), LOGPRINTF, sql3_begin_transaction_readonly(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by load_document_data().

00464 {
00465     LOGPRINTF("file [%s]", filename);
00466 
00467     CHECK_LOCAL
00468     g_assert(filename && filename[0]);
00469     g_return_val_if_fail( (annotation_type == NULL || annotation_type[0] != 0), ER_INVALID_PARAMETER );
00470     g_return_val_if_fail( values_tbl && *values_tbl == NULL, ER_INVALID_PARAMETER );
00471 
00472     // start transaction
00473     int ret = sql3_begin_transaction_readonly(thiz);
00474     if (ret != ER_OK) return ret;
00475 
00476     metadata_table *result = NULL;
00477     
00478     gint64 file_id = get_local_id(thiz, filename);
00479     if (file_id < 0) goto out;
00480 
00481     // build sql
00482     GString *sql = g_string_new("");
00483     g_string_printf( sql, "SELECT annotation_id"
00484                                ", annotation_type"
00485                                ", layer"
00486                                ", file_position"
00487                                ", start_anchor"
00488                                ", end_anchor"
00489                           " FROM annotations"
00490                           " WHERE file_id = %lld",
00491                      file_id );
00492     if (annotation_type)
00493     {
00494         char *str = sqlite3_mprintf("%Q", annotation_type);
00495         g_string_append_printf(sql, " AND annotation_type = %s", str);
00496         sqlite3_free(str);
00497     }
00498     if (layer)
00499     {
00500         char *str = sqlite3_mprintf("%Q", layer);
00501         g_string_append_printf(sql, " AND layer = %s", str);
00502         sqlite3_free(str);
00503     }
00504     if (file_position_min >= 0)
00505     {
00506         g_string_append_printf(sql, " AND file_position >= %lld", file_position_min);
00507     }
00508     if (file_position_max >= 0)
00509     {
00510         g_string_append_printf(sql, " AND file_position <= %lld", file_position_max);
00511     }
00512     g_string_append(sql, "ORDER BY file_position, annotation_type, layer;");
00513 
00514     // execute query
00515     int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00516     if (rc != ER_OK)
00517     {
00518         ERRORPRINTF("cannot get annotations, sql [%s]", sql->str);
00519         ret = ER_NOT_FOUND;
00520     }
00521     g_string_free(sql, TRUE);
00522 
00523 out:
00524     ret = sql3_commit_or_rollback(thiz, ret);
00525 
00526     *values_tbl = result;
00527     return ret;
00528 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_set_annotation ( erMetadb  thiz,
const gint64  annotation_id,
const gchar *  annotation_type,
const gchar *  layer,
const gint64  file_position,
const gchar *  title,
const gchar *  start_anchor,
const gchar *  end_anchor,
const gchar *  data_blob,
const guint  data_len 
)

Set selected annotation fields for a file or folder.

---------------------------------------------------------------------------

Name : ermetadb_local_set_annotation

Parameters:
[in] thiz - erMetadb object
[in] annotation_id - unique id of this annotation
[in] annotation_type - specifies what type of annotation this is
[in] layer - specifies what layer this annotation belongs to or empty string when no layer is applicable
[in] file_position - page number (1, 2, ..) for page-oriented docs like pdf, relative position (0 .. 100,000 for 0 .. 100%) for reflowable content
[in] title - specifies a title for this annotation or NULL when no title is applicable
[in] start_anchor - exact begin position of this annotation in the document or NULL when not relevant
[in] end_anchor - exact end position of this annotation in the document or NULL when not relevant
[in] data_blob - data belonging to this annotation as a blob or NULL when no data Note: caller must release this data after the function returns.
[in] data_len - number of bytes in data_blob or zero when no data
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 355 of file ermetadb_local.c.

References CHECK_LOCAL, ER_OK, LOGPRINTF, set_annotation_impl(), sql3_begin_transaction(), and sql3_commit_or_rollback().

Referenced by save_page_data().

00365 {
00366     LOGPRINTF("annotation_id [%lld]", annotation_id);
00367 
00368     CHECK_LOCAL
00369     g_assert(annotation_id);
00370 
00371     int ret = sql3_begin_transaction(thiz);
00372     if (ret != ER_OK) return ret;
00373 
00374     ret = set_annotation_impl( thiz,
00375                                annotation_id,
00376                                annotation_type,
00377                                layer,
00378                                file_position,
00379                                title,
00380                                start_anchor,
00381                                end_anchor,
00382                                data_blob,
00383                                data_len        );
00384 
00385     ret = sql3_commit_or_rollback(thiz, ret);
00386     return ret;
00387 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_local_set_application_data ( erMetadb  thiz,
const gchar *  filename,
const metadata_table values_tbl 
)

Set selected application_data fields for a file or folder.

---------------------------------------------------------------------------

Name : ermetadb_local_set_application_data

Parameters:
[in] thiz - erMetadb object
[in] filename - filename of the document or folder
[in] values_tbl - metadata_table holding application keys (column name) and values a single row only, because keys/values are for one file or folder keys with value type METADATA_NULL will be removed from the database
Returns:
ER_OK or error code

--------------------------------------------------------------------------

Definition at line 609 of file ermetadb_local.c.

References CHECK_LOCAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ERMETADB_FAIL, ERRORPRINTF, find_or_create_filename(), LOGPRINTF, METADATA_NULL, metadata_table_get_cell(), metadata_table_n_columns, metadata_table_n_rows, metadata_cell::name, sql3_begin_transaction(), sql3_commit_or_rollback(), sql3_execute_query(), and metadata_cell::type.

Referenced by meta_file_close(), and save_application_data().

00612 {
00613     LOGPRINTF("file [%s]", filename);
00614 
00615     CHECK_LOCAL
00616     g_assert(filename && filename[0]);
00617     g_return_val_if_fail( values_tbl, ER_INVALID_PARAMETER );
00618     g_return_val_if_fail( (metadata_table_n_rows(values_tbl) == 1), ER_INVALID_PARAMETER );
00619 
00620     gint64 file_id = find_or_create_filename(thiz, filename);
00621     if (file_id < 0) return ER_NOT_FOUND;
00622 
00623     int ret = sql3_begin_transaction(thiz);
00624     if (ret != ER_OK) return ret;
00625 
00626     // build delete and insert statements for sql query
00627     GString *sql_del = NULL;     // SQL delete statement
00628     GString *sql_ins   = NULL;     // SQL insert statements
00629     int n_cols = metadata_table_n_columns(values_tbl);
00630     int col;
00631     for (col = 0 ; col < n_cols ; col++)
00632     {
00633         const metadata_cell*cell = metadata_table_get_cell(values_tbl, col);
00634         if (cell && cell->name && cell->name->str)
00635         {
00636             char* sql3_cellname = sqlite3_mprintf("%Q", cell->name->str);
00637 
00638             if (cell->type == METADATA_NULL)
00639             {
00640                 // add this key to sql delete statement
00641                 if (sql_del == NULL)
00642                 {
00643                     sql_del = g_string_new("");
00644                     g_string_printf( sql_del, "DELETE FROM application_data"
00645                                               " WHERE file_id=%lld"
00646                                               "   AND key IN ( %s",
00647                                      file_id,
00648                                      sql3_cellname );
00649                 }
00650                 else
00651                 {
00652                     g_string_append_printf( sql_del, ", %s", sql3_cellname );
00653                 }
00654             }
00655             else
00656             {
00657                 // add this key to sql_insert statement
00658                 if (sql_ins == NULL)
00659                 {
00660                     sql_ins = g_string_new("");
00661                 }
00662                 g_string_append_printf( sql_ins, "INSERT OR REPLACE INTO application_data"
00663                                                  " (file_id, key, value)"
00664                                                  " VALUES (%lld, %s, ?%d);",
00665                                         file_id,
00666                                         sql3_cellname,
00667                                         col + 1   );
00668             }
00669             sqlite3_free( sql3_cellname );
00670         }
00671     }
00672     if (sql_del) g_string_append( sql_del, " );" );
00673 
00674     // execute delete query
00675     if (sql_del)
00676     {
00677         int rc = sql3_execute_query(thiz->database, sql_del->str, NULL, NULL);
00678         if (rc != ER_OK)
00679         {
00680             ERRORPRINTF("cannot delete application_data, sql [%s]", sql_del->str);
00681             ret = ERMETADB_FAIL;
00682         }
00683     }
00684 
00685     // execute insert query
00686     if (ret == ER_OK && sql_ins)
00687     {
00688         int rc = sql3_execute_query(thiz->database, sql_ins->str, values_tbl, NULL);
00689         if (rc != ER_OK)
00690         {
00691             ERRORPRINTF("cannot insert application_data, sql [%s]", sql_ins->str);
00692             ret = ERMETADB_FAIL;
00693         }
00694     }
00695 
00696     ret = sql3_commit_or_rollback(thiz, ret);
00697 
00698     if (sql_ins) { g_string_free(sql_ins, TRUE); }
00699     if (sql_del) { g_string_free(sql_del, TRUE); }
00700     return ret;
00701 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gint64 find_or_create_filename ( erMetadb  thiz,
const char *  filename 
) [static]

Definition at line 264 of file ermetadb_local.c.

References ER_OK, ERRORPRINTF, get_local_id(), and sql3_execute_query().

Referenced by ermetadb_local_create_annotation(), and ermetadb_local_set_application_data().

00265 {
00266     gint64 file_id = get_local_id(thiz, filename);
00267     if (file_id < 0) {
00268         char *sql = sqlite3_mprintf("INSERT INTO file_metadata (filename) VALUES (%Q);", filename);
00269         int rc = sql3_execute_query(thiz->database, sql, NULL, NULL);
00270         sqlite3_free(sql);
00271         if (rc != ER_OK)
00272         {
00273             ERRORPRINTF("cannot add filename [%s]", filename);
00274             return -1;
00275         }
00276         file_id = sqlite3_last_insert_rowid(thiz->database);
00277     }
00278     return file_id;
00279 }

Here is the call graph for this function:

Here is the caller graph for this function:

static GString* get_keys ( const metadata_table names_tbl  )  [static]

Definition at line 545 of file ermetadb_local.c.

References metadata_table_get_cell(), metadata_table_n_columns, and metadata_cell::name.

Referenced by ermetadb_local_get_application_data(), and ermetadb_local_remove_application_data().

00546 {
00547     GString *sql_keys = g_string_new("");
00548     int n_cols = metadata_table_n_columns(names_tbl);
00549     int col;
00550     for (col = 0 ; col < n_cols ; col++)
00551     {
00552         const metadata_cell *cell = metadata_table_get_cell(names_tbl, col);
00553         if (cell && cell->name && cell->name->str)
00554         {
00555             char *sql3_cellname = sqlite3_mprintf("%Q", cell->name->str);
00556             if (sql_keys->len > 0)
00557             {
00558                 g_string_append(sql_keys, ", ");
00559             }
00560             g_string_append(sql_keys, sql3_cellname);
00561 
00562             sqlite3_free( sql3_cellname );
00563         }
00564     }
00565     return sql_keys;
00566 }

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* const* get_local_column_names ( const char *  table  )  [static]

Definition at line 103 of file ermetadb_local.c.

References local_database_tables, table_name, and TRACE.

Referenced by ermetadb_local_get_annotations().

00104 {
00105     TRACE("entry: table [%s]", table);
00106     g_assert(table);
00107 
00108     int i;
00109     for (i = 0 ; local_database_tables[i].table_name; i++)
00110     {
00111         if ( strcmp(local_database_tables[i].table_name, table) == 0 )
00112         {
00113             return local_database_tables[i].column_names;
00114         }
00115     }
00116     return NULL;
00117 }

Here is the caller graph for this function:

static gint64 get_local_id ( erMetadb  thiz,
const char *  filename 
) [static]

Definition at line 120 of file ermetadb_local.c.

References ER_OK, METADATA_INT64, metadata_table_free, metadata_table_get_cell(), sql3_execute_query(), metadata_cell::type, metadata_cell::v_int64, and metadata_cell::value.

Referenced by ermetadb_local_get_application_data(), ermetadb_local_remove_application_data(), ermetadb_local_select_annotations(), find_or_create_filename(), and local_delete_all_data_for_file().

00121 {
00122     // build query
00123     char *query = sqlite3_mprintf("SELECT file_id FROM file_metadata WHERE filename = %Q LIMIT 1;",
00124                 filename);
00125 
00126     metadata_table *result = NULL;
00127     int rc = sql3_execute_query(thiz->database, query, NULL, &result);
00128     gint64 file_id = -1;
00129     if (rc == ER_OK && result) {
00130         const metadata_cell *cell = metadata_table_get_cell(result, 0);
00131         g_assert(cell->type == METADATA_INT64);
00132         file_id = cell->value.v_int64;
00133     }
00134 
00135     sqlite3_free(query);
00136     metadata_table_free(result);
00137     return file_id;
00138 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int local_delete_all_annotations ( erMetadb  thiz,
gint64  file_id 
) [static]

Definition at line 531 of file ermetadb_local.c.

References ER_OK, ERMETADB_FAIL, ERRORPRINTF, and sql3_execute_query().

Referenced by local_delete_all_data_for_id().

00532 {
00533     char query[255];
00534     sprintf(query, "DELETE FROM annotations WHERE file_id=%lld;", file_id );
00535     int rc = sql3_execute_query(thiz->database, query, NULL, NULL);
00536     if (rc != ER_OK)
00537     {
00538         ERRORPRINTF("cannot delete annotations, sql [%s]", query);
00539         rc = ERMETADB_FAIL;
00540     }
00541     return rc;
00542 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int local_delete_all_application_data ( erMetadb  thiz,
gint64  file_id 
) [static]

Definition at line 823 of file ermetadb_local.c.

References ER_OK, ERMETADB_FAIL, ERRORPRINTF, and sql3_execute_query().

Referenced by local_delete_all_data_for_id().

00824 {
00825     char query[255];
00826     sprintf(query, "DELETE FROM application_data WHERE file_id=%lld;", file_id );
00827 
00828     int rc = sql3_execute_query(thiz->database, query, NULL, NULL);
00829     if (rc != ER_OK)
00830     {
00831         ERRORPRINTF("cannot delete application_data, sql [%s]", query);
00832         rc = ERMETADB_FAIL;
00833     }
00834     return rc;
00835 }

Here is the call graph for this function:

Here is the caller graph for this function:

int local_delete_all_data_for_file ( erMetadb  thiz,
const char *  filename 
)

Definition at line 846 of file ermetadb_local.c.

References ER_NOT_FOUND, get_local_id(), and local_delete_all_data_for_id().

Referenced by delete_local_metadata().

00847 {
00848     g_assert(!thiz->is_global);
00849 
00850     gint64 file_id = get_local_id(thiz, filename);
00851     if (file_id < 0) return ER_NOT_FOUND;
00852 
00853     return local_delete_all_data_for_id(thiz, file_id);
00854 }

Here is the call graph for this function:

Here is the caller graph for this function:

int local_delete_all_data_for_id ( erMetadb  thiz,
gint64  file_id 
)

Definition at line 857 of file ermetadb_local.c.

References ER_OK, local_delete_all_annotations(), local_delete_all_application_data(), local_delete_entry(), sql3_begin_transaction(), and sql3_commit_or_rollback().

Referenced by convert_database_05_06(), and local_delete_all_data_for_file().

00858 {
00859     g_assert(!thiz->is_global);
00860 
00861     int ret = sql3_begin_transaction(thiz);
00862     if (ret != ER_OK) return ret;
00863 
00864     // delete annotations, application data and file_metadata entry
00865     local_delete_all_annotations(thiz, file_id);
00866     local_delete_all_application_data(thiz, file_id);
00867     local_delete_entry(thiz, file_id);
00868 
00869     ret = sql3_commit_or_rollback(thiz, ER_OK);
00870     return ret;
00871 
00872 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int local_delete_entry ( erMetadb  thiz,
gint64  file_id 
) [static]

Definition at line 838 of file ermetadb_local.c.

References sql3_execute_query().

Referenced by local_delete_all_data_for_id().

00839 {
00840     char query[255];
00841     snprintf(query, sizeof(query), "DELETE FROM file_metadata WHERE file_id = %lld;", file_id);
00842     return sql3_execute_query(thiz->database, query, NULL, NULL);
00843 }

Here is the call graph for this function:

Here is the caller graph for this function:

static metadata_table* rotate_keyval_table ( const metadata_table table  )  [static]

Definition at line 707 of file ermetadb_local.c.

References ER_OK, ERRORPRINTF, metadata_table_add_column(), metadata_table_cell_index, metadata_table_find_column(), metadata_table_free, metadata_table_get_cell(), metadata_table_get_string(), metadata_table_n_rows, metadata_table_new(), metadata_table_set_cell(), and metadata_cell::type.

Referenced by ermetadb_local_get_application_data().

00708 {
00709     // find 'key' and 'value' columns
00710     int n_keys  = metadata_table_n_rows(table);
00711     int col_key = metadata_table_find_column(table, "key"  );
00712     int col_val = metadata_table_find_column(table, "value");
00713     g_assert(col_key >= 0);
00714     g_assert(col_val >= 0);
00715 
00716     // create new table
00717     metadata_table *rotated = metadata_table_new();
00718 
00719     // convert table.rows into rotated.columns
00720     int key_index;
00721     gboolean ok = TRUE;
00722     for (key_index = 0 ; key_index < n_keys ; key_index++)
00723     {
00724         // set column name = key
00725         GString *key = metadata_table_get_string( table, 
00726                                          metadata_table_cell_index(table, key_index, col_key) );
00727         if (key == NULL || key->len == 0)
00728         {
00729             ERRORPRINTF("cannot read key from row [%d]", key_index);
00730             ok = FALSE;
00731         }
00732         else
00733         {
00734             int rc = metadata_table_add_column(rotated, key->str);
00735             if (rc != ER_OK)
00736             {
00737                 ERRORPRINTF("cannot add column [%s] in rotated, error [%d]", key->str, rc);
00738                 ok = FALSE;
00739             }
00740         }
00741         if (key)
00742         {
00743             g_string_free(key, TRUE);
00744         }
00745 
00746         // set column value = value
00747         if (ok)
00748         {
00749             const metadata_cell *cell = metadata_table_get_cell( table,
00750                                             metadata_table_cell_index(table, key_index, col_val) );
00751             int rc = metadata_table_set_cell( rotated, key_index, cell );
00752             if (rc != ER_OK)
00753             {
00754                 ERRORPRINTF("cannot set value type [%d] in cell, error [%d]", cell->type, rc);
00755                 ok = FALSE;
00756             }
00757         }
00758     }
00759 
00760     if (!ok)
00761     {
00762         metadata_table_free(rotated);
00763     }
00764     return rotated;
00765 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_annotation_impl ( erMetadb  thiz,
const gint64  annotation_id,
const gchar *  annotation_type,
const gchar *  layer,
const gint64  file_position,
const gchar *  title,
const gchar *  start_anchor,
const gchar *  end_anchor,
const gchar *  data_blob,
const guint  data_len 
) [static]

Definition at line 160 of file ermetadb_local.c.

References ER_INVALID_PARAMETER, ER_OK, ERMETADB_FAIL, ERRORPRINTF, metadata_table_add_column(), metadata_table_free, metadata_table_new(), metadata_table_set_blob_static(), sql3_execute_query(), and TRACE.

Referenced by ermetadb_local_create_annotation(), and ermetadb_local_set_annotation().

00170 {
00171     TRACE("annotation_id [%lld]", annotation_id);
00172 
00173     g_return_val_if_fail( annotation_type, ER_INVALID_PARAMETER );
00174     g_return_val_if_fail( layer, ER_INVALID_PARAMETER );
00175     g_return_val_if_fail( file_position >= 0, ER_INVALID_PARAMETER );
00176     g_return_val_if_fail( (start_anchor == NULL || start_anchor[0] != 0), ER_INVALID_PARAMETER );
00177     g_return_val_if_fail( (end_anchor == NULL || end_anchor[0] != 0), ER_INVALID_PARAMETER );
00178     g_return_val_if_fail( (data_blob == NULL || data_len > 0), ER_INVALID_PARAMETER );
00179 
00180     // build sql query
00181     GString *sql = g_string_new("");
00182     char *sql3_annotype = sqlite3_mprintf("%Q", annotation_type);
00183     char *sql3_layer    = sqlite3_mprintf("%Q", layer);
00184     g_string_printf(        sql, "UPDATE annotations"
00185                                  " SET annotation_type = %s,"
00186                                      " layer = %s,"
00187                                      " file_position = %lld",
00188                             sql3_annotype,
00189                             sql3_layer,
00190                             file_position );
00191     sqlite3_free(sql3_layer   );
00192     sqlite3_free(sql3_annotype);
00193 
00194     g_string_append(        sql, ", title = " );
00195     if (title)
00196     {
00197         char *sql3_string = sqlite3_mprintf("%Q", title);
00198         g_string_append( sql, sql3_string );
00199         sqlite3_free(sql3_string);
00200     }
00201     else
00202     {
00203         // clear old title
00204         g_string_append(    sql, "NULL" );
00205     }
00206 
00207     g_string_append(        sql, ", start_anchor = " );
00208     if (start_anchor)
00209     {
00210         char *sql3_string = sqlite3_mprintf("%Q", start_anchor);
00211         g_string_append( sql, sql3_string );
00212         sqlite3_free(sql3_string);
00213     }
00214     else
00215     {
00216         // clear old anchor
00217         g_string_append(    sql, "NULL" );
00218     }
00219 
00220     g_string_append(        sql, ", end_anchor = " );
00221     if (end_anchor)
00222     {
00223         char *sql3_string = sqlite3_mprintf("%Q", end_anchor);
00224         g_string_append( sql, sql3_string);
00225         sqlite3_free(sql3_string);
00226     }
00227     else
00228     {
00229         // clear old anchor
00230         g_string_append(    sql, "NULL" );
00231     }
00232 
00233     g_string_append(        sql, ", data = " );
00234     metadata_table *parameters = NULL;
00235     if (data_blob)
00236     {
00237         parameters = metadata_table_new();
00238         metadata_table_add_column( parameters, "data" );
00239         metadata_table_set_blob_static( parameters, 0, data_blob, data_len );
00240         g_string_append(        sql, "?1" );
00241     }
00242     else
00243     {
00244         // clear old data
00245         g_string_append(        sql, "NULL" );
00246     }
00247 
00248     g_string_append_printf( sql, " WHERE annotation_id = %lld;",
00249                             annotation_id );
00250 
00251     // execute query
00252     int rc = sql3_execute_query(thiz->database, sql->str, parameters, NULL);
00253     if (rc != ER_OK)
00254     {
00255         ERRORPRINTF("cannot set annotation details, sql [%s]", sql->str);
00256         rc = ERMETADB_FAIL;
00257     }
00258 
00259     metadata_table_free(parameters);
00260     return rc;
00261 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char* column_names[LOCAL_MAX_COLUMNS+1]

Definition at line 51 of file ermetadb_local.c.

struct { ... } local_database_tables[] [static]

Referenced by get_local_column_names().

const char* table_name

Definition at line 50 of file ermetadb_local.c.

Generated by  doxygen 1.6.2-20100208