summaryrefslogtreecommitdiffabout
path: root/src/db.cc
Unidiff
Diffstat (limited to 'src/db.cc') (more/less context) (ignore 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 @@
1#include <unistd.h>
2#include <sys/stat.h>
3#include <sys/types.h>
4#include <cassert>
5#include <napkin/exception.h>
6#include "db.h"
7
8#include "config.h"
9
10namespace napkin {
11
12 extern const char *sql_bootstrap;
13
14 db_t::db_t() {
15 const char *h = getenv("HOME");
16 if(h) {
17 datadir = h;
18 datadir += "/."PACKAGE_NAME"/";
19 }else{
20 char *cwd = get_current_dir_name();
21 if(!cwd)
22 throw napkin::exception("failed to get_current_dir_name()");
23 datadir = cwd;
24 free(cwd);
25 datadir += "/."PACKAGE_NAME"/";
26 }
27 if(access(datadir.c_str(),R_OK|W_OK)
28 && mkdir(datadir.c_str(),0700))
29 throw napkin::exception("no access to '"+datadir+"' directory");
30 open((datadir+PACKAGE_NAME".db").c_str());
31 assert(_D);
32 char **resp; int nr,nc; char *errm;
33 if(sqlite3_get_table(
34 _D,
35 "SELECT s_tobed FROM sleeps LIMIT 0",
36 &resp,&nr,&nc,&errm)!=SQLITE_OK) {
37 if(sqlite3_exec(_D,sql_bootstrap,NULL,NULL,&errm)!=SQLITE_OK)
38 throw napkin::exception(string("failed to bootstrap sqlite database: ")+errm);
39 }else
40 sqlite3_free_table(resp);
41 }
42
43 void db_t::store(const hypnodata_t& hd) {
44 sqlite::mem_t<char*> S = sqlite3_mprintf(
45 "INSERT INTO sleeps ("
46 "s_tobed,s_alarm,"
47 "s_window,s_data_a,"
48 "s_almost_awakes,"
49 "s_timezone"
50 ") VALUES ("
51 "%Q,%Q,%d,%d,%Q,%ld"
52 ")",
53 hd.w3c_to_bed().c_str(),
54 hd.w3c_alarm().c_str(),
55 hd.window,hd.data_a,
56 hd.w3c_almostawakes().c_str(),
57 timezone );
58 try {
59 exec(S);
60 }catch(sqlite::exception& se) {
61 if(se.rcode==SQLITE_CONSTRAINT)
62 throw exception_db_already("The record seems to be already in the database");
63 throw exception_db("Well, some error occured");
64 }
65 }
66
67 void db_t::remove(const hypnodata_t& hd) {
68 sqlite::mem_t<char*> S = sqlite3_mprintf(
69 "DELETE FROM sleeps"
70 " WHERE s_tobed=%Q AND s_alarm=%Q",
71 hd.w3c_to_bed().c_str(),
72 hd.w3c_alarm().c_str() );
73 exec(S);
74 }
75
76 void db_t::load(list<hypnodata_ptr_t>& rv,
77 const string& sql) {
78 sqlite::table_t T;
79 int nr,nc;
80 get_table( string(
81 "SELECT"
82 " s_tobed, s_alarm,"
83 " s_window, s_data_a,"
84 " s_almost_awakes"
85 " FROM sleeps"
86 " "+sql).c_str(),T,&nr,&nc );
87 if(nr) {
88 assert(nc==5);
89 for(int r=1;r<=nr;++r) {
90 hypnodata_ptr_t hd(new hypnodata_t());
91 hd->set_to_bed(T.get(r,0,nc));
92 hd->set_alarm(T.get(r,1,nc));
93 hd->set_window(T.get(r,2,nc));
94 hd->set_data_a(T.get(r,3,nc));
95 hd->set_almost_awakes(T.get(r,4,nc));
96 rv.push_back(hd);
97 }
98 }
99 }
100
101}