3. Operations

These are the command line operations for the crate interface.

3.1. Top Level Callback

ww_crate is expected to be called inside of the top-level weewiki program.

<<funcdefs>>=
int ww_crate(int argc, char *argv[]);
<<funcs>>=
int ww_crate(int argc, char *argv[])
{
    const char *cmd;

    if (argc <= 1) {
        fprintf(stderr, "Crate: supply a command\n");
        return -1;
    }

    cmd = argv[1];

    argv++;
    argc--;

    if (!strcmp(cmd, "import")) {
        p_import(argc, argv);
    } else if (!strcmp(cmd, "export")) {
        p_export(argc, argv);
    } else if (!strcmp(cmd, "extract")) {
        p_extract(argc, argv);
    } else if (!strcmp(cmd, "find")) {
        p_find(argc, argv);
    } else if (!strcmp(cmd, "copy")) {
        p_copy(argc, argv);
    } else {
        fprintf(stderr, "Crate: could not find command '%s'\n", cmd);
    }
    /* TODO: implement */
    return -1;
}

3.2. Import

Usage: import a.db foo.sqlar

Import a SQLar archive into the zet. Doing th is also creates a metafile for every file in the archive, so this should be run in a new directory.

<<static_funcdefs>>=
static int p_import(int argc, char *argv[]);

Import assumes that the SQLar archive and the weewiki database are two separate files. Both are SQLite databases. The weewiki database gets opened up using weewiki abstractions. SQLar gets opened up directly using the SQLite API.

The name of the game here is to take the name column from the SQLar sqlite table, and use that to create file zet entries in the weewiki database.

Before inserting file entries, a new group entry is created with the name of the SQLar archive. When a new file entry is created, its UUID gets linked with the UUID of the group.

Note: don't forget to use BEGIN and COMMIT on the weewiki database for faster inserts.

<<funcs>>=
static int do_i_exist(const char *filename)
{
    FILE *fp;
    int rc;

    fp = fopen(filename, "r");

    rc = 0;

    if (fp == NULL) {
        rc = 0;
    } else {
        rc = 1;
        fclose(fp);
    }

    return rc;
}

static int p_import(int argc, char *argv[])
{
    const char *ww_name;
    weewiki_d *ww;
    sqlite3 *ww_db;

    const char *sqlar_name;
    sqlite3 *sqlar_db;
    sqlite3_stmt *stmt;
    int rc;

    wwzet_uuid group_uuid;

    if (argc < 3) {
        fprintf(stderr, "Usage: %s a.db foo.sqlar\n", argv[0]);
        return 1;
    }

    ww_name = argv[1];
    sqlar_name = argv[2];

    if (!do_i_exist(sqlar_name)) {
        fprintf(stderr, "Could not find %s\n", sqlar_name);
        return 1;
    }

    ww = malloc(weewiki_sizeof());
    weewiki_init(ww);
    weewiki_open(ww, ww_name);
    sqlite3_open(sqlar_name, &sqlar_db);

    wwzet_uuid_rng_init();

    /* create group */
    wwzet_uuid_init(&group_uuid);
    wwzet_group(ww, sqlar_name, strlen(sqlar_name), &group_uuid);

    sqlite3_prepare_v2(sqlar_db,
                       "SELECT name FROM sqlar;",
                       -1, &stmt, NULL);

    rc = sqlite3_step(stmt);

    ww_db = weewiki_db(ww);

    sqlite3_exec(ww_db, "BEGIN;\n", NULL, NULL, NULL);

    while (rc == SQLITE_ROW) {
        const char *f;
        int sz;
        wwzet_uuid file_uuid;

        f = (const char *)sqlite3_column_text(stmt, 0);
        sz = sqlite3_column_bytes(stmt, 0);

        wwzet_file(ww, f, sz, &file_uuid);
        wwzet_link(ww, &file_uuid, &group_uuid);

        rc = sqlite3_step(stmt);
    }

    sqlite3_exec(ww_db, "COMMIT;\n", NULL, NULL, NULL);

    sqlite3_finalize(stmt);
    sqlite3_close(sqlar_db);
    weewiki_close(ww);
    weewiki_clean(ww);
    free(ww);

    return 1;
}

3.3. Find

Usage: find a.db file_pattern

Performs a search in the zet for a file pattern.

<<static_funcdefs>>=
static int p_find(int argc, char *argv[]);
<<funcs>>=
static int p_find(int argc, char *argv[])
{
    sqlite3_stmt *stmt;
    const char *ww_name;
    weewiki_d *ww;
    sqlite3 *db;
    int rc;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s a.db file_pattern\n",
                argv[0]);
        return 1;
    }

    ww_name = argv[1];

    ww = malloc(weewiki_sizeof());
    weewiki_init(ww);
    weewiki_open(ww, ww_name);

    db = weewiki_db(ww);

    if (argc == 2) {
        /* list all files */
        sqlite3_prepare_v2(db,
                           "SELECT uuid, value FROM wikizet "
                           "WHERE value LIKE \"/%\";",
                           -1, &stmt, NULL);
    } else {
        sqlite3_prepare_v2(db,
                           "SELECT uuid, value FROM wikizet "
                           "WHERE value LIKE \"/%\" "
                           "and value LIKE ?1;",
                           -1, &stmt, NULL);

        sqlite3_bind_text(stmt, 1, argv[2], -1, NULL);
    }


    rc = sqlite3_step(stmt);

    while (rc == SQLITE_ROW) {
        const char *uuid;
        const char *fname;

        uuid = (const char *)sqlite3_column_text(stmt, 0);
        fname = (const char *)sqlite3_column_text(stmt, 1);
        printf("%s\t%s\n", uuid, fname);

        rc = sqlite3_step(stmt);
    }

    sqlite3_finalize(stmt);
    weewiki_close(ww);
    weewiki_clean(ww);
    free(ww);
    return 1;
}

3.4. Export

Usage: export a.db file_pattern

Exports metadata based on a SQLite file pattern. This will save information as tab-separated key value pairs. The filenames used will be their UUID.

<<static_funcdefs>>=
static int p_export(int argc, char *argv[]);
<<funcs>>=
static int p_export(int argc, char *argv[])
{
    sqlite3_stmt *stmt;
    const char *ww_name;
    weewiki_d *ww;
    sqlite3 *db;
    int rc;

    if (argc < 3) {
        fprintf(stderr, "Usage: %s a.db file_pattern\n",
                argv[0]);
        return 1;
    }

    ww_name = argv[1];

    ww = malloc(weewiki_sizeof());
    weewiki_init(ww);
    weewiki_open(ww, ww_name);

    db = weewiki_db(ww);

    sqlite3_prepare_v2(db,
                        "SELECT uuid, value FROM wikizet "
                        "WHERE value LIKE \"/%\" "
                        "and value LIKE ?1;",
                        -1, &stmt, NULL);

    sqlite3_bind_text(stmt, 1, argv[2], -1, NULL);


    rc = sqlite3_step(stmt);

    while (rc == SQLITE_ROW) {
        const char *uuid;
        const char *fname;
        FILE *fp;

        uuid = (const char *)sqlite3_column_text(stmt, 0);
        fname = (const char *)sqlite3_column_text(stmt, 1);

        fp = fopen(uuid, "w");
        printf("%s\t%s\n", uuid, fname);
        fprintf(fp, "uuid\t%s\n", uuid);
        fprintf(fp, "filename\t%s\n", fname);
        fclose(fp);
        rc = sqlite3_step(stmt);
    }

    sqlite3_finalize(stmt);
    weewiki_close(ww);
    weewiki_clean(ww);
    free(ww);
    return 1;
}

3.5. Extract

Extracts a file using the metadata file.

<<static_funcdefs>>=
static int p_extract(int argc, char *argv[]);
<<funcs>>=
static int p_extract(int argc, char *argv[])
{
    fprintf(stderr, "not implemented.\n");
    return 1;
}

3.6. Copy

Usage: copy a.db foo.sqlar

Copy a SQLar archive foo.sqlar to a weewiki database a.db.

<<static_funcdefs>>=
static int p_copy(int argc, char *argv[]);
<<funcs>>=
static int p_copy(int argc, char *argv[])
{
    sqlite3 *db;
    sqlite3_stmt *stmt;

    int rc;
    int err;

    err = 0;

    rc = sqlite3_open(":memory:", &db);

    if (rc) {
        fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
        return 1;
    }

    if (argc < 3) {
        fprintf(stderr, "Usage: %s src dst\n", argv[0]);
        return 1;
    }

    rc = sqlite3_prepare_v2(db,
                            "ATTACH ?1 AS src;",
                            -1, &stmt, NULL);
    sqlite3_bind_text(stmt, 1, argv[1], -1, NULL);

    rc = sqlite3_step(stmt);

    if (rc != SQLITE_DONE) {
        fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
        err = 1;
        goto cleanup;
    }

    rc = sqlite3_prepare_v2(db,
                            "ATTACH ?1 AS dst;",
                            -1, &stmt, NULL);
    sqlite3_bind_text(stmt, 1, argv[2], -1, NULL);

    rc = sqlite3_step(stmt);

    if (rc != SQLITE_DONE) {
        fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
        err = 1;
        goto cleanup;
    }

    sqlite3_exec(db,
        "CREATE TABLE IF NOT EXISTS dst.sqlar("
        "  name TEXT PRIMARY KEY,"
        "  mode INT,"
        "  mtime INT,"
        "  sz INT,"
        "  data BLOB"
        ");", NULL, NULL, NULL);

    sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
    sqlite3_exec(db,
                "INSERT OR REPLACE INTO dst.sqlar SELECT * FROM src.sqlar;", NULL, NULL, NULL);
    sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);

    sqlite3_exec(db, "DETACH src;", NULL, NULL, NULL);
    sqlite3_exec(db, "DETACH dst;", NULL, NULL, NULL);

    cleanup:
    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return err;
}



prev | home | next