summaryrefslogtreecommitdiffabout
path: root/src/db.cc
Side-by-side diff
Diffstat (limited to 'src/db.cc') (more/less context) (show whitespace changes)
-rw-r--r--src/db.cc101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/db.cc b/src/db.cc
new file mode 100644
index 0000000..d1e0a85
--- a/dev/null
+++ b/src/db.cc
@@ -0,0 +1,101 @@
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <cassert>
+#include <napkin/exception.h>
+#include "db.h"
+
+#include "config.h"
+
+namespace napkin {
+
+ extern const char *sql_bootstrap;
+
+ db_t::db_t() {
+ const char *h = getenv("HOME");
+ if(h) {
+ datadir = h;
+ datadir += "/."PACKAGE_NAME"/";
+ }else{
+ char *cwd = get_current_dir_name();
+ if(!cwd)
+ throw napkin::exception("failed to get_current_dir_name()");
+ datadir = cwd;
+ free(cwd);
+ datadir += "/."PACKAGE_NAME"/";
+ }
+ if(access(datadir.c_str(),R_OK|W_OK)
+ && mkdir(datadir.c_str(),0700))
+ throw napkin::exception("no access to '"+datadir+"' directory");
+ open((datadir+PACKAGE_NAME".db").c_str());
+ assert(_D);
+ char **resp; int nr,nc; char *errm;
+ if(sqlite3_get_table(
+ _D,
+ "SELECT s_tobed FROM sleeps LIMIT 0",
+ &resp,&nr,&nc,&errm)!=SQLITE_OK) {
+ if(sqlite3_exec(_D,sql_bootstrap,NULL,NULL,&errm)!=SQLITE_OK)
+ throw napkin::exception(string("failed to bootstrap sqlite database: ")+errm);
+ }else
+ sqlite3_free_table(resp);
+ }
+
+ void db_t::store(const hypnodata_t& hd) {
+ sqlite::mem_t<char*> S = sqlite3_mprintf(
+ "INSERT INTO sleeps ("
+ "s_tobed,s_alarm,"
+ "s_window,s_data_a,"
+ "s_almost_awakes,"
+ "s_timezone"
+ ") VALUES ("
+ "%Q,%Q,%d,%d,%Q,%ld"
+ ")",
+ hd.w3c_to_bed().c_str(),
+ hd.w3c_alarm().c_str(),
+ hd.window,hd.data_a,
+ hd.w3c_almostawakes().c_str(),
+ timezone );
+ try {
+ exec(S);
+ }catch(sqlite::exception& se) {
+ if(se.rcode==SQLITE_CONSTRAINT)
+ throw exception_db_already("The record seems to be already in the database");
+ throw exception_db("Well, some error occured");
+ }
+ }
+
+ void db_t::remove(const hypnodata_t& hd) {
+ sqlite::mem_t<char*> S = sqlite3_mprintf(
+ "DELETE FROM sleeps"
+ " WHERE s_tobed=%Q AND s_alarm=%Q",
+ hd.w3c_to_bed().c_str(),
+ hd.w3c_alarm().c_str() );
+ exec(S);
+ }
+
+ void db_t::load(list<hypnodata_ptr_t>& rv,
+ const string& sql) {
+ sqlite::table_t T;
+ int nr,nc;
+ get_table( string(
+ "SELECT"
+ " s_tobed, s_alarm,"
+ " s_window, s_data_a,"
+ " s_almost_awakes"
+ " FROM sleeps"
+ " "+sql).c_str(),T,&nr,&nc );
+ if(nr) {
+ assert(nc==5);
+ for(int r=1;r<=nr;++r) {
+ hypnodata_ptr_t hd(new hypnodata_t());
+ hd->set_to_bed(T.get(r,0,nc));
+ hd->set_alarm(T.get(r,1,nc));
+ hd->set_window(T.get(r,2,nc));
+ hd->set_data_a(T.get(r,3,nc));
+ hd->set_almost_awakes(T.get(r,4,nc));
+ rv.push_back(hd);
+ }
+ }
+ }
+
+}