00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 #include <glib.h>
00035 #include <string.h>
00036 
00037 
00038 #include <liberutils/er_error.h>
00039 
00040 
00041 #include "ermetadb_log.h"
00042 #include "ermetadb.h"
00043 #include "ermetadb_error.h"
00044 #include "ermetadb_private.h"
00045 #include "sqlite3_wrapper.h"
00046 
00047 #define LOCAL_MAX_COLUMNS  12
00048 static const struct
00049              {
00050                  const char     *table_name;
00051                  const char     *column_names[LOCAL_MAX_COLUMNS+1];
00052              } local_database_tables[]
00053              =
00054              {
00055                 {
00056                     "application_data",
00057                     {
00058                         "file_id",
00059                         "key",
00060                         "value",
00061                          NULL
00062                     }
00063                 },
00064                 { 
00065                     "annotations",
00066                     {
00067                         "annotation_id",
00068                         "file_id",
00069                         "annotation_type",
00070                         "layer",
00071                         "file_position",
00072                         "title",
00073                         "start_anchor",
00074                         "end_anchor",
00075                         "data",
00076                         NULL
00077                     }
00078                 },
00079                 { 
00080                     "file_metadata",
00081                     {
00082                         "file_id",
00083                         "filename",
00084                         NULL
00085                     }
00086                 },
00087                 {
00088                     NULL,
00089                     {}
00090                 }
00091              };
00092 
00093 #define CHECK_LOCAL \
00094     g_assert(thiz); \
00095     g_assert(thiz->database); \
00096     g_assert(!thiz->is_global);
00097 
00098 
00099 
00100 
00101 
00102 
00103 static const char* const * get_local_column_names(const char* table)
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 }
00118 
00119 
00120 static gint64 get_local_id(erMetadb thiz, const char* filename)
00121 {
00122     
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 }
00139 
00140 
00141 int ermetadb_local_remove_annotation (erMetadb thiz, const gint64 annotation_id)
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 }
00157 
00158 
00159 
00160 static int set_annotation_impl (erMetadb        thiz,
00161                                 const gint64    annotation_id,
00162                                 const gchar     *annotation_type,
00163                                 const gchar     *layer,
00164                                 const gint64    file_position,
00165                                 const gchar     *title,
00166                                 const gchar     *start_anchor,
00167                                 const gchar     *end_anchor,
00168                                 const gchar     *data_blob,
00169                                 const guint     data_len )
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     
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         
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         
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         
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         
00245         g_string_append(        sql, "NULL" );
00246     }
00247 
00248     g_string_append_printf( sql, " WHERE annotation_id = %lld;",
00249                             annotation_id );
00250 
00251     
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 }
00262 
00263 
00264 static gint64 find_or_create_filename(erMetadb thiz, const char* filename)
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 }
00280 
00281 
00282 int ermetadb_local_create_annotation (erMetadb     thiz,
00283                                       const gchar  *filename,
00284                                       gint64       *annotation_id,
00285                                       const gchar  *annotation_type,
00286                                       const gchar  *layer,
00287                                       const gint64 file_position,
00288                                       const gchar  *title,
00289                                       const gchar  *start_anchor,
00290                                       const gchar  *end_anchor,
00291                                       const gchar  *data_blob,
00292                                       const guint  data_len )
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     
00312     
00313     GString *sql = g_string_new("");  
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     
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         
00329         anno_id = sqlite3_last_insert_rowid(thiz->database);
00330     }
00331     g_string_free(sql, TRUE);
00332 
00333     
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 }
00353 
00354 
00355 int ermetadb_local_set_annotation (erMetadb      thiz,
00356                                    const gint64  annotation_id,
00357                                    const gchar   *annotation_type,
00358                                    const gchar   *layer,
00359                                    const gint64  file_position,
00360                                    const gchar   *title,
00361                                    const gchar   *start_anchor,
00362                                    const gchar   *end_anchor,
00363                                    const gchar   *data_blob,
00364                                    const guint   data_len )
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 }
00388 
00389 
00390 
00391 int ermetadb_local_get_annotations (erMetadb       thiz,
00392                                     const gint64   *annotation_id_list,
00393                                     long           annotation_id_num,
00394                                     metadata_table **values_tbl        )
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     
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     
00421     const gint64 *p_anno = annotation_id_list;
00422     GString *sql = g_string_new("");  
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     
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     
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 }
00454 
00455 
00456 
00457 int ermetadb_local_select_annotations (erMetadb        thiz,
00458                                        const gchar     *filename,
00459                                        const gchar     *annotation_type,
00460                                        const gchar     *layer,
00461                                        const gint64    file_position_min,
00462                                        const gint64    file_position_max,
00463                                        metadata_table  **values_tbl )
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     
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     
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     
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 }
00529 
00530 
00531 static int local_delete_all_annotations (erMetadb thiz, gint64 file_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 }
00543 
00544 
00545 static GString *get_keys(const metadata_table *names_tbl)
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 }
00567 
00568 
00569 int ermetadb_local_remove_application_data (erMetadb             thiz,
00570                                             const gchar          *filename,
00571                                             const metadata_table *names_tbl )
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     
00584     int ret = sql3_begin_transaction(thiz);
00585     if (ret != ER_OK) return ret;
00586 
00587     
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 }
00607 
00608 
00609 int ermetadb_local_set_application_data (erMetadb             thiz,
00610                                          const gchar          *filename,
00611                                          const metadata_table *values_tbl )
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     
00627     GString *sql_del = NULL;     
00628     GString *sql_ins   = NULL;     
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                 
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                 
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     
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     
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 }
00702 
00703 
00704 
00705 
00706 
00707 static metadata_table* rotate_keyval_table(const metadata_table *table)
00708 {
00709     
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     
00717     metadata_table *rotated = metadata_table_new();
00718 
00719     
00720     int key_index;
00721     gboolean ok = TRUE;
00722     for (key_index = 0 ; key_index < n_keys ; key_index++)
00723     {
00724         
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         
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 }
00766 
00767 
00768 int ermetadb_local_get_application_data (erMetadb             thiz,
00769                                          const gchar          *filename,
00770                                          const metadata_table *names_tbl,
00771                                          metadata_table       **values_tbl )
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     
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     
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     
00808     ret = sql3_commit_or_rollback(thiz, ret);
00809 
00810     
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 }
00821 
00822 
00823 static int local_delete_all_application_data (erMetadb thiz, gint64 file_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 }
00836 
00837 
00838 static int local_delete_entry(erMetadb thiz, gint64 file_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 }
00844 
00845 
00846 int local_delete_all_data_for_file(erMetadb thiz, const char* filename)
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 }
00855 
00856 
00857 int local_delete_all_data_for_id(erMetadb thiz, gint64 file_id)
00858 {
00859     g_assert(!thiz->is_global);
00860 
00861     int ret = sql3_begin_transaction(thiz);
00862     if (ret != ER_OK) return ret;
00863 
00864     
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 }
00873