new: better way of handling files db
This commit is contained in:
@ -10,166 +10,171 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool lm_database_files_foreach(lm_database_t *db, lm_pkg_t *pkg, lm_database_files_eachfunc_t func, void *data){
|
||||
if(NULL == db || NULL == pkg || NULL == func){
|
||||
bool lm_database_files_matches(lm_database_t *db, char *path, char *hash){
|
||||
char *hashdb = NULL;
|
||||
bool ret = false;
|
||||
|
||||
if(NULL == db || NULL == path || NULL == hash){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_SINGLE], strlen(queries[QUERY_SELECT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
|
||||
pdebug(__func__, "failed to prepare statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlPrepareFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
|
||||
|
||||
if(sqlite3_step(db->files_st) != SQLITE_DONE){
|
||||
pdebug(__func__, "failed to execute select statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlSelectFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
hashdb = (char*)sqlite3_column_text(db->files_st, 1);
|
||||
ret = eq(hashdb, hash);
|
||||
|
||||
end:
|
||||
if(NULL != db->files_st){
|
||||
sqlite3_finalize(db->files_st);
|
||||
db->files_st = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool lm_database_files_iskeep(lm_database_t *db, char *path){
|
||||
bool ret = false;
|
||||
int iskeep = 0;
|
||||
|
||||
if(NULL == db || NULL == path){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_SINGLE], strlen(queries[QUERY_SELECT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
|
||||
pdebug(__func__, "failed to prepare statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlPrepareFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
|
||||
|
||||
if(sqlite3_step(db->files_st) != SQLITE_DONE){
|
||||
pdebug(__func__, "failed to execute select statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlSelectFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
iskeep = sqlite3_column_int64(db->files_st, 2);
|
||||
ret = iskeep == 1;
|
||||
|
||||
end:
|
||||
if(NULL != db->files_st){
|
||||
sqlite3_finalize(db->files_st);
|
||||
db->files_st = NULL;
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
bool lm_database_files_next(lm_database_t *db, lm_pkg_t *pkg, char **path, char **hash, bool *keep){
|
||||
if(NULL == db || NULL == pkg || NULL == path || NULL == hash || NULL == keep){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
char files_list[strlen(db->dir)+strlen(pkg->name)+20];
|
||||
join_multiple(files_list, db->dir, pkg->name, "files");
|
||||
|
||||
if(!exists(files_list)){
|
||||
lm_error_set(LM_ERR_DbFilesNotFound);
|
||||
if(NULL == db->files_st &&
|
||||
sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_ALL], strlen(queries[QUERY_SELECT_FILE_ALL]), &db->files_st, NULL) != SQLITE_OK){
|
||||
pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlPrepareFail);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *files = fopen(files_list, "r");
|
||||
char *line = NULL, hash[HASH_LEN+1];
|
||||
size_t line_len = 0;
|
||||
bool ret = false;
|
||||
|
||||
if(NULL == files){
|
||||
lm_error_set(LM_ERR_DbFilesOpenFail);
|
||||
goto end;
|
||||
else if(NULL != db->files_st){
|
||||
free(*path);
|
||||
free(*hash);
|
||||
*path = NULL;
|
||||
*hash = NULL;
|
||||
}
|
||||
|
||||
while((line_len = getline(&line, 0, files)) > 0){
|
||||
if(HASH_LEN >= line_len)
|
||||
continue;
|
||||
|
||||
char path[line_len+1];
|
||||
memcpy(path, line+HASH_LEN+1, line_len-HASH_LEN);
|
||||
memcpy(hash, line, HASH_LEN+1);
|
||||
hash[HASH_LEN] = 0;
|
||||
|
||||
if(!func(pkg, path, hash, data))
|
||||
goto end;
|
||||
|
||||
free(line);
|
||||
line = NULL;
|
||||
if(sqlite3_step(db->files_st) != SQLITE_ROW){
|
||||
sqlite3_finalize(db->files_st);
|
||||
db->files_st = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
free(line);
|
||||
|
||||
if(NULL != files)
|
||||
fclose(files);
|
||||
|
||||
return ret;
|
||||
*path = strdup((char*)sqlite3_column_text(db->files_st, 0));
|
||||
*hash = strdup((char*)sqlite3_column_text(db->files_st, 1));
|
||||
*keep = sqlite3_column_int(db->files_st, 2) == 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lm_database_files_add(lm_database_t *db, lm_pkg_t *pkg, char *path, char *hash){
|
||||
if(NULL == db || NULL == pkg || NULL == path || NULL == hash){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
char pkg_dir[strlen(db->dir)+strlen(pkg->name)+5];
|
||||
char files_list[sizeof(pkg_dir)+15];
|
||||
bool ret = false;
|
||||
|
||||
join(pkg_dir, db->dir, pkg->name);
|
||||
join(files_list, pkg_dir, "files");
|
||||
|
||||
if(!mkdir_ifnot(pkg_dir)){
|
||||
lm_error_set(LM_ERR_DbFilesDirFail);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *files = fopen(files_list, "a");
|
||||
|
||||
if(NULL == files){
|
||||
lm_error_set(LM_ERR_DbFilesOpenFail);
|
||||
if(NULL == db || NULL == pkg || NULL == path || NULL == hash){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(fprintf(files, "%s:%s\n", hash, path) < 0){
|
||||
pdebug(__func__, "failed to append file to files list: %s", files_list);
|
||||
lm_error_set(LM_ERR_DbFilesWriteFail);
|
||||
if(sqlite3_prepare(db->files_db, queries[QUERY_INSERT_FILE_SINGLE], strlen(queries[QUERY_INSERT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
|
||||
pdebug(__func__, "failed to prepare statement for inserting %s: %s", path, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlPrepareFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
|
||||
sqlite3_bind_text(db->files_st, 2, hash, strlen(hash), SQLITE_STATIC);
|
||||
if(lm_package_keep_contains(pkg, path))
|
||||
sqlite3_bind_int(db->files_st, 3, 1);
|
||||
else
|
||||
sqlite3_bind_int(db->files_st, 3, 0);
|
||||
sqlite3_bind_text(db->files_st, 4, pkg->name, strlen(pkg->name), SQLITE_STATIC);
|
||||
|
||||
if(sqlite3_step(db->files_st) != SQLITE_DONE){
|
||||
pdebug(__func__, "failed to execute insert statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlInsertFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
if(NULL != files)
|
||||
fclose(files);
|
||||
|
||||
if(NULL != db->files_st){
|
||||
sqlite3_finalize(db->files_st);
|
||||
db->files_st = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool lm_database_files_get(lm_database_t *db, lm_pkg_t *pkg, char *path, char *hash){
|
||||
if(NULL == db || NULL == pkg || NULL == path){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(NULL != hash)
|
||||
bzero(hash, HASH_LEN+1); // zero out the hash
|
||||
|
||||
char files_list[strlen(db->dir)+strlen(pkg->name)+10];
|
||||
join_multiple(files_list, db->dir, pkg->name, "files");
|
||||
|
||||
if(!exists(files_list)){
|
||||
lm_error_set(LM_ERR_DbFilesNotFound);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *files = fopen(files_list, "r");
|
||||
size_t line_len = 0;
|
||||
char *line = NULL;
|
||||
bool ret = false;
|
||||
|
||||
if(NULL == files){
|
||||
lm_error_set(LM_ERR_DbFilesOpenFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
while((line_len = getline(&line, 0, files)) > 0){
|
||||
if(HASH_LEN >= line_len)
|
||||
continue;
|
||||
|
||||
char lpath[line_len+1];
|
||||
memcpy(lpath, line+HASH_LEN+1, line_len-HASH_LEN);
|
||||
|
||||
if(eq(lpath, path)){
|
||||
if(NULL != hash){
|
||||
memcpy(hash, line, HASH_LEN+1);
|
||||
hash[HASH_LEN] = 0;
|
||||
}
|
||||
ret = true;
|
||||
goto end;
|
||||
}
|
||||
|
||||
free(line);
|
||||
line = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
free(line);
|
||||
|
||||
if(NULL != files)
|
||||
fclose(files);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool lm_database_files_del(lm_database_t *db, lm_pkg_t *pkg){
|
||||
if(NULL == db || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
char files_list[strlen(db->dir)+strlen(pkg->name)+10];
|
||||
join_multiple(files_list, db->dir, pkg->name, "files");
|
||||
bool ret = false;
|
||||
|
||||
if(unlink(files_list) < 0 && errno != ENOENT){
|
||||
pdebug(__func__, "failed to delete file list for %s: %s", pkg->name, files_list);
|
||||
lm_error_set(LM_ERR_DbFilesUnlinkFail);
|
||||
return false;
|
||||
if(sqlite3_prepare(db->files_db, queries[QUERY_DELETE_FILE_ALL], strlen(queries[QUERY_DELETE_FILE_ALL]), &db->files_st, NULL) != SQLITE_OK){
|
||||
pdebug(__func__, "failed to prepare statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlPrepareFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
sqlite3_bind_text(db->files_st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
|
||||
|
||||
if(sqlite3_step(db->files_st) != SQLITE_DONE){
|
||||
pdebug(__func__, "failed to execute delete statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->files_db));
|
||||
lm_error_set(LM_ERR_DbSqlDeleteFail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
if(NULL != db->files_st){
|
||||
sqlite3_finalize(db->files_st);
|
||||
db->files_st = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user