Skip to content

Instantly share code, notes, and snippets.

@varqox
Last active August 19, 2021 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save varqox/08b9e506997dbbc043b55f61d0c35a8b to your computer and use it in GitHub Desktop.
Save varqox/08b9e506997dbbc043b55f61d0c35a8b to your computer and use it in GitHub Desktop.
Test of sqlite zipfile (disappointed me, so I switched to libzip)
// needs sqlite.h from sim's lib that is not in simlib
#include "lib/simlib/sqlite3/sqlite3.h"
#include "lib/simlib/sqlite3/zipfile.h"
#include <simlib/filesystem.h>
#include <simlib/sqlite.h>
class Zip {
SQLite::Connection conn_;
public:
Zip(StringView file)
: conn_(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
SQLITE_OPEN_NOMUTEX) {
sqlite3_zipfile_init(conn_, nullptr, nullptr);
InplaceBuff<64> escaped_file;
for (char c : file) {
escaped_file.append(c);
if (c == '\'')
escaped_file.append('\'');
}
conn_.execute(concat("CREATE VIRTUAL TABLE zip USING zipfile('",
escaped_file, "')").to_cstr());
conn_.execute("BEGIN TRANSACTION");
}
~Zip() {
conn_.execute("COMMIT");
}
SQLite::Connection& sqlite() noexcept { return conn_; }
// Adds @p contents as @p path
void add_file(StringView path, StringView contents, mode_t mode, uint64_t mtime) {
if (hasSuffix(path, ".a")) {
stdlog(path, ' ', contents.size());
}
auto stmt = conn_.prepare("REPLACE INTO zip(name, data, mode, mtime, method)"
" VALUES(?,?,?,?,8)");
stmt.bindText(1, path, SQLITE_STATIC);
stmt.bindText(2, contents, SQLITE_STATIC);
stmt.bindInt(3, mode);
stmt.bindInt64(4, mtime);
stmt.step();
}
void add_file(StringView path, StringView contents, mode_t mode = 33188 /*(-rw-r--r--)*/)
{
add_file(path, contents, mode, time(nullptr));
}
// Adds @p path as a directory
void add_dir(StringView path, mode_t mode, uint64_t mtime) {
stdlog("Adding: ", path);
auto stmt = conn_.prepare("REPLACE INTO zip(name, data, mode, mtime)"
" VALUES(?,NULL,?,?)");
stmt.bindText(1, path, SQLITE_STATIC);
stmt.bindInt(2, mode);
stmt.bindInt64(3, mtime);
stmt.step();
}
void add_dir(StringView path, mode_t mode = 16877 /*(drwxr-xr-x)*/) {
add_dir(path, mode, time(nullptr));
}
// Adds file or directory with path @p path
void add_file(CStringView path) {
struct stat64 st;
if (stat64(path.data(), &st))
THROW("stat()", errmsg());
if (S_ISDIR(st.st_mode))
add_dir(path, st.st_mode, st.st_mtim.tv_sec);
else
add_file(path, getFileContents(path), st.st_mode, st.st_mtim.tv_sec);
}
private:
void add_dir_r(InplaceBuff<PATH_MAX>& path) {
struct stat64 st;
if (stat64(path.to_cstr().data(), &st))
THROW("stat()", errmsg());
if (not S_ISDIR(st.st_mode))
return add_file(path, getFileContents(path.to_cstr()), st.st_mode,
st.st_mtim.tv_sec);
if (path.back() != '/')
path.append('/');
forEachDirComponent(path.to_cstr(), [&](dirent* file) {
size_t path_size_bkp = path.size;
path.append(file->d_name);
add_dir_r(path);
path.size = path_size_bkp;
});
}
public:
// Adds directory and its contents recursively
void add_dir_r(StringView path) {
InplaceBuff<PATH_MAX> buff(path);
return add_dir_r(buff);
}
};
#include <simlib/libarchive_zip.h>
int main() {/*
auto conn = SQLite::Connection(":memory:",
// // auto conn = SQLite::Connection("",
// // 0);
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX);
sqlite3_zipfile_init(conn, nullptr, nullptr);
auto stmt = conn.prepare("SELECT name, sz, rawdata FROM zipfile('new.zip')");
while (stmt.step() == SQLITE_ROW) {
// stdlog(stmt.getStr(0), ' ', stmt.getStr(1), ' ', stmt.getStr(0).size() + stmt.getStr(2).size());
auto size = stmt.getOptStr(2).value_or("").size();
stdlog(stmt.getStr(0), ' ', stmt.getStr(1), '\t', stmt.getStr(0).size(), ' ', size);
}
*/
// Zip zip("test.zip");
// zip.add_dir_r("src");
compress_into_zip({"src"}, "src.libarchive.zip");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment