ermetadb_file.c File Reference

#include <glib.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.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_file.c:

Go to the source code of this file.

Defines

#define MDB_SORT_PRIORITY_FILE   10
#define MDB_SORT_PRIORITY_FOLDER   20
#define CHECK_GLOBAL

Enumerations

enum  is_directory_value { ISDIR_DOCUMENT = 0, ISDIR_FOLDER, ISDIR_DONT_CARE }

Functions

const char * g_extension_pointer (const char *path)
static gint64 get_global_id (erMetadb thiz, const gchar *filename, const gchar *filepath, const is_directory_value is_dir)
static int add_filename (erMetadb thiz, const gchar *filepath, const gchar *filename, const gboolean is_directory, const gint64 size, const gint64 time_modified, const gchar *title, const gchar *author, const gchar *tag)
int ermetadb_global_add_folder (erMetadb thiz, const gchar *filepath, const gchar *foldername, const gint64 time_modified)
 Add a folder to the metadata database.
int ermetadb_global_add_file (erMetadb thiz, const gchar *filepath, const gchar *filename, const gint64 size, const gint64 time_modified, const gchar *title, const gchar *author, const gchar *tag)
 Add a file to the metadata database.
int ermetadb_global_rename_file (erMetadb thiz, const gchar *filepath, const gchar *filename, const gchar *new_filename, const gchar *new_title)
 Renames a file to another name.
static int delete_entry (erMetadb thiz, gint64 file_id)
int ermetadb_global_remove_folder (erMetadb thiz, const gchar *filepath, const gchar *filename)
 Remove a folder from the metadata database.
int ermetadb_global_remove_file (erMetadb thiz, const gchar *filepath, const gchar *filename)
 Remove a document from the global AND local database.
static int delete_local_metadata (const gchar *filepath, const gchar *filename)
int ermetadb_global_remove_entry (erMetadb thiz, gint64 file_id, const gchar *filepath, const gchar *filename, gboolean is_dir)
 Remove a file/folder from the global AND local database.
static int set_file_metadata_impl (erMetadb thiz, const gchar *filepath, const gchar *filename, const metadata_table *values_tbl)
int ermetadb_global_change_file (erMetadb thiz, const gchar *filepath, const gchar *filename, const metadata_table *values_tbl)
 Set selected file_metadata fields for a file or folder.
int ermetadb_global_update_size (erMetadb thiz, gint64 file_id, gint64 last_modified, gint64 filesize)
 Updates size and last modified fields of entry.
int ermetadb_global_update_title (erMetadb thiz, gint64 file_id, const gchar *title, const gchar *author)
 Updates title and author fields of entry.
static GString * get_column_names (const metadata_table *names_tbl)
int ermetadb_global_get_file (erMetadb thiz, const gchar *filepath, const gchar *filename, const metadata_table *names_tbl, metadata_table **values_tbl)
 Get selected file_metadata fields for a file or folder.
int ermetadb_global_select_all (erMetadb thiz, metadata_table **values_tbl)
 Returns the contents of the file_metadata table.
static int global_select_common (erMetadb thiz, const gchar *sort_key, gboolean sort_is_ascending, long num_items, const metadata_table *names_tbl, metadata_table **values_tbl, const gchar *extra_sql)
int ermetadb_global_select_files (erMetadb thiz, const gchar *sort_key, gboolean sort_is_ascending, const metadata_table *names_tbl, metadata_table **values_tbl, const gchar *tag_filter)
 Get selected file_metadata fields for a group of files/folders sorted on (1) specified metadata field and (2) filename ascending This function mainly exists for content browser assistance.
int ermetadb_global_select_recent (erMetadb thiz, const gchar *sort_key, int num_items, const metadata_table *names_tbl, metadata_table **values_tbl)
int ermetadb_global_select_subdir (erMetadb thiz, const gchar *sort_key, gboolean sort_is_ascending, const metadata_table *names_tbl, metadata_table **values_tbl, const gchar *path_filter)
int ermetadb_global_select_search (erMetadb thiz, const gchar *sort_key, gboolean sort_is_ascending, const metadata_table *names_tbl, metadata_table **values_tbl, const gchar *search_filter)

Variables

static const gchar * FILE_METADATA_DIRPATH_DEFAULT = "."

Define Documentation

#define CHECK_GLOBAL
#define MDB_SORT_PRIORITY_FILE   10

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

Definition at line 53 of file ermetadb_file.c.

Referenced by add_filename().

#define MDB_SORT_PRIORITY_FOLDER   20

Definition at line 54 of file ermetadb_file.c.

Referenced by add_filename().


Enumeration Type Documentation

Enumerator:
ISDIR_DOCUMENT 
ISDIR_FOLDER 
ISDIR_DONT_CARE 

Definition at line 65 of file ermetadb_file.c.

00066         {
00067             ISDIR_DOCUMENT = 0,
00068             ISDIR_FOLDER,
00069             ISDIR_DONT_CARE,
00070         } is_directory_value;


Function Documentation

static int add_filename ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename,
const gboolean  is_directory,
const gint64  size,
const gint64  time_modified,
const gchar *  title,
const gchar *  author,
const gchar *  tag 
) [static]

Definition at line 178 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_OK, ERMETADB_FAIL, ERRORPRINTF, FILE_METADATA_DIRPATH_DEFAULT, g_extension_pointer(), MDB_SORT_PRIORITY_FILE, MDB_SORT_PRIORITY_FOLDER, sql3_begin_transaction(), sql3_commit_or_rollback(), sql3_execute_query(), and TRACE.

Referenced by ermetadb_global_add_file(), and ermetadb_global_add_folder().

00187 {
00188     TRACE("entry: path [%s] file [%s]", filepath, filename);
00189 
00190     CHECK_GLOBAL
00191     g_assert(filename && filename[0]);
00192     g_assert(filepath && filepath[0]);
00193 
00194     int ret = sql3_begin_transaction(thiz);
00195     if (ret != ER_OK) return ret;
00196 
00197     // add entry
00198     if (ret == ER_OK)
00199     {
00200         char *sql3_filename  = sqlite3_mprintf( "%Q", filename );
00201         char* extension;
00202         if (is_directory) extension = g_strdup("");
00203         else extension = g_ascii_strdown( g_extension_pointer(filename), -1 );
00204         char *sql3_extension = sqlite3_mprintf( "%Q", extension     );
00205         char *sql3_dirpath   = sqlite3_mprintf( "%Q", filepath ? filepath
00206                                                          : FILE_METADATA_DIRPATH_DEFAULT );
00207         char *sql3_title     = sqlite3_mprintf( "%Q", title ? title : filename);
00208         char *sql3_author    = sqlite3_mprintf( "%Q", author ? author : "");
00209         char *sql3_tag       = sqlite3_mprintf( "%Q", tag ? tag : "");
00210 
00211         GString *sql = g_string_new("");
00212         gint64 local_time = time(NULL);
00213         g_string_printf( sql, "INSERT INTO file_metadata"
00214                               " (filename, directory_path, sort_priority, is_directory,"
00215                                " file_type, file_size, file_time_modified, file_time_added,"
00216                                " title, author, tag)"
00217                               " VALUES (%s, %s, '%d', '%d',"
00218                                       " %s, '%lld', '%lld', '%lld',"
00219                                       " %s, %s, %s);",
00220                          sql3_filename,
00221                          sql3_dirpath,
00222                          is_directory ? MDB_SORT_PRIORITY_FOLDER : MDB_SORT_PRIORITY_FILE,
00223                          is_directory ? 1 : 0,
00224                          sql3_extension,
00225                          size,
00226                          time_modified,
00227                          local_time,
00228                          sql3_title,
00229                          sql3_author,
00230                          sql3_tag ); 
00231 
00232         sqlite3_free( sql3_dirpath   );
00233         sqlite3_free( sql3_extension );
00234         sqlite3_free( sql3_filename  );
00235         sqlite3_free( sql3_title     );
00236         sqlite3_free( sql3_tag       );
00237         g_free(extension);
00238 
00239         int rc = sql3_execute_query(thiz->database, sql->str, NULL, NULL);
00240         g_string_free(sql, TRUE);
00241         if (rc != ER_OK)
00242         {
00243             ERRORPRINTF("cannot insert filename [%s]", filename);
00244             ret = ERMETADB_FAIL;
00245         }
00246     }
00247 
00248     ret = sql3_commit_or_rollback(thiz, ret);
00249     return ret;
00250 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 332 of file ermetadb_file.c.

References sql3_execute_query().

Referenced by ermetadb_global_remove_entry(), and ermetadb_global_remove_folder().

00333 {
00334     // NOTE: thumbnails are deleted by trigger of delete
00335     char query[255];
00336     snprintf(query, sizeof(query), "DELETE FROM file_metadata WHERE file_id = %lld;", file_id);
00337     return sql3_execute_query(thiz->database, query, NULL, NULL);
00338 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int delete_local_metadata ( const gchar *  filepath,
const gchar *  filename 
) [static]

Definition at line 389 of file ermetadb_file.c.

References ER_OK, ermetadb_close(), ermetadb_local_open(), and local_delete_all_data_for_file().

Referenced by ermetadb_global_remove_entry().

00390 {
00391     // try to open local database
00392     erMetadb thiz = ermetadb_local_open(filepath, FALSE);
00393     if (thiz) {
00394         int ret = local_delete_all_data_for_file(thiz, filename);
00395         ermetadb_close(thiz);
00396         return ret;
00397     }
00398 
00399     return ER_OK;   // no database, ok
00400 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_add_file ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename,
const gint64  size,
const gint64  time_modified,
const gchar *  title,
const gchar *  author,
const gchar *  tag 
)

Add a file to the metadata database.

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

Name : ermetadb_global_add_file

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path of the file
[in] filename - filename of the file
[in] size - size of file
[in] time_modified - folder modification date/time as seconds since epoch
[in] title - title of file or NULL
[in] author - author of file or NULL
[in] tag - tag of file or NULL
Returns:
ER_OK or error code

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

Definition at line 264 of file ermetadb_file.c.

References add_filename(), and LOGPRINTF.

Referenced by add_file_to_metadata(), create_shortcut_item(), and db_add_entry().

00272 {
00273     LOGPRINTF("folder [%s]  file [%s]", filepath, filename);
00274 
00275     return add_filename(thiz, filepath, filename, FALSE, size, time_modified, title, author, tag);
00276 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_add_folder ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  foldername,
const gint64  time_modified 
)

Add a folder to the metadata database.

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

Name : ermetadb_global_add_folder

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path of the document
[in] foldername - filename of the folder
[in] time_modified - folder modification date/time as seconds since epoch
Returns:
ER_OK or error code

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

Definition at line 253 of file ermetadb_file.c.

References add_filename(), and LOGPRINTF.

Referenced by add_folder_to_metadata(), and db_add_entry().

00257 {
00258     LOGPRINTF("folder [%s]  file [%s]", filepath, foldername);
00259 
00260     return add_filename(thiz, filepath, foldername, TRUE, 0, time_modified, NULL, NULL, NULL);
00261 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Set selected file_metadata fields for a file or folder.

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

Name : ermetadb_global_change_file

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path for the document or folder
[in] filename - filename of the document or folder
[in] values_tbl - metadata_table holding metadata names and values a single row only, because data is for one file or folder
Returns:
ER_OK or error code

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

Definition at line 553 of file ermetadb_file.c.

References LOGPRINTF, and set_file_metadata_impl().

Referenced by db_query_update_lastread(), and save_file_metadata().

00557 {
00558     LOGPRINTF("folder [%s]  file [%s]", filepath, filename);
00559 
00560     return set_file_metadata_impl( thiz, filepath, filename, values_tbl );
00561 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Get selected file_metadata fields for a file or folder.

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

Name : ermetadb_global_get_file

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path for the document or folder
[in] filename - filename of the document or folder
[in] names_tbl - metadata_table holding metadata names or NULL to get all metadata columns
[out] values_tbl - metadata_table holding metadata names and values a single row only, because data is 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 634 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ermetadb_private_get_global_column_names(), ERRORPRINTF, get_column_names(), get_global_id(), ISDIR_DONT_CARE, LOGPRINTF, metadata_table_n_rows, name, sql3_begin_transaction_readonly(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by db_query_get_metadata(), and load_file_metadata().

00639 {
00640     LOGPRINTF("folder [%s]  file [%s]", filepath, filename);
00641 
00642     CHECK_GLOBAL
00643     g_assert(filename && filename[0]);
00644     g_assert(filepath && filepath[0]);
00645     g_return_val_if_fail( (metadata_table_n_rows(names_tbl) == 0), ER_INVALID_PARAMETER );
00646     g_return_val_if_fail( (values_tbl && *values_tbl == NULL    ), ER_INVALID_PARAMETER );
00647 
00648     gint64 file_id = get_global_id(thiz, filename, filepath, ISDIR_DONT_CARE);
00649     if (file_id < 0) return ER_NOT_FOUND;
00650 
00651     int ret = sql3_begin_transaction_readonly(thiz);
00652     if (ret != ER_OK) return ret;
00653 
00654     GString *columns = NULL;
00655     // build column names for sql query
00656     if (names_tbl)
00657     {
00658         columns = get_column_names(names_tbl);
00659     }
00660     else
00661     {
00662         columns = g_string_new("");
00663         const char* const *name;
00664         // get all known columns
00665         for ( name = ermetadb_private_get_global_column_names("file_metadata") ; *name ; name++ )
00666         {
00667             if (   strcmp(*name, "file_id"        ) != 0
00668                 && strcmp(*name, "filename"       ) != 0
00669                 && strcmp(*name, "directory_path" ) != 0
00670                 && strcmp(*name, "file_type"      ) != 0 )
00671             {
00672                 if (columns->len > 0)
00673                 {
00674                     g_string_append( columns, ", "  );
00675                 }
00676                 g_string_append( columns, *name );
00677             }
00678         }
00679         for ( name = ermetadb_private_get_global_column_names("thumbnails") ; *name ; name++ )
00680         {
00681             if ( strcmp(*name, "file_id") != 0 )
00682             {
00683                 if (columns->len > 0)
00684                 {
00685                     g_string_append( columns, ", "  );
00686                 }
00687                 g_string_append( columns, *name );
00688             }
00689         }
00690     }
00691 
00692     // build query
00693     GString *sql = g_string_new("");
00694     g_string_printf( sql, "SELECT %s FROM file_metadata AS m"
00695                           " LEFT JOIN thumbnails AS t"
00696                           " ON m.file_id = t.file_id"
00697                           " WHERE m.file_id=%lld",
00698                      columns->str,
00699                      file_id      );
00700     g_string_free(columns, TRUE);
00701 
00702     // execute query
00703     metadata_table *result = NULL;
00704     if (ret == ER_OK)
00705     {
00706         int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00707         if (rc != ER_OK)
00708         {
00709             ERRORPRINTF("cannot get metadata, sql [%s]", sql->str);
00710             ret = rc;
00711         }
00712     }
00713     g_string_free(sql, TRUE);
00714 
00715     ret = sql3_commit_or_rollback(thiz, ret);
00716 
00717     *values_tbl = result;
00718     return ret;
00719 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_remove_entry ( erMetadb  thiz,
gint64  file_id,
const gchar *  filepath,
const gchar *  filename,
gboolean  is_dir 
)

Remove a file/folder from the global AND local database.

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

Name : ermetadb_global_remove_entry

Parameters:
[in] thiz - erMetadb object
[in] file_id - db id of entry
[in] filepath - directory_path for the document
[in] filename - filename of the document
[in] is_dir - whether entry is a dir
Returns:
ER_OK or error code ER_OK when filename with filepath not present in database

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

Definition at line 403 of file ermetadb_file.c.

References CHECK_GLOBAL, delete_entry(), delete_local_metadata(), and LOGPRINTF.

Referenced by db_delete_entry(), and ermetadb_global_remove_file().

00408 {
00409     LOGPRINTF("id [%lld]  folder [%s]  file [%s]", file_id, filepath, filename);
00410 
00411     CHECK_GLOBAL
00412     g_assert(file_id > 0);
00413     g_assert(filepath && filepath[0]);
00414     g_assert(filename && filename[0]);
00415 
00416     int res = delete_entry(thiz, file_id);
00417 
00418     if (!is_dir) { // for a dir, there is no metadata
00419         delete_local_metadata(filepath, filename);
00420     }
00421 
00422     return res;
00423 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_remove_file ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename 
)

Remove a document from the global AND local database.

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

Name : ermetadb_global_remove_file

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path for the document
[in] filename - filename of the document
Returns:
ER_OK or error code ER_OK when filename with filepath not present in database

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

Definition at line 372 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_NOT_FOUND, ermetadb_global_remove_entry(), get_global_id(), ISDIR_DOCUMENT, and LOGPRINTF.

Referenced by delete_item_from_db().

00373 {
00374     LOGPRINTF("folder [%s]  file [%s]", filepath, filename);
00375 
00376     CHECK_GLOBAL
00377     g_assert(filepath && filepath[0]);
00378     g_assert(filename && filename[0]);
00379 
00380     gint64 file_id = get_global_id (thiz, filename, filepath, ISDIR_DOCUMENT);
00381     if (file_id == -1) return ER_NOT_FOUND;
00382 
00383     return ermetadb_global_remove_entry(thiz, file_id, filepath, filename, FALSE);
00384 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_remove_folder ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename 
)

Remove a folder from the metadata database.

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

Name : ermetadb_global_remove_folder

NOTE: does NOT remove local metadata. Not a problem, since complete directory is deleted anyway.

Parameters:
[in] thiz - erMetadb object
[in] filepath - path of the folder
[in] filename - filename of the folder
Returns:
ER_OK or error code ER_OK when foldername not present in database

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

Definition at line 341 of file ermetadb_file.c.

References CHECK_GLOBAL, delete_entry(), ER_FAIL, ER_NOT_FOUND, ER_OK, get_global_id(), ISDIR_FOLDER, LOGPRINTF, sql3_begin_transaction(), sql3_commit_or_rollback(), and sql3_execute_query().

Referenced by delete_item_from_db().

00342 {
00343     LOGPRINTF("folder [%s]  file [%s]", filepath, filename);
00344 
00345     CHECK_GLOBAL
00346     g_assert(filepath && filepath[0]);
00347     g_assert(filename && filename[0]);
00348 
00349     gint64 file_id = get_global_id (thiz, filename, filepath, ISDIR_FOLDER);
00350     if (file_id == -1) return ER_NOT_FOUND;
00351 
00352     // delete all underlying entries with trumbnails (and metadata)
00353     int ret = sql3_begin_transaction(thiz);
00354     if (ret != ER_OK) return ER_FAIL;
00355 
00356     delete_entry(thiz, file_id);
00357 
00358     // Also delete items that are in the directory.
00359     // ASSUMES that directory is really deleted from FS, so local metadb info
00360     // will be deleted automatically
00361     // NOTE: thumbnail data is deleted by database trigger
00362     GString *sql = g_string_new("");
00363     g_string_printf(sql, "DELETE FROM file_metadata WHERE directory_path LIKE '%s/%s%%';", filepath, filename);
00364     ret = sql3_execute_query(thiz->database, sql->str, NULL, NULL);
00365     g_string_free(sql, TRUE);
00366 
00367     ret = sql3_commit_or_rollback(thiz, ret);
00368     return ret;
00369 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_rename_file ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename,
const gchar *  new_filename,
const gchar *  new_title 
)

Renames a file to another name.

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

Name : ermetadb_global_rename_file

Parameters:
[in] thiz - erMetadb object
[in] filepath - directory_path for the document
[in] filename - old filename of the document
[in] new_filename - new filename of the document
[in] new_title- new title of the document
Returns:
ER_OK or error code ER_OK when filename with filepath not present in database

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

Definition at line 279 of file ermetadb_file.c.

References CHECK_GLOBAL, LOGPRINTF, sql3_commit_or_rollback(), and sql3_execute_query().

00284 {
00285     LOGPRINTF("folder [%s]  file [%s->%s]", filepath, filename, new_filename);
00286 
00287     CHECK_GLOBAL;
00288     g_assert(filepath && filepath[0]);
00289     g_assert(filename && filename[0]);
00290     g_assert(new_filename && new_filename[0]);
00291     g_assert(new_title && new_title[0]);
00292 
00293     char *sql_path    = sqlite3_mprintf("%Q", filepath);
00294     char *sql_srcfile = sqlite3_mprintf("%Q", filename);
00295     char *sql_dstfile = sqlite3_mprintf("%Q", new_filename);
00296     char *sql_title   = sqlite3_mprintf("%Q", new_title);
00297 
00298     // in case of overwrite: first delete old occurence, case-insensitive!
00299     GString *delq = g_string_new("");
00300     g_string_printf(delq , "DELETE FROM file_metadata "
00301                            " WHERE filename LIKE %s" 
00302                            " AND directory_path = %s",
00303                      sql_dstfile,
00304                      sql_path);
00305     (void) sql3_execute_query(thiz->database, delq->str, NULL, NULL);
00306     g_string_free(delq, TRUE);
00307 
00308     GString *sql = g_string_new("");
00309     g_string_printf( sql, "UPDATE file_metadata SET"
00310                           " filename = %s"
00311                           " , title = %s"
00312                           " WHERE filename = %s"
00313                           " AND directory_path = %s",
00314                      sql_dstfile,
00315                      sql_title,
00316                      sql_srcfile,
00317                      sql_path);
00318     int ret = sql3_execute_query(thiz->database, sql->str, NULL, NULL);
00319 
00320     g_string_free(sql, TRUE);
00321     sqlite3_free( sql_path );
00322     sqlite3_free( sql_srcfile );
00323     sqlite3_free( sql_dstfile );
00324     sqlite3_free( sql_title );
00325 
00326     ret = sql3_commit_or_rollback(thiz, ret);
00327     return ret;
00328 }

Here is the call graph for this function:

int ermetadb_global_select_all ( erMetadb  thiz,
metadata_table **  values_tbl 
)

Returns the contents of the file_metadata table.

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

Name : ermetadb_global_select_all

Parameters:
[in] thiz - erMetadb object
[out] values_tbl - tables with all the results
Returns:
ER_OK or error code

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

Definition at line 722 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_INVALID_PARAMETER, ER_OK, ERRORPRINTF, LOGPRINTF, and sql3_execute_query().

Referenced by db_get_model().

00723 {
00724     LOGPRINTF("entry");
00725 
00726     CHECK_GLOBAL
00727     g_return_val_if_fail( (values_tbl && *values_tbl == NULL), ER_INVALID_PARAMETER );
00728 
00729     const char* sql = "SELECT file_id,"
00730                       " filename,"
00731                       " directory_path,"
00732                       " is_directory,"
00733                       " file_size,"
00734                       " file_time_modified"
00735                       " FROM file_metadata";
00736     metadata_table *result = NULL;
00737     int ret = sql3_execute_query(thiz->database, sql, NULL, &result);
00738     if (ret != ER_OK)
00739     {
00740         ERRORPRINTF("cannot get filenames");
00741     }
00742 
00743     *values_tbl = result;
00744     return ret;
00745 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_select_files ( erMetadb  thiz,
const gchar *  sort_key,
gboolean  sort_is_ascending,
const metadata_table names_tbl,
metadata_table **  values_tbl,
const gchar *  tag_filter 
)

Get selected file_metadata fields for a group of files/folders sorted on (1) specified metadata field and (2) filename ascending This function mainly exists for content browser assistance.

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

Name : ermetadb_global_select_files

Parameters:
[in] thiz - erMetadb object
[in] sort_key - metadata field to sort on or NULL when no sort required (i.e. sort on filename only)
[in] sort_is_ascending - sorting order
[in] start_item - index (0 ..) of the first item from the selection to be returned
[in] num_items - maximum number of items to be returned or -1 for unlimited number of items
[in] names_tbl - metadata_table holding metadata names
[out] values_tbl - metadata_table holding metadata names and values one row per file or folder or NULL on error Caller must use metadata_table_free() to release this table.
[in] tag_filter - tag filter to be used or NULL
Returns:
ER_OK or error code

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

Definition at line 815 of file ermetadb_file.c.

References global_select_common(), and LOGPRINTF.

Referenced by db_query_execute().

00821 {
00822     LOGPRINTF("tag_filter [%s]", tag_filter);
00823 
00824     char extra_sql[128];
00825     extra_sql[0] = 0;
00826     if (tag_filter) sprintf(extra_sql, "WHERE tag = '%s'", tag_filter);
00827     int ret = global_select_common(thiz, 
00828                                    sort_key, 
00829                                    sort_is_ascending, 
00830                                    0,
00831                                    names_tbl,
00832                                    values_tbl,
00833                                    extra_sql);
00834     return ret;
00835 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_select_recent ( erMetadb  thiz,
const gchar *  sort_key,
int  num_items,
const metadata_table names_tbl,
metadata_table **  values_tbl 
)

Definition at line 838 of file ermetadb_file.c.

References global_select_common(), and LOGPRINTF.

Referenced by db_query_execute_recent().

00843 {
00844     LOGPRINTF("entry");
00845 
00846     int ret = global_select_common(thiz, 
00847                                    sort_key, 
00848                                    FALSE, 
00849                                    num_items,
00850                                    names_tbl,
00851                                    values_tbl,
00852                                    "WHERE tag != ''");
00853     return ret;
00854 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_select_search ( erMetadb  thiz,
const gchar *  sort_key,
gboolean  sort_is_ascending,
const metadata_table names_tbl,
metadata_table **  values_tbl,
const gchar *  search_filter 
)

Definition at line 881 of file ermetadb_file.c.

References global_select_common(), and LOGPRINTF.

Referenced by db_query_execute_search_filter().

00887 {
00888     LOGPRINTF("search_filter [%s]", search_filter);
00889 
00890     g_assert(search_filter && search_filter[0]);
00891 
00892     char sql[1024];
00893     sprintf(sql, "WHERE (filename LIKE '%%%s%%' or"
00894                             " title LIKE '%%%s%%' or"
00895                             " author LIKE '%%%s%%') AND tag != ''",
00896                             search_filter, search_filter, search_filter);
00897     int ret = global_select_common(thiz, 
00898                                    sort_key, 
00899                                    sort_is_ascending, 
00900                                    0,
00901                                    names_tbl,
00902                                    values_tbl,
00903                                    sql);
00904     return ret;
00905 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_select_subdir ( erMetadb  thiz,
const gchar *  sort_key,
gboolean  sort_is_ascending,
const metadata_table names_tbl,
metadata_table **  values_tbl,
const gchar *  path_filter 
)

Definition at line 857 of file ermetadb_file.c.

References global_select_common(), and LOGPRINTF.

Referenced by db_query_execute_path_filter().

00863 {
00864     LOGPRINTF("path_filter [%s]", path_filter);
00865 
00866     g_assert(path_filter && path_filter[0]);
00867 
00868     char sql[256];
00869     sprintf(sql, " WHERE directory_path = '%s'", path_filter);
00870     int ret = global_select_common(thiz, 
00871                                    sort_key, 
00872                                    sort_is_ascending, 
00873                                    0,
00874                                    names_tbl,
00875                                    values_tbl,
00876                                    sql);
00877     return ret;
00878 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_update_size ( erMetadb  thiz,
gint64  file_id,
gint64  last_modified,
gint64  filesize 
)

Updates size and last modified fields of entry.

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

Name : ermetadb_global_update_size

Parameters:
[in] thiz - erMetadb object
[in] file_id - db id of entry
[in] last_modified - when file was last modified
[in] filesize - size of file
Returns:
ER_OK or error code

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

Definition at line 564 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_NOT_FOUND, ER_OK, LOGPRINTF, and sql3_execute_query().

Referenced by db_update_entry().

00568 {
00569     LOGPRINTF("id [%lld]", file_id);
00570 
00571     CHECK_GLOBAL
00572     g_assert(file_id > 0);
00573 
00574     char query[255];
00575     snprintf(query, sizeof(query),
00576         "Update file_metadata SET file_size=%lld, file_time_modified=%lld WHERE file_id = %lld;",
00577         filesize, last_modified, file_id);
00578     if (!sql3_execute_query(thiz->database, query, NULL, NULL)) {
00579         return ER_NOT_FOUND;
00580     }
00581     return ER_OK;
00582 }

Here is the call graph for this function:

Here is the caller graph for this function:

int ermetadb_global_update_title ( erMetadb  thiz,
gint64  file_id,
const gchar *  title,
const gchar *  author 
)

Updates title and author fields of entry.

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

Name : ermetadb_global_update_title

Parameters:
[in] thiz - erMetadb object
[in] file_id - db id of entry
[in] title - title field. cannot be NULL
[in] author - author field. cannot be NULL
Returns:
ER_OK or error code

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

Definition at line 585 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_NOT_FOUND, ER_OK, LOGPRINTF, and sql3_execute_query().

Referenced by db_update_shortcut_entry().

00589 {
00590     LOGPRINTF("id [%lld]", file_id);
00591 
00592     CHECK_GLOBAL
00593     g_assert(file_id > 0);
00594     g_assert(title);
00595     g_assert(author);
00596 
00597     char *sql3_title = sqlite3_mprintf("%Q", title);
00598     char *sql3_author = sqlite3_mprintf("%Q", author);
00599     char query[255];
00600     snprintf(query, sizeof(query),
00601         "Update file_metadata SET title=%s, author=%s WHERE file_id = %lld;",
00602         sql3_title, sql3_author, file_id);
00603     sqlite3_free(sql3_title);
00604     sqlite3_free(sql3_author);
00605 
00606     if (!sql3_execute_query(thiz->database, query, NULL, NULL)) {
00607         return ER_NOT_FOUND;
00608     }
00609     return ER_OK;
00610 }

Here is the call graph for this function:

Here is the caller graph for this function:

const char* g_extension_pointer ( const char *  path  ) 

g_extension_pointer: : A filename or file path.

Extracts the extension from the end of a filename (the part after the final '.' in the filename).

Returns: A pointer to the extension part of the filename, or a pointer to the end of the string if the filename does not have an extension.

Definition at line 96 of file ermetadb_file.c.

Referenced by activate_shortcut(), add_filename(), get_tag_for_file(), get_thumbnail_for_shortcut(), ignore_thumbnail_generation(), is_shortcut_file(), and read_directory().

00097 {
00098    char * s, * t;
00099 
00100    g_return_val_if_fail(path != NULL, NULL);
00101 
00102    /* get the dot in the last element of the path */
00103    t = strrchr(path, G_DIR_SEPARATOR);
00104    if (t != NULL)
00105       s = strrchr(t, '.');
00106    else
00107       s = strrchr(path, '.');
00108 
00109    if (s == NULL)
00110       return path + strlen(path); /* There is no extension. */
00111    else {
00112       ++s;      /* pass the . */
00113       return s;
00114    }
00115 }

Here is the caller graph for this function:

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

Definition at line 613 of file ermetadb_file.c.

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

Referenced by ermetadb_global_get_file(), and global_select_common().

00614 {
00615     GString *columns = g_string_new("");
00616     int n_cols = metadata_table_n_columns(names_tbl);
00617     int col;
00618     for (col = 0 ; col < n_cols ; col++)
00619     {
00620         const metadata_cell *cell = metadata_table_get_cell(names_tbl, col);
00621         if (cell && cell->name && cell->name->str)
00622         {
00623             if (columns->len > 0)
00624             {
00625                 g_string_append(columns, ", ");
00626             }
00627             g_string_append(columns, cell->name->str);
00628         }
00629     }
00630     return columns;
00631 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gint64 get_global_id ( erMetadb  thiz,
const gchar *  filename,
const gchar *  filepath,
const is_directory_value  is_dir 
) [static]

Definition at line 118 of file ermetadb_file.c.

References ER_OK, ERRORPRINTF, ISDIR_DOCUMENT, ISDIR_DONT_CARE, ISDIR_FOLDER, METADATA_INT64, metadata_table_free, metadata_table_get_cell(), sql3_execute_query(), TRACE, metadata_cell::type, metadata_cell::v_int64, and metadata_cell::value.

Referenced by ermetadb_global_get_file(), ermetadb_global_remove_file(), ermetadb_global_remove_folder(), and set_file_metadata_impl().

00122 {
00123     TRACE( "entry: filename [%s] filepath [%s] is_dir [%d]",
00124                filename, filepath, is_dir );
00125 
00126     // build query
00127     GString *sql = g_string_new("");
00128     char *sql3_filename = sqlite3_mprintf("%Q", filename);
00129     char *sql3_dirpath  = sqlite3_mprintf("%Q", filepath);
00130     g_string_printf( sql, "SELECT file_id FROM file_metadata"
00131                           " WHERE filename = %s"
00132                             " AND directory_path = %s",
00133                      sql3_filename,
00134                      sql3_dirpath  );
00135     sqlite3_free( sql3_dirpath  );
00136     sqlite3_free( sql3_filename );
00137 
00138     switch (is_dir)
00139     {
00140         case ISDIR_DOCUMENT:
00141             g_string_append(sql, " AND is_directory = 0");
00142             break;
00143         case ISDIR_FOLDER:
00144             g_string_append(sql, " AND is_directory = 1");
00145             break;
00146         case ISDIR_DONT_CARE:
00147             // ignore
00148             break;
00149     }
00150     g_string_append(sql, " ORDER BY file_id LIMIT 1;");
00151 
00152     // execute query
00153     metadata_table *result = NULL;
00154     int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00155     gint64 file_id = -1;
00156     if (rc == ER_OK  &&  result)
00157     {
00158         // filename present: get file_id
00159         const metadata_cell *cell = metadata_table_get_cell(result, 0);
00160         if (cell->type != METADATA_INT64)
00161         {
00162             ERRORPRINTF( "filename [%s] invalid file_id type [%d] from database",
00163                          filename, cell->type );
00164         }
00165         else
00166         {
00167             file_id = cell->value.v_int64;
00168         }
00169     }
00170 
00171     metadata_table_free(result);
00172     g_string_free(sql, TRUE);
00173     return file_id;
00174 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int global_select_common ( erMetadb  thiz,
const gchar *  sort_key,
gboolean  sort_is_ascending,
long  num_items,
const metadata_table names_tbl,
metadata_table **  values_tbl,
const gchar *  extra_sql 
) [static]

Definition at line 748 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_NOT_FOUND, ER_OK, ERRORPRINTF, get_column_names(), sql3_execute_query(), and SQLITE_COLLATION_STRCASECMP.

Referenced by ermetadb_global_select_files(), ermetadb_global_select_recent(), ermetadb_global_select_search(), and ermetadb_global_select_subdir().

00755 {
00756     CHECK_GLOBAL
00757     g_assert(extra_sql);
00758 
00759     // build query
00760     GString *columns = get_column_names(names_tbl);
00761     GString *sql = g_string_new("");
00762     g_string_printf(            sql, "SELECT %s FROM file_metadata AS m"
00763                                      " LEFT JOIN thumbnails AS t"
00764                                      " ON m.file_id = t.file_id"
00765                                      " %s "
00766                                      " ORDER BY"
00767                                      "  sort_priority DESC,"
00768                                      "  (CASE WHEN %s IS NOT NULL THEN 0 ELSE 1 END)",
00769                                 columns->str, extra_sql, sort_key);
00770     g_string_free(columns, TRUE);
00771 
00772     if (sort_key)
00773     {
00774         g_string_append_printf( sql, ", %s", sort_key);
00775 
00776         if (   strcmp(sort_key, "filename") == 0
00777             || strcmp(sort_key, "title"   ) == 0
00778             || strcmp(sort_key, "author"  ) == 0 )
00779         {
00780             g_string_append(    sql, " COLLATE " SQLITE_COLLATION_STRCASECMP );
00781         }
00782         g_string_append(        sql, sort_is_ascending ? " ASC" : " DESC" );
00783 
00784         if ( strcmp(sort_key, "filename") != 0 )
00785         {
00786             g_string_append(    sql, ", filename COLLATE " SQLITE_COLLATION_STRCASECMP " ASC" );
00787         }
00788         g_string_append(        sql, ", directory_path COLLATE " SQLITE_COLLATION_STRCASECMP " ASC" );
00789     }
00790 
00791     if (num_items > 0)
00792     {
00793         g_string_append_printf( sql, " LIMIT %ld",
00794                                 num_items );
00795     }
00796 
00797     g_string_append(            sql, ";" );
00798 
00799     // execute query
00800     metadata_table *result = NULL;
00801     int rc = sql3_execute_query(thiz->database, sql->str, NULL, &result);
00802     if (rc != ER_OK)
00803     {
00804         ERRORPRINTF("cannot get metadata, sql [%s]", sql->str);
00805         rc = ER_NOT_FOUND;
00806     }
00807     g_string_free(sql, TRUE);
00808 
00809     *values_tbl = result;
00810     return rc;
00811 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_file_metadata_impl ( erMetadb  thiz,
const gchar *  filepath,
const gchar *  filename,
const metadata_table values_tbl 
) [static]

Definition at line 426 of file ermetadb_file.c.

References CHECK_GLOBAL, ER_INVALID_PARAMETER, ER_NOT_FOUND, ER_OK, ermetadb_private_get_global_column_names(), ERRORPRINTF, get_global_id(), ISDIR_DONT_CARE, metadata_table_get_cell(), metadata_table_n_columns, metadata_table_n_rows, name, metadata_cell::name, sql3_begin_transaction(), sql3_commit_or_rollback(), sql3_execute_query(), and TRACE.

Referenced by ermetadb_global_change_file().

00430 {
00431     TRACE("entry");
00432 
00433     CHECK_GLOBAL
00434     g_assert(filepath && filepath[0]);
00435     g_assert(filename && filename[0]);
00436     g_return_val_if_fail(  values_tbl                             , ER_INVALID_PARAMETER );
00437     g_return_val_if_fail( (metadata_table_n_rows(values_tbl) == 1), ER_INVALID_PARAMETER );
00438 
00439     gint64 file_id = get_global_id(thiz, filename, filepath, ISDIR_DONT_CARE);
00440     if (file_id < 0) return ER_NOT_FOUND;
00441 
00442     int ret = sql3_begin_transaction(thiz);
00443     if (ret != ER_OK) return ret;
00444 
00445     // build sql query per table
00446     GString *sql_m = g_string_new("");  // SQL query to update file_metadata
00447     GString *sql_t = g_string_new("");  // SQL query to update thumbnails
00448 
00449     const char* const *names_m = ermetadb_private_get_global_column_names("file_metadata");
00450     g_assert(names_m);
00451     const char* const *names_t = ermetadb_private_get_global_column_names("thumbnails"   );
00452     g_assert(names_t);
00453 
00454     int n_cols = metadata_table_n_columns(values_tbl);
00455     int col;
00456     for (col = 0 ; col < n_cols ; col++)
00457     {
00458         const metadata_cell *cell = metadata_table_get_cell(values_tbl, col);
00459         if (cell && cell->name && cell->name->str)
00460         {
00461             const gchar *cell_name = cell->name->str;
00462 
00463             // find column in file_metadata
00464             gboolean found = FALSE;
00465             const char* const *name;
00466             for (name = names_m ; *name && !found ; name++)
00467             {
00468                 if (strcmp(cell_name, *name) == 0)
00469                 {
00470                     found = TRUE;
00471                 }
00472             }
00473             if (found)
00474             {
00475                 if (sql_m->len == 0)
00476                 {
00477                     g_string_assign(sql_m, "UPDATE file_metadata SET ");
00478                 }
00479                 else
00480                 {
00481                     g_string_append(sql_m, ", ");
00482                 }
00483                 g_string_append_printf(sql_m, "%s = ?%d", cell_name, col + 1);
00484             }
00485 
00486             // find column in thumbnails
00487             found = FALSE;
00488             for (name = names_t ; *name && !found ; name++)
00489             {
00490                 if (strcmp(cell_name, *name) == 0)
00491                 {
00492                     found = TRUE;
00493                 }
00494             }
00495             if (found)
00496             {
00497                 if (sql_t->len == 0)
00498                 {
00499                     g_string_printf( sql_t, "INSERT OR IGNORE INTO thumbnails (file_id) VALUES (%lld);"
00500                                             "UPDATE thumbnails SET ",
00501                                      file_id );
00502                 }
00503                 else
00504                 {
00505                     g_string_append(sql_t, ", ");
00506                 }
00507                 g_string_append_printf(sql_t, "%s = ?%d", cell_name, col + 1);
00508             }
00509         }
00510     }
00511     if (sql_m->len > 0)
00512     {
00513         g_string_append_printf(sql_m, " WHERE file_id = %lld;", file_id);
00514     }
00515     if (sql_t->len > 0)
00516     {
00517         g_string_append_printf(sql_t, " WHERE file_id = %lld;", file_id);
00518     }
00519 
00520     // execute query on file_metadata
00521     if (ret == ER_OK  &&  sql_m->len > 0)
00522     {
00523         int rc = sql3_execute_query(thiz->database, sql_m->str, values_tbl, NULL);
00524         if (rc != ER_OK)
00525         {
00526             ERRORPRINTF("cannot set file_metadata, sql [%s]", sql_m->str);
00527             ret = ER_NOT_FOUND;
00528         }
00529     }
00530 
00531     // execute query on thumbnails
00532     if (ret == ER_OK  &&  sql_t->len > 0)
00533     {
00534         int rc = sql3_execute_query(thiz->database, sql_t->str, values_tbl, NULL);
00535         if (rc != ER_OK)
00536         {
00537             ERRORPRINTF("cannot set thumbnails, sql [%s]", sql_t->str);
00538             ret = ER_NOT_FOUND;
00539         }
00540     }
00541 
00542     // commit changes to database
00543     ret = sql3_commit_or_rollback(thiz, ret);
00544 
00545     // clean up
00546     g_string_free(sql_t, TRUE);
00547     g_string_free(sql_m, TRUE);
00548 
00549     return ret;
00550 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const gchar* FILE_METADATA_DIRPATH_DEFAULT = "." [static]

Definition at line 77 of file ermetadb_file.c.

Referenced by add_filename().

Generated by  doxygen 1.6.2-20100208