new: implement database keeps and files functions

This commit is contained in:
ngn
2024-07-03 03:40:52 +03:00
parent 17a073838d
commit 43cf7d26c8
14 changed files with 461 additions and 32 deletions

View File

@ -25,12 +25,15 @@ lm_database_t *lm_database_new(char *path){
char *err = NULL;
bzero(db, sizeof(lm_database_t));
if(exists(path) && !can_read(path)){
if(exists(path) && (is_file(path) || !can_read(path) || !can_write(path))){
lm_error_set(LM_ERR_DbCantAccess);
return NULL;
}
char dbfile[strlen(path)+20];
join(dbfile, path, "packages.db");
if(sqlite3_open(path, &db->sql)){
if(sqlite3_open(dbfile, &db->sql)){
pdebug(__func__, "(%s) failed to open databse: %s", path, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlOpenFail);
return NULL;
@ -42,13 +45,13 @@ lm_database_t *lm_database_new(char *path){
sqlite3_free(err);
}
db->path = strdup(path);
db->dir = strdup(path);
return db;
}
void lm_database_free(lm_database_t *db){
sqlite3_close(db->sql);
free(db->path);
free(db->dir);
lm_pkg_t *cur = db->pkg, *prev = NULL;
while(NULL != cur){

177
src/database/files.c Normal file
View File

@ -0,0 +1,177 @@
#include "../../include/database.h"
#include "../../include/package.h"
#include "../../include/error.h"
#include "../../include/util.h"
#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <unistd.h>
#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){
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);
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;
}
while(getline(&line, 0, files) > 0){
line_len = strlen(line);
char path[line_len+1];
if(HASH_LEN >= line_len)
continue;
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;
}
ret = true;
end:
free(line);
if(NULL != files)
fclose(files);
return ret;
}
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);
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);
goto end;
}
ret = true;
end:
if(NULL != files)
fclose(files);
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 || NULL == hash){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
// zero out the hash
bzero(hash, HASH_LEN+1);
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");
char *line = NULL;
size_t line_len = 0;
bool ret = false;
if(NULL == files){
lm_error_set(LM_ERR_DbFilesOpenFail);
goto end;
}
while(getline(&line, 0, files) > 0){
line_len = strlen(line);
char lpath[line_len+1];
if(HASH_LEN >= line_len)
continue;
memcpy(lpath, line+HASH_LEN+1, line_len-HASH_LEN);
if(eq(lpath, path)){
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");
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;
}
return true;
}

153
src/database/keeps.c Normal file
View File

@ -0,0 +1,153 @@
#include "../../include/database.h"
#include "../../include/package.h"
#include "../../include/error.h"
#include "../../include/util.h"
#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
bool lm_database_keeps_foreach(lm_database_t *db, lm_pkg_t *pkg, lm_database_keeps_eachfunc_t func, void *data){
if(NULL == db || NULL == pkg || NULL == func){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
char keeps_list[strlen(db->dir)+strlen(pkg->name)+20];
join_multiple(keeps_list, db->dir, pkg->name, "keeps");
if(!exists(keeps_list)){
lm_error_set(LM_ERR_DbKeepsNotFound);
return false;
}
FILE *keeps = fopen(keeps_list, "r");
char *line = NULL;
bool ret = false;
if(NULL == keeps){
lm_error_set(LM_ERR_DbKeepsOpenFail);
goto end;
}
while(getline(&line, 0, keeps) > 0){
if(line[0] == 0)
continue;
if(!func(pkg, line, data))
goto end;
free(line);
line = NULL;
}
ret = true;
end:
free(line);
if(NULL != keeps)
fclose(keeps);
return ret;
}
bool lm_database_keeps_load(lm_database_t *db, lm_pkg_t *pkg){
if(NULL == db || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
char keeps_list[strlen(db->dir)+strlen(pkg->name)+20];
join_multiple(keeps_list, db->dir, pkg->name, "keeps");
if(!exists(keeps_list)){
lm_error_set(LM_ERR_DbKeepsNotFound);
return false;
}
FILE *keeps = fopen(keeps_list, "r");
char *line = NULL;
bool ret = false;
if(NULL == keeps){
lm_error_set(LM_ERR_DbKeepsOpenFail);
goto end;
}
while(getline(&line, 0, keeps) > 0){
if(line[0] == 0)
continue;
if(!lm_package_keep_add(pkg, line))
goto end;
free(line);
line = NULL;
}
ret = true;
end:
free(line);
if(NULL != keeps)
fclose(keeps);
return ret;
}
bool lm_database_keeps_save(lm_database_t *db, lm_pkg_t *pkg){
if(NULL == db || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
char pkg_dir[strlen(db->dir)+strlen(pkg->name)+5];
char keeps_list[sizeof(pkg_dir)+15];
bool ret = false;
join(pkg_dir, db->dir, pkg->name);
join(keeps_list, pkg_dir, "keeps");
if(!mkdir_ifnot(pkg_dir)){
lm_error_set(LM_ERR_DbKeepsDirFail);
return false;
}
FILE *keeps = fopen(keeps_list, "a");
if(NULL == keeps){
lm_error_set(LM_ERR_DbKeepsOpenFail);
goto end;
}
for(int i = 0; NULL != pkg->keeps[i]; i++)
fprintf(keeps, "%s\n", pkg->keeps[i]);
ret = true;
end:
if(NULL != keeps)
fclose(keeps);
return ret;
}
bool lm_database_keeps_del(lm_database_t *db, lm_pkg_t *pkg){
if(NULL == db || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
char keeps_list[strlen(db->dir)+strlen(pkg->name)+20];
join_multiple(keeps_list, db->dir, pkg->name, "keeps");
if(unlink(keeps_list) < 0 && errno != ENOENT){
pdebug(__func__, "failed to delete keep list for %s: %s", pkg->name, keeps_list);
lm_error_set(LM_ERR_DbKeepsUnlinkFail);
return false;
}
return true;
}

View File

@ -19,7 +19,7 @@ bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){
bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_PACKAGE], strlen(queries[QUERY_INSERT_PACKAGE]), &st, NULL) != SQLITE_OK){
pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql));
pdebug(__func__, "failed to prepare statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
@ -30,13 +30,13 @@ bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){
sqlite3_bind_int64(st, 4, pkg->size);
if(!lm_package_depend_tostr(pkg, depends)){
pdebug(__func__, "(%s) failed to convert depends to string: %s", db->path, lm_strerror());
pdebug(__func__, "failed to convert depends to string for inserting %s: %s", pkg->name, lm_strerror());
goto end;
}
sqlite3_bind_text(st, 5, depends, strlen(depends), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_DONE){
pdebug(__func__, "(%s) failed to execute insert statement: %s", db->path, sqlite3_errmsg(db->sql));
pdebug(__func__, "failed to execute insert statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlInsertFail);
goto end;
}
@ -58,7 +58,7 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_SELECT_PACKAGE], strlen(queries[QUERY_SELECT_PACKAGE]), &st, NULL) != SQLITE_OK){
pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql));
pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
@ -66,7 +66,7 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
sqlite3_bind_text(st, 1, name, strlen(name), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_ROW){
pdebug(__func__, "(%s) got no rows for %s", db->path, name);
pdebug(__func__, "got no rows for %s", name);
lm_error_set(LM_ERR_DbSqlNotFound);
goto end;
}
@ -87,7 +87,7 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
char *depends = (char*)sqlite3_column_text(st, 3);
if(!lm_package_depend_fromstr(pkg, depends)){
pdebug(__func__, "(%s) failed to load depends for %s (%s): %s", db->path, name, lm_strerror());
pdebug(__func__, "failed to load depends for finding %s: %s", pkg->name, lm_strerror());
// error is set by the function
goto end;
}
@ -109,7 +109,7 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_DELETE_PACKAGE], strlen(queries[QUERY_DELETE_PACKAGE]), &st, NULL) != SQLITE_OK){
pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql));
pdebug(__func__, "failed to prepare statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
@ -117,7 +117,7 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_DONE){
pdebug(__func__, "(%s) failed to execute delete statement: %s", db->path, sqlite3_errmsg(db->sql));
pdebug(__func__, "failed to execute delete statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlInsertFail);
goto end;
}