4. Adding a single file to a SQLar archive
4.1. Adding a file in C
4.1.1. sqlar_add_file
<<static_sqlar_function_declarations>>=
static int sqlar_add_file(const char *sqlar,
const char *file,
const char *name);
<<sqlar_functions>>=
<<compress_function>>
static int sqlar_add_file(const char *sqlar,
const char *file,
const char *name)
{
sqlite3 *db;
int rc;
sqlite3_stmt *stmt;
struct stat x;
char *zc;
int sz_orig;
int sz_compr;
sz_orig = 0;
sz_compr = 0;
rc = stat(file, &x);
if(rc) return SQLITE_CANTOPEN;
rc = sqlite3_open(sqlar, &db);
if(rc) return rc;
rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS sqlar(\n"
" name TEXT PRIMARY KEY,\n"
" mode INT,\n"
" mtime INT,\n"
" sz INT,\n"
" data BLOB\n"
");", 0, 0, 0);
rc = sqlite3_exec(db, "SELECT 1 FROM sqlar LIMIT 1", 0, 0, 0);
if(rc) {
fprintf(stderr, "File %s is not a SQLar archive\n", sqlar);
sqlite3_close(db);
return rc;
}
sqlite3_prepare(db,
"REPLACE INTO sqlar(name,mode,mtime,sz,data)"
" VALUES(?1,?2,?3,?4,?5)",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, x.st_mode);
sqlite3_bind_int64(stmt, 3, x.st_mtime);
zc = read_file(file, &sz_orig, &sz_compr);
sqlite3_bind_int(stmt, 4, sz_orig);
sqlite3_bind_blob(stmt, 5, zc, sz_compr, sqlite3_free);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_close(db);
return SQLITE_OK;
}
4.1.2. Compress Function
<<compress_function>>=
static char *read_file(const char *filename, int *size_orig, int *size_compr)
{
FILE *in;
char *zin;
long int nin;
char *zcompr;
unsigned long int ncompr;
int rc;
in = fopen(filename, "rb");
if(in==0) {
fprintf(stderr, "cannot open \"%s\" for reading\n", filename);
return NULL;
}
fseek(in, 0, SEEK_END);
nin = ftell(in);
rewind(in);
zin = sqlite3_malloc( nin+1 );
if(zin==0) {
fprintf(stderr, "cannot malloc for %ld bytes\n", nin+1);
return NULL;
}
if( nin>0 && fread(zin, nin, 1, in)!=1 ){
fprintf(stderr, "unable to read %ld bytes of file %s\n", nin, filename);
return NULL;
}
fclose(in);
ncompr = 13 + nin + (nin+999)/1000;
zcompr = sqlite3_malloc(ncompr+1);
if(zcompr==0) {
fprintf(stderr, "cannot malloc for %ld bytes\n", ncompr+1);
return NULL;
}
rc = compress((Bytef*)zcompr, &ncompr, (const Bytef*)zin, nin);
if( rc!=Z_OK ) {
fprintf(stderr, "Cannot compress %s\n", filename);
return NULL;
}
if(nin>ncompr){
sqlite3_free(zin);
*size_orig = nin;
*size_compr = (int)ncompr;
return zcompr;
}else{
sqlite3_free(zcompr);
*size_orig = *size_compr = nin;
return zin;
}
}
4.2. Adding a file in Scheme
<<sqlar_scheme_entries>>=
{"sqlar:add-file", pp_add_file, 3, 3, {STR,STR,STR}},
<<sqlar_scheme_functions>>=
static cell pp_add_file(cell x)
{
const char *db;
const char *file;
const char *name;
int rc;
cell cstr;
cstr = car(x);
db = string(car(x));
x = cdr(x);
file = string(car(x));
x = cdr(x);
name = string(car(x));
rc = sqlar_add_file(db, file, name);
if(rc != SQLITE_OK) {
error("Could not add file to sqlar archive", cstr);
}
return UNSPECIFIC;
}
prev | home | next