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