X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=lib%2Fzpm.c;h=4ffe0d3d89856618da5f2c86296604f2e5345e2c;hb=2e690698fef46656959d76b7d69b7162b734a96d;hp=37c7e7b565fc14288ce96d18318812e29f523f34;hpb=ecdd57da7df775c039aee834e1f74172004f352b;p=zpackage diff --git a/lib/zpm.c b/lib/zpm.c index 37c7e7b..4ffe0d3 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "zpm.h" @@ -189,11 +190,94 @@ int zpm_rollback(struct zpm *z) { return 1; } +int zpm_db_set_pragma(struct zpm *db, int pragma, int value) { + int rc; + char *sql; + sqlite3_stmt *s; + + switch (pragma) { + case 1: sql = "pragma application_id = ?;"; break; + case 2: sql = "pragma user_version = ?;"; break; + default: return -1; break; + } + + rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0); + + if (rc != SQLITE_OK) { + SQLERROR(sqlite3_errmsg(db->db)); + return -1; + } + + sqlite3_bind_int(s, 1, value); + if (rc != SQLITE_OK) { + SQLERROR(sqlite3_errmsg(db->db)); + fprintf(stderr, "cant bind pragma value\n"); + sqlite3_finalize(s); + return -1; + } + rc = sqlite3_step(s); + if (rc != SQLITE_DONE) { + SQLERROR(sqlite3_errmsg(db->db)); + fprintf(stderr, "cant set pragma\n"); + sqlite3_finalize(s); + return -1; + } + + sqlite3_finalize(s); + return value; +} + +int zpm_db_pragma(struct zpm *db, int pragma) { + int rc; + int value = -1; + char *sql = 0; + sqlite3_stmt *s; + + switch (pragma) { + case 1: sql = "pragma application_id;"; break; + case 2: sql = "pragma user_version;"; break; + default: return -1; break; + } + + rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0); + + if (rc != SQLITE_OK) { + SQLERROR(sqlite3_errmsg(db->db)); + fprintf(stderr, "%s, errnum = %d\n", sqlite3_errmsg(db->db), rc); + /* TODO just abort? */ + return -1; + } + + rc = sqlite3_step(s); + if (rc == SQLITE_ROW) { + value = sqlite3_column_int(s, 0); + } + + sqlite3_finalize(s); + return value; +} + +static +#include "newdb.c" + +int zpm_db_initialize(struct zpm *pkg) { + fprintf(stderr, "initializing zpm database\n"); + switch (sqlite3_exec(pkg->db, createdb, (int (*)(void *,int,char **,char **))0, NULL, NULL)) { + case SQLITE_OK: break; + default: + SQLERROR(sqlite3_errmsg(pkg->db)); + return 0; + break; + } + return 1; +} + /* NULL? Create? */ int zpm_open(struct zpm *pkg, char *path) { int rc; char *errstr = 0; sqlite3 *db = 0; + int appid, dbver; pkg->db = 0; pkg->path = 0; @@ -202,14 +286,38 @@ int zpm_open(struct zpm *pkg, char *path) { pkg->pkgname = 0; pkg->installed = 0; - /* TODO some way to determine if the DB is newly created ? */ - /* could check for tables, if there are any, then check version, etc */ rc = sqlite3_open(path, &db); if (rc) { SQLERROR(sqlite3_errmsg(db)); sqlite3_close(db); return 0; } + pkg->db = db; + pkg->path = dupstr(path); + + appid = zpm_db_pragma(pkg, 1); + dbver = zpm_db_pragma(pkg, 2); + + fprintf(stderr, "db appid = %x, dbver = %d\n", appid, dbver); + switch (appid) { + case 0: if (!zpm_db_initialize(pkg)) { + sqlite3_close(db); + return 1; + }; + break; + case 0x5a504442: break; + default: + fprintf(stderr, "unknown database type\n"); + sqlite3_close(db); + return 0; + break; + } + if (dbver > 1) { + fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver); + sqlite3_close(db); + return 0; + } + sqlite3_exec(pkg->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr); if (errstr) { fprintf(stderr, "sqlite foreign key error: %s\n", errstr); @@ -218,8 +326,6 @@ int zpm_open(struct zpm *pkg, char *path) { return 0; } - pkg->path = dupstr(path); - pkg->db = db; /* TODO if this is a new database, create structures */ @@ -322,7 +428,7 @@ int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) { unsigned char tmp[32]; hash_state md; sqlite3_stmt *ifile; - int haverow,havedata; + int haverow = 0,havedata = 0; int j,rc,type; char hashbuf[65]; @@ -342,19 +448,23 @@ int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) { /* mmap the file */ fd = open(path, O_RDONLY); if (fd == -1) { + fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno)); return 0; } if (fstat(fd, &sbuf) == -1) { + fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno)); return 0; } /* not a regular file? */ if (!S_ISREG(sbuf.st_mode)) { /* TODO this is ok, just stored differently */ + fprintf(stderr, "%s non-regular files unsupported %s\n", __FUNCTION__, path); return 0; } content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0); if (!content) { + fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno)); return 0; } @@ -366,24 +476,16 @@ int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) { sprintf(hash+j*2, "%02x", (unsigned)tmp[j]); } hash[64] = 0; -// fprintf(stderr, "file %s: %s\n", path, hash); - - /* compress */ - outbuf = compresslzma(content, sbuf.st_size, &outlen); -// fprintf(stderr, "compressed to %zu\n", outlen); - - /* don't need the original file now */ - munmap(content, sbuf.st_size); - close(fd); + fprintf(stderr, "file %s: %s\n", path, hash); /* prepare and bind */ /* TODO check null */ sqlite3 *db = pkg->db; - rc = sqlite3_prepare(db, "select size, content is not null from files where hash = ?", -1, &ifile,0); + rc = sqlite3_prepare_v2(db, "select size, content is not null from files where hash = ?", -1, &ifile,0); if (rc != SQLITE_OK) { SQLERROR(sqlite3_errmsg(db)); - return 1; + return 0; } /* hash, filename */ @@ -422,15 +524,27 @@ int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) { sqlite3_finalize(ifile); if (!havedata) { + /* compress */ + outbuf = compresslzma(content, sbuf.st_size, &outlen); + if (!outbuf) { + fprintf(stderr, "compresslzma failed\n"); + return 0; + } + fprintf(stderr, "compressed to %zu\n", outlen); + /* don't need the original file now */ + munmap(content, sbuf.st_size); + close(fd); + /* start a transaction */ // do that outside of here //zpm_begin(pkg); /* insert */ if (haverow) { + fprintf(stderr, "adding file data\n"); rc = sqlite3_prepare(db, "update files set size = ?, content = ? where hash = ?", -1, &ifile,0); } else { -// fprintf(stderr, "missing file data\n"); + fprintf(stderr, "creating new data row\n"); rc = sqlite3_prepare(db, "insert into files (size, content, hash) values (?,?,?)", -1, &ifile,0); } if (rc != SQLITE_OK) { @@ -473,8 +587,13 @@ int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) { /* commit */ //zpm_commit(pkg); + } else { + /* don't need the original file now */ + munmap(content, sbuf.st_size); + close(fd); } + /* if package and not nopackage flag, add to package */ if (pkg->pkgname && (!ZPM_NOPACKAGE)) { /* TODO */