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 <sys/time.h>
00029 #include <cstring>
00030 #include <gtk/gtk.h>
00031 #include <glib.h>
00032 #include <glib/gstdio.h>
00033 #include <libermetadb/ermetadb.h>
00034
00035 #include "log.h"
00036 #include "notepad_ipc.h"
00037 #include "notepad_utils.h"
00038 #include "notepad_filestore.h"
00039
00040 #define NOTE_AUTHOR "Notepad"
00041 #define NOTE_DIR "Notes"
00042 #define NOTE_TAG "note"
00043 #define NOTE_EXTENSION ".note"
00044
00045 namespace notepad
00046 {
00047
00048 static const char* SCRIBBLE_LAST_READ_LOCATION = "scribble_last_read_location";
00049
00050 CFileStore::CFileStore()
00051 :
00052 m_db(0),
00053 m_dbfilename(0)
00054 {
00055 LOGPRINTF("entry");
00056 LOGPRINTF("exit");
00057 }
00058
00059 CFileStore::~CFileStore()
00060 {
00061 LOGPRINTF("entry");
00062 closeDatabase();
00063 LOGPRINTF("exit");
00064 }
00065
00066 np_result CFileStore::openDatabase(const gchar* dir, const gchar* filename)
00067 {
00068 LOGPRINTF("entry");
00069 g_assert(m_db == 0 );
00070 g_return_val_if_fail((dir !=0) && (dir[0] != '\0'), NP_NO_FILENAME);
00071 g_return_val_if_fail((filename !=0) && (filename[0] != '\0'), NP_NO_FILENAME);
00072
00073 erMetadb db = ermetadb_local_open_custom(dir, filename);
00074 if (db == 0)
00075 {
00076 LOGPRINTF("opening file failed");
00077 return NP_CREATE_FAILED;
00078 }
00079 m_db = db;
00080
00081 LOGPRINTF("exit");
00082 return NP_OK;
00083 }
00084
00085 void CFileStore::closeDatabase(void)
00086 {
00087 LOGPRINTF("entry");
00088
00089 if (m_dbfilename) g_free(m_dbfilename);
00090 m_dbfilename = 0;
00091
00092 if (m_db)
00093 {
00094 ermetadb_close(m_db);
00095 m_db = 0;
00096 }
00097
00098 LOGPRINTF("exit");
00099 }
00100
00101 np_result CFileStore::createDatabase(const gchar* dir, const gchar* file, const char* title)
00102 {
00103 LOGPRINTF("entry");
00104
00105
00106 g_assert(m_db == 0);
00107
00108 g_return_val_if_fail((dir != 0) && (dir[0] != '\0'), NP_NO_FILENAME);
00109 g_return_val_if_fail((file != 0) && (file[0] != '\0'), NP_NO_FILENAME);
00110 g_return_val_if_fail((title != 0) && (title[0] != '\0'), NP_NO_FILENAME);
00111
00112 if ( ! g_file_test(dir, G_FILE_TEST_EXISTS) )
00113 {
00114 LOGPRINTF("dir %s did not exist, created", dir);
00115
00116 if (g_mkdir(dir, 0775) != 0)
00117 {
00118 WARNPRINTF("failed to create Notes directory.");
00119 return NP_IS_NOT_DIR;
00120 }
00121 }
00122
00123 if ( ! g_file_test(dir, G_FILE_TEST_IS_DIR))
00124 {
00125 LOGPRINTF("%s is no directory", dir);
00126 return NP_IS_NOT_DIR;
00127 }
00128
00129
00130
00131 int ret = ermetadb_local_create_database(dir, file);
00132 if (ret != ER_OK) {
00133 WARNPRINTF("ermetadb_new failed");
00134 return NP_CREATE_FAILED;
00135 }
00136
00137
00138 const char* mountpoint = ipc_get_mountpoint();
00139 erMetadb global_db = ermetadb_global_open(mountpoint, FALSE);
00140 if (global_db == 0) {
00141 WARNPRINTF("failed to open globaldb.");
00142 return NP_OPEN_FAILED;
00143 }
00144
00145
00146 struct stat statbuf;
00147 gchar* fname = g_strdup_printf("%s/%s", dir, file);
00148 stat(fname, &statbuf);
00149 gint64 size = statbuf.st_size;
00150 gint64 mtime = statbuf.st_mtime;
00151 LOGPRINTF("%s size %lld, mtime %lld", fname, size, mtime);
00152 g_free(fname);
00153
00154 ret = ermetadb_global_add_file(global_db, dir, file, size, mtime, title, NOTE_AUTHOR, NOTE_TAG);
00155 if (ret != ER_OK) {
00156 WARNPRINTF("ermetadb_add_file failed");
00157 }
00158
00159 ermetadb_close(global_db);
00160
00161 LOGPRINTF("exit");
00162 return openDatabase(dir, file);
00163 }
00164
00165 np_result CFileStore::renameDatabase(const gchar* dir, const gchar* srcfile, const gchar* destfile)
00166 {
00167 LOGPRINTF("entry");
00168
00169 g_assert(m_db != 0);
00170
00171 g_return_val_if_fail((dir != 0) && (dir[0] != '\0'), NP_NO_FILENAME);
00172 g_return_val_if_fail((srcfile != 0) && (srcfile[0] != '\0'), NP_NO_FILENAME);
00173 g_return_val_if_fail((destfile != 0) && (destfile[0] != '\0'), NP_NO_FILENAME);
00174
00175 LOGPRINTF("dir %s srcfile %s destfile %s", dir, srcfile, destfile);
00176
00177 if (0 == g_strcmp0(srcfile, destfile))
00178 {
00179 LOGPRINTF("same name, do nothing");
00180 return NP_OK;
00181 }
00182
00183
00184 gchar *dst = g_strdup_printf("%s/%s", dir, destfile);
00185 gchar *src = g_strdup_printf("%s/%s", dir, srcfile);
00186 int err = g_rename(src, dst);
00187 g_free(src);
00188 g_free(dst);
00189 if (err) {
00190 WARNPRINTF("rename failed.");
00191 return NP_RENAME_FAILED;
00192 }
00193
00194
00195 const char* mountpoint = ipc_get_mountpoint();
00196 erMetadb global_db = ermetadb_global_open(mountpoint, FALSE);
00197 if (global_db == 0) {
00198 WARNPRINTF("rename failed.");
00199 return NP_OPEN_FAILED;
00200 }
00201 gchar* title = noExt(destfile);
00202 int ret = ermetadb_global_rename_file(global_db, dir, srcfile, destfile, title);
00203
00204 g_free(title);
00205 ermetadb_close(global_db);
00206 if (ret != ER_OK) {
00207 WARNPRINTF("rename failed.");
00208 return NP_RENAME_FAILED;
00209 }
00210
00211 LOGPRINTF("exit success");
00212 return NP_OK;
00213 }
00214
00215 np_result CFileStore::createFile(const gchar* filename)
00216 {
00217 LOGPRINTF("filename='%s'", filename ? filename : "NULL");
00218
00219 g_assert(m_dbfilename == 0);
00220 g_assert(m_db == 0);
00221
00222
00223 gchar* dir = 0;
00224 gchar* file = 0;
00225 if ( (filename != 0) && (filename[0] != '\0'))
00226 {
00227 dir = g_path_get_dirname(filename);
00228 file = g_path_get_basename(filename);
00229 }
00230 else
00231 {
00232 dir = g_strdup_printf("%s/%s", ipc_get_mountpoint(), NOTE_DIR);
00233 file = generateNewFilename();
00234 }
00235
00236 gchar* title = 0;
00237 gchar* iter = g_strrstr(file, NOTE_EXTENSION);
00238 if ( iter == 0 )
00239 {
00240 title = g_strdup(file);
00241 }
00242 else
00243 {
00244 title = g_strndup(file, (iter - file));
00245 }
00246
00247 np_result result = createDatabase(dir, file, title);
00248 if (result == NP_OK)
00249 {
00250 m_dbfilename = g_strdup_printf("%s/%s", dir, file);
00251 }
00252 else
00253 {
00254 WARNPRINTF("failed to create");
00255 }
00256
00257 g_free(dir);
00258 g_free(file);
00259 g_free(title);
00260
00261 LOGPRINTF("exit");
00262 return result;
00263 }
00264
00265 np_result CFileStore::openFile(const gchar* filename)
00266 {
00267 LOGPRINTF("entry");
00268
00269 g_assert( m_dbfilename == 0);
00270 g_assert( m_db == 0);
00271
00272
00273 g_return_val_if_fail((filename != 0) && (filename[0] != '\0'), NP_NO_FILENAME);
00274
00275 gchar* directory = g_path_get_dirname(filename);
00276 gchar* file = g_path_get_basename(filename);
00277 np_result result = openDatabase(directory, file);
00278
00279 if ( result == NP_OK)
00280 {
00281 m_dbfilename = g_strdup(filename);
00282 }
00283 else
00284 {
00285 WARNPRINTF("failed to open");
00286 }
00287
00288 g_free(directory);
00289 g_free(file);
00290
00291 LOGPRINTF("exit");
00292 return result;
00293 }
00294
00295 void CFileStore::closeFile()
00296 {
00297 return closeDatabase();
00298 }
00299
00300 np_result CFileStore::renameFile(const gchar* newshortfilename)
00301 {
00302 LOGPRINTF("entry");
00303 np_result result = NP_OK;
00304
00305 g_assert( m_dbfilename != 0);
00306 g_assert( m_db != 0);
00307
00308
00309 g_return_val_if_fail((newshortfilename != 0) && (newshortfilename[0] != '\0'), NP_NO_FILENAME);
00310
00311
00312 gchar* dir = getFileNameDirPart();
00313 gchar* newfilename = 0;
00314 int len = strlen(newshortfilename) - strlen(NOTE_EXTENSION);
00315 if (0 == g_strcmp0(newshortfilename + len, NOTE_EXTENSION))
00316 {
00317 g_assert(len > 0);
00318 newfilename = g_strdup_printf("%s/%s", dir, newshortfilename);
00319 }
00320 else
00321 {
00322 newfilename = g_strdup_printf("%s/%s%s", dir, newshortfilename, NOTE_EXTENSION);
00323 }
00324 LOGPRINTF("oldfilename %s, newfilename %s", m_dbfilename, newfilename);
00325
00326
00327 if (0 == g_strcmp0(m_dbfilename, newfilename))
00328 {
00329 LOGPRINTF("save as same filename");
00330 result = NP_OK;
00331 }
00332 else
00333 {
00334
00335 if (g_file_test(newfilename, G_FILE_TEST_EXISTS))
00336 result = NP_FILE_EXISTS;
00337
00338 if (result != NP_FILE_EXISTS)
00339 {
00340 gchar* srcfile = getFileNameFilePart();
00341 gchar* destfile = g_path_get_basename(newfilename);
00342
00343
00344 result = renameDatabase(dir, srcfile, destfile);
00345 if (result == NP_OK)
00346 {
00347
00348 g_free(m_dbfilename);
00349 m_dbfilename = g_strdup(newfilename);
00350 }
00351 g_free(srcfile);
00352 g_free(destfile);
00353 }
00354 }
00355
00356 g_free(dir);
00357 g_free(newfilename);
00358
00359 LOGPRINTF("FUNCTION EXIT");
00360 return result;
00361 }
00362
00363 gchar* CFileStore::getFilename(void)
00364 {
00365
00366 return m_dbfilename;
00367 }
00368
00369 erMetadb CFileStore::getFile()
00370 {
00371 return m_db;
00372 }
00373
00374
00375 gchar* CFileStore::generateNewFilename(void)
00376 {
00377
00378 time_t rawtime;
00379 time(&rawtime);
00380 struct tm * tms;
00381 tms = localtime(&rawtime);
00382
00383 gchar* fname = g_strdup_printf("Note_%d-%02d-%02d__%02d-%02d-%02d%s",
00384 1900+tms->tm_year,
00385 1+tms->tm_mon,
00386 tms->tm_mday,
00387 tms->tm_hour,
00388 tms->tm_min,
00389 tms->tm_sec,
00390 NOTE_EXTENSION);
00391 return fname;
00392 }
00393
00394 gchar* CFileStore::noExt(const gchar* filename)
00395 {
00396 g_assert(filename != 0);
00397
00398 gchar* basename = g_path_get_basename(filename);
00399 gchar* iter = g_strrstr(basename, NOTE_EXTENSION);
00400 if (iter == 0)
00401 {
00402 return basename ;
00403 }
00404 gchar* basename_noext = g_strndup(basename, (iter - basename));
00405 g_free(basename);
00406 return basename_noext;
00407 }
00408
00409
00410 gchar* CFileStore::getFileNameDirPart(void)
00411 {
00412 g_assert( m_dbfilename != 0);
00413 return g_path_get_dirname(m_dbfilename);
00414 }
00415
00416
00417 gchar* CFileStore::getFileNameFilePart(void)
00418 {
00419 g_assert( m_dbfilename != 0);
00420 return g_path_get_basename(m_dbfilename);
00421 }
00422
00423
00424 gchar* CFileStore::getFileNameFilePartNoExt(void)
00425 {
00426 g_assert( m_dbfilename != 0);
00427 return noExt(m_dbfilename);
00428 }
00429
00430
00431
00432
00433 gboolean CFileStore::save_string(const char *key, const gchar* value)
00434 {
00435
00436 metadata_table *value_table = metadata_table_new();
00437 if (value_table == 0)
00438 {
00439 return false;
00440 }
00441
00442
00443 metadata_table_add_column(value_table, key);
00444
00445
00446 int ret = -1;
00447 int index = metadata_table_find_column(value_table, key);
00448 if (index >= 0)
00449 {
00450 ret = metadata_table_set_text(value_table, index, value);
00451 if (ret != ER_OK)
00452 {
00453 ERRORPRINTF("Cannot write value %s to table.", value);
00454 }
00455 }
00456
00457
00458
00459 ret = ermetadb_local_set_application_data(m_db, ".", value_table);
00460 metadata_table_free(value_table);
00461 return static_cast<gboolean>(ret == ER_OK);
00462 }
00463
00464
00465
00466 gboolean CFileStore::load_string(const char *key, gchar** value)
00467 {
00468 LOGPRINTF("entry, key %s", key);
00469
00470 metadata_table *name_table = metadata_table_new();
00471 if (name_table == NULL)
00472 {
00473 return FALSE;
00474 }
00475
00476
00477 metadata_table_add_column(name_table, key);
00478
00479
00480 metadata_table *results_table = NULL;
00481 int ret = ermetadb_local_get_application_data(m_db, ".", name_table, &results_table);
00482
00483
00484 metadata_table_free(name_table);
00485
00486 if (results_table == NULL)
00487 {
00488 LOGPRINTF("No result.");
00489 return FALSE;
00490 }
00491 if (ret != ER_OK)
00492 {
00493 ERRORPRINTF("Could not get application data.");
00494 }
00495
00496 const metadata_cell *cell = NULL;
00497 int index = metadata_table_find_column(results_table, key);
00498
00499 if (index >= 0)
00500 {
00501 cell = metadata_table_get_cell(results_table, index);
00502 if (cell != 0)
00503 {
00504 if (cell->type == METADATA_TEXT)
00505 {
00506 *value = g_strdup(cell->value.v_text->str);
00507 }
00508 else
00509 {
00510 ERRORPRINTF("wrong cell type");
00511 ret = ER_NOT_FOUND;
00512 }
00513 }
00514 else
00515 {
00516 ERRORPRINTF("Cannot find cell");
00517 ret = ER_NOT_FOUND;
00518 }
00519 }
00520 else
00521 {
00522 ERRORPRINTF("Cannot find column");
00523 ret = ER_NOT_FOUND;
00524 }
00525
00526
00527 metadata_table_free(results_table);
00528 return static_cast<gboolean>(ret == ER_OK);
00529 }
00530
00531
00532 gint CFileStore::get_last_read_location(void)
00533 {
00534 gchar* location = 0;
00535 gboolean result = load_string (SCRIBBLE_LAST_READ_LOCATION, &location);
00536 gint last_read = 0;
00537 if ( ! result )
00538 {
00539 last_read = -1;
00540 }
00541 else if (sscanf( location, "%d", &last_read ) < 0)
00542 {
00543 last_read = -1;
00544 }
00545 g_free(location);
00546 LOGPRINTF( "get_last_read_location -- last_read = %d", last_read);
00547 return last_read;
00548 }
00549
00550 gboolean CFileStore::set_last_read_location(gint location)
00551 {
00552 LOGPRINTF( "set_last_read_location -- last_read = %d", location);
00553 gboolean result = FALSE;
00554 gchar* my_location = g_strdup_printf("%d", location);
00555 result = save_string( SCRIBBLE_LAST_READ_LOCATION, my_location);
00556 g_free(my_location);
00557 return result;
00558 }
00559
00560 }
00561
00562