6. Database
6.1. Open
A database is opened with weewiki_open
.
int weewiki_open(weewiki_d *ww, const char *filename);
int weewiki_open(weewiki_d *ww, const char *filename)
{
sqlite3 *db;
int rc;
FILE *fp;
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr,
"Could not find database %s\n",
filename);
return 1;
}
fclose(fp);
ww->db = NULL;
rc = sqlite3_open(filename, &db);
if (rc) {
fprintf(stderr,
"Could not open database: %s",
sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
ww->db = db;
return 0;
}
6.2. Create
Creates and initializes a weewiki database.
int weewiki_create(weewiki_d *ww, const char *filename);
int weewiki_create(weewiki_d *ww, const char *filename)
{
sqlite3 *db;
int rc;
ww->db = NULL;
rc = sqlite3_open(filename, &db);
if (rc) {
fprintf(stderr,
"Could not open database: %s",
sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
ww->db = db;
weewiki_create_tables(ww);
return 0;
}
6.3. Close
void weewiki_close(weewiki_d *ww);
void weewiki_close(weewiki_d *ww)
{
if (ww->db != NULL) sqlite3_close(ww->db);
ww->db = NULL;
}
6.4. Get
int weewiki_getter(weewiki_d *ww, const char *key);
int weewiki_getter(weewiki_d *ww, const char *key)
{
size_t sz;
sqlite3 *db;
sqlite3_stmt *stmt;
int rc;
FILE *fp;
fp = stdout;
db = ww->db;
sqlite3_prepare_v2(db,
"SELECT value FROM wiki WHERE(key==?1);",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, key, -1, NULL);
rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW) {
fprintf(stderr,
"Could not find key '%s'\n",
key);
sqlite3_finalize(stmt);
return 1;
}
sz = sqlite3_column_bytes(stmt, 0);
fwrite(sqlite3_column_text(stmt, 0), 1, sz, fp);
sqlite3_finalize(stmt);
return 0;
}
6.5. Set
int weewiki_setter(weewiki_d *ww,
const char *key,
const char *val);
int weewiki_setter(weewiki_d *ww,
const char *key,
const char *val)
{
sqlite3 *db;
sqlite3_stmt *stmt;
db = ww->db;
sqlite3_prepare_v2(db,
"SELECT value FROM wiki WHERE(key==?1);",
-1,
&stmt,
NULL);
sqlite3_prepare_v2(db,
"INSERT OR REPLACE INTO wiki"
"(key, value)\n"
"VALUES(?1,?2);",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, key, -1, NULL);
sqlite3_bind_text(stmt, 2, val, -1, NULL);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
return 0;
}
6.6. Create Tables
The function weewiki_create_tables
creates all the needed
SQLite tables needed by weewiki. This includes wiki
,
wikilinks
, and wikizet
.
The wiki
table is most important table by weewiki. It
holds all the wiki document content. wikis are stored in
a key-value fashion, with unique keys being the page names,
and text
being the page content, stored in org markup.
The wikilinks
table is used to managed all externally
linked files. What is given here is the page name
(the key
), the filename path, and the unix modification
time mtime
. This logic is used to determine syncing.
The wikizet
table is the the weewiki zettelkasten
interface. It is implemented using SQLites full-text
search capabilities (fts5) as a virtual table. Similar to
the wiki, the zet is a key/value database, except that
the keys are UUIDs that do not have a unique constraint, and
each entry has an optional timestamp for microblogging.
void weewiki_create_tables(weewiki_d *ww);
void weewiki_create_tables(weewiki_d *ww)
{
sqlite3_exec(ww->db,
"CREATE TABLE IF NOT EXISTS wiki(\n"
"key TEXT UNIQUE,\n"
"value TEXT\n"
");\n",
NULL,
NULL,
NULL);
sqlite3_exec(ww->db,
"CREATE TABLE IF NOT EXISTS wikilinks(\n"
"key TEXT UNIQUE,\n"
"filename TEXT,\n"
"mtime INTEGER\n"
");\n",
NULL,
NULL,
NULL);
sqlite3_exec(ww->db,
"CREATE VIRTUAL TABLE wikizet using fts5("
"time,\n"
"UUID,\n"
"value);\n",
NULL,
NULL,
NULL);
}
6.7. Push
Low level operation that pushes a file to a key. On error, returns a non-zero value.
int weewiki_push(weewiki_d *ww,
const char *fname,
const char *key);
int weewiki_push(weewiki_d *ww,
const char *fname,
const char *key)
{
char *buf;
size_t sz;
sqlite3 *db;
sqlite3_stmt *stmt;
int rc;
FILE *fp;
fp = fopen(fname, "r");
if (fp == NULL) {
fprintf(stderr,
"Could not open file %s for reading.\n",
fname);
return 1;
}
fseek(fp, 0, SEEK_END);
sz = ftell(fp);
buf = calloc(1, sz + 1);
fseek(fp, 0, SEEK_SET);
fread(buf, 1, sz, fp);
db = ww->db;
sqlite3_prepare_v2(db,
"INSERT OR REPLACE INTO wiki"
"(key, value)\n"
"VALUES(?1,?2);",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, key, -1, NULL);
sqlite3_bind_text(stmt, 2, buf, sz, NULL);
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
fprintf(stderr,
"SQLite error: %s\n",
sqlite3_errmsg(db));
return 1;
}
sqlite3_finalize(stmt);
free(buf);
return 0;
}
6.8. Pull
int weewiki_pull(weewiki_d *ww,
const char *key,
const char *fname);
int weewiki_pull(weewiki_d *ww,
const char *key,
const char *fname)
{
size_t sz;
sqlite3 *db;
sqlite3_stmt *stmt;
int rc;
FILE *fp;
fp = fopen(fname, "w");
if (fp == NULL) {
fprintf(stderr,
"Could not open file %s for writing\n",
fname);
return 1;
}
db = ww->db;
sqlite3_prepare_v2(db,
"SELECT value FROM wiki WHERE(key==?1);",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, key, -1, NULL);
rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW) {
fprintf(stderr,
"Could not find key '%s'\n",
key);
sqlite3_finalize(stmt);
return 1;
}
sz = sqlite3_column_bytes(stmt, 0);
fwrite(sqlite3_column_text(stmt, 0), 1, sz, fp);
sqlite3_finalize(stmt);
fclose(fp);
return 0;
}
6.9. Exists
The function weewiki_exists
is used to check if
a page (key
) exists in the weewiki database. Returns
TRUE (1) or FALSE (0).
int weewiki_exists(weewiki_d *ww, const char *key);
int weewiki_exists(weewiki_d *ww, const char *key)
{
sqlite3 *db;
sqlite3_stmt *stmt;
int rc;
db = ww->db;
sqlite3_prepare_v2(db,
"SELECT EXISTS("
"SELECT * FROM wiki WHERE(key==?1)"
");",
-1,
&stmt,
NULL);
sqlite3_bind_text(stmt, 1, key, -1, NULL);
sqlite3_step(stmt);
rc = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return rc;
}
6.10. Name Set/Get
A global variable is used outside of the global weewiki_d
because it needs to be able to be set before that struct
is initialized.
void weewiki_dbname_set(const char *name);
const char * weewiki_dbname_get(void);
static const char *g_dbname = "a.db";
void weewiki_dbname_set(const char *name)
{
g_dbname = name;
}
const char * weewiki_dbname_get(void)
{
return g_dbname;
}
prev | home | next