summaryrefslogtreecommitdiffhomepage
path: root/storage.cpp
blob: 545ba04bcf2b60b5bc590d1e1a265fe534a9ffa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "storage.h"

#include "config.h"

#include <chrono>

#include <SQLiteCpp/SQLiteCpp.h>

using namespace std::string_literals;

Storage::Storage(const Config& config):
 m_db(config.getDataPath() + "/whiteboard.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE),
 m_maxage(config.getMaxage())
{
 m_db.exec("CREATE TABLE IF NOT EXISTS documents (id VARCHAR(16) PRIMARY KEY, value BLOB, rev INTEGER, cursorpos INTEGER, timestamp BIGINT)");
}

uint64_t Storage::getNumberOfDocuments()
{
 SQLite::Statement query(m_db, "SELECT COUNT(*) FROM documents");
 if (!query.executeStep())
  throw std::runtime_error("Count not possible");
 
 return static_cast<int64_t>(query.getColumn(0));
}

void Storage::cleanup()
{
 if (m_maxage == 0)
  return;

 SQLite::Statement query(m_db, "DELETE FROM documents WHERE timestamp + ? < unixepoch()");
 query.bind(1, static_cast<int64_t>(m_maxage));

 query.exec();
}

bool Storage::exists(const std::string& id)
{
 SQLite::Statement query(m_db, "SELECT id FROM documents WHERE id = ?");
 query.bind(1, id);

 return query.executeStep();
}

std::string Storage::getDocument(const std::string& id)
{
 SQLite::Statement query(m_db, "SELECT value FROM documents WHERE id = ?");
 query.bind(1, id);

 if (!query.executeStep())
  throw std::runtime_error("id "s + id + " not found"s);

 return query.getColumn(0);
}

int Storage::getRevision(const std::string& id)
{
 SQLite::Statement query(m_db, "SELECT rev FROM documents WHERE id = ?");
 query.bind(1, id);

 if (!query.executeStep())
  throw std::runtime_error("id "s + id + " not found"s);

 return query.getColumn(0);
}

int Storage::getCursorPos(const std::string& id)
{
 SQLite::Statement query(m_db, "SELECT cursorpos FROM documents WHERE id = ?");
 query.bind(1, id);

 if (!query.executeStep())
  throw std::runtime_error("id "s + id + " not found"s);

 return query.getColumn(0);
}

std::tuple<std::string, int, int> Storage::getRow(const std::string& id)
{
 SQLite::Statement query(m_db, "SELECT value, rev, cursorpos FROM documents WHERE id = ?");
 query.bind(1, id);

 if (!query.executeStep())
  throw std::runtime_error("id "s + id + " not found"s);

 return {query.getColumn(0), query.getColumn(1), query.getColumn(2)};
}
 
void Storage::setDocument(const std::string& id, const std::string& document)
{
 SQLite::Statement query(m_db, "UPDATE documents SET value = ? WHERE id = ?");
 query.bind(1, document);
 query.bind(2, id);

 if (!query.exec()) {
  SQLite::Statement query(m_db, "INSERT INTO documents (id, value, rev, cursorpos, timestamp) values (?, ?, ?, ?, unixepoch())");
  query.bind(1, id);
  query.bind(2, document);
  query.bind(3, 0);
  query.bind(4, 0);
  query.exec();
 }
}

void Storage::setRevision(const std::string& id, int rev)
{
 SQLite::Statement query(m_db, "UPDATE documents SET rev = ? WHERE id = ?");
 query.bind(1, rev);
 query.bind(2, id);

 if (!query.exec())
  throw std::runtime_error("Unable to insert row with id "s + id);
}

void Storage::setCursorPos(const std::string& id, int cursorPos)
{
 SQLite::Statement query(m_db, "UPDATE documents SET cursorpos = ? WHERE id = ?");
 query.bind(1, cursorPos);
 query.bind(2, id);

 if (!query.exec())
  throw std::runtime_error("Unable to insert row with id "s + id);
}

void Storage::setRow(const std::string& id, const std::string& document, int rev, int cursorPos)
{
 SQLite::Statement query(m_db, "INSERT OR REPLACE INTO documents (id, value, rev, cursorpos, timestamp) values (?, ?, ?, ?, unixepoch())");
 query.bind(1, id);
 query.bind(2, document);
 query.bind(3, rev);
 query.bind(4, cursorPos);
 if (!query.exec())
  throw std::runtime_error("Unable to insert row with id "s + id);
}