index_db.c
Go to the documentation of this file.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 #include "config.h"
00028 #include <unistd.h>
00029 #include <stdlib.h>
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 
00033 #include "log.h"
00034 #include "index_db.h"
00035 
00036 
00037 #define MAX_WAIT_DATABASE (30)
00038 
00039 
00040 int db_open_global (db_state_t *db_state, const gchar *directory)
00041 {
00042     LOGPRINTF("entry: dir [%s]", directory);
00043     
00044     db_state->mdb = NULL;
00045     db_state->transaction_started = FALSE;
00046     db_state->values = NULL;
00047     db_state->db = NULL;
00048     db_state->num_rows = 0;
00049     db_state->num_cols = 0;
00050     db_state->row = 0;
00051 
00052     erMetadb db = ermetadb_global_open(directory, FALSE);
00053     if (db == NULL) {
00054         ERRORPRINTF("failed to open database in %s.", directory);
00055         return ER_FAIL;
00056     }
00057     
00058     db_state->mdb = db;
00059     return ER_OK;
00060 }
00061 
00062 
00063 void db_close (db_state_t *db_state)
00064 {
00065     LOGPRINTF("entry");
00066 
00067     if (db_state->mdb)
00068     {
00069         ermetadb_close(db_state->mdb);
00070         db_state->mdb = NULL;
00071     }
00072 }
00073 
00074 
00075 int db_start_transaction (db_state_t *db_state)
00076 {
00077     int           ret = ER_OK;    
00078     const time_t  start = time(NULL);
00079 
00080     LOGPRINTF("entry");
00081 
00082     if (db_state->mdb)
00083     {
00084         if (db_state->transaction_started)
00085             WARNPRINTF("transaction already started");
00086         ret = ermetadb_begin_transaction(db_state->mdb);
00087         if (ret == ERMETADB_DATABASE_BUSY)
00088         {
00089             
00090             while ((ret == ERMETADB_DATABASE_BUSY) &&
00091                    (time(NULL) - start) <= MAX_WAIT_DATABASE )
00092             {
00093                 WARNPRINTF("database locked");
00094                 ret = ermetadb_begin_transaction(db_state->mdb);
00095             }
00096         }
00097     }
00098 
00099     db_state->transaction_started = TRUE;
00100 
00101     return ret;
00102 }
00103 
00104 
00105 int db_end_transaction (db_state_t *db_state)
00106 {
00107     int  ret = ER_OK;    
00108 
00109     LOGPRINTF("entry");
00110 
00111     if (db_state->transaction_started && db_state->mdb)
00112     {
00113         ret = ermetadb_end_transaction(db_state->mdb);
00114         db_state->transaction_started = FALSE;
00115     }
00116 
00117     return ret;
00118 }
00119 
00120 
00121 void db_update_entry(db_state_t *db_state, const db_entry_t* entry)
00122 {
00123     ermetadb_global_update_size(db_state->mdb, entry->file_id, entry->last_modified, entry->filesize);
00124 }
00125 
00126 
00127 void db_update_shortcut_entry(db_state_t *db_state, const db_entry_t* entry, const char* display_name, const char* author)
00128 {
00129     ermetadb_global_update_title(db_state->mdb, entry->file_id, display_name, author);
00130 }
00131 
00132 
00133 void db_add_entry(db_state_t *db_state, const db_entry_t* entry, const char* tag, const char* display_name, const char* author)
00134 {
00135     if (entry->is_dir) {
00136         ermetadb_global_add_folder(db_state->mdb,
00137                                    entry->filepath,
00138                                    entry->filename,
00139                                    entry->last_modified);
00140     } else {
00141         if (display_name == NULL) display_name = entry->filename;
00142         ermetadb_global_add_file(db_state->mdb,
00143                                  entry->filepath,
00144                                  entry->filename,
00145                                  entry->filesize,
00146                                  entry->last_modified,
00147                                  display_name,
00148                                  author,
00149                                  tag);
00150     }
00151 }
00152 
00153 
00154 int db_delete_entry(db_state_t *db_state, const db_entry_t *entry)
00155 {
00156     
00157     return ermetadb_global_remove_entry(db_state->mdb,
00158                                         entry->file_id,
00159                                         entry->filepath,
00160                                         entry->filename,
00161                                         entry->is_dir);
00162 }
00163 
00164 
00165 static db_entry_t* row2entry(const metadata_cell *row)
00166 {
00167     
00168     db_entry_t* entry = g_malloc(sizeof(db_entry_t));
00169     memset(entry, 0, sizeof(db_entry_t));
00170 
00171     const metadata_cell *cell = row;
00172     gint64 file_id = cell->value.v_int64;
00173     entry->file_id = file_id;
00174 
00175     cell++;
00176     char* filename = cell->value.v_text->str;
00177     entry->filename = filename;
00178 
00179     cell++;
00180     char* filepath = cell->value.v_text->str;
00181     entry->filepath = filepath;
00182 
00183     cell++;
00184     gboolean is_dir = cell->value.v_int64;
00185     entry->is_dir = is_dir;
00186 
00187     cell++;
00188     gint64 size = cell->value.v_int64;
00189     entry->filesize = size;
00190 
00191     cell++;
00192     gint64 filedate = cell->value.v_int64;
00193     entry->last_modified = filedate;
00194 
00195     return entry;
00196 }
00197 
00198 
00199 GSList* db_get_model(const gchar* dir)
00200 {
00201     db_state_t db_state;
00202     GSList* model = 0;
00203 
00204     if (db_open_global(&db_state, dir) != ER_OK) {
00205         ERRORPRINTF("error opening db");
00206         return NULL;
00207     }
00208 
00209     metadata_table *values = NULL;
00210 
00211     int ret = ermetadb_global_select_all(db_state.mdb, &values);
00212     if (ret != ER_OK) {
00213         ERRORPRINTF("error [%d]", ret);
00214         goto out;
00215     }
00216 
00217     int n_rows = metadata_table_n_rows(values);
00218     int n_cols = metadata_table_n_columns(values);
00219 
00220     const metadata_cell *row = (const metadata_cell*) (values->cell_data->data);
00221     for (int i=0; i<n_rows; i++) {
00222         db_entry_t* entry = row2entry(row);
00223         model = g_slist_prepend(model, entry);
00224         row += n_cols; 
00225     }
00226 
00227     model = g_slist_reverse(model);
00228     
00229     
00230     
00231 out:
00232     db_close(&db_state);
00233     return model;
00234 }
00235