aboutsummaryrefslogtreecommitdiff
path: root/src/data.cpp
diff options
context:
space:
mode:
authorMetroWind <chris.corsair@gmail.com>2025-09-12 14:41:42 -0700
committerMetroWind <chris.corsair@gmail.com>2025-09-12 14:41:42 -0700
commiteedd1c6b6a612daeb0e4e154bc0200df6826aa1d (patch)
tree88f9d49e8bb6bca54b058a1b3763c1e86e8f68a8 /src/data.cpp
parentc33272456bf969aa47bca432ef302530aa2cf752 (diff)
Implement items() and addLink() in data source.
Diffstat (limited to 'src/data.cpp')
-rw-r--r--src/data.cpp88
1 files changed, 83 insertions, 5 deletions
diff --git a/src/data.cpp b/src/data.cpp
index 78cb500..d6c4c5f 100644
--- a/src/data.cpp
+++ b/src/data.cpp
@@ -1,3 +1,4 @@
1#include <format>
1#include <memory> 2#include <memory>
2#include <string> 3#include <string>
3#include <expected> 4#include <expected>
@@ -8,8 +9,33 @@
8 9
9#include "data.hpp" 10#include "data.hpp"
10 11
12// id, owner_id, parent_id, name, url, desc, visibility, time.
13#define LINK_TUPLE_TYPES int64_t,int64_t,int64_t,std::string,std::string,std::string,int,int64_t
14
11namespace 15namespace
12{ 16{
17using LinkTuple = std::tuple<LINK_TUPLE_TYPES>;
18LinkItem linkFromTuple(const LinkTuple& t)
19{
20 LinkItem l;
21 l.id = std::get<0>(t);
22 l.owner_id = std::get<1>(t);
23 int64_t p = std::get<2>(t);
24 if(p == 0)
25 {
26 l.parent_id = std::nullopt;
27 }
28 else
29 {
30 l.parent_id = p;
31 }
32 l.name = std::get<3>(t);
33 l.url = std::get<4>(t);
34 l.description = std::get<5>(t);
35 l.visibility = static_cast<LinkItem::Visibility>(std::get<6>(t));
36 l.time = mw::secondsToTime(std::get<7>(t));
37 return l;
38}
13 39
14} // namespace 40} // namespace
15 41
@@ -18,7 +44,7 @@ DataSourceSQLite::fromFile(const std::string& db_file)
18{ 44{
19 auto data_source = std::make_unique<DataSourceSQLite>(); 45 auto data_source = std::make_unique<DataSourceSQLite>();
20 ASSIGN_OR_RETURN(data_source->db, mw::SQLite::connectFile(db_file)); 46 ASSIGN_OR_RETURN(data_source->db, mw::SQLite::connectFile(db_file));
21 47 DO_OR_RETURN(data_source->db->execute("PRAGMA foreign_keys = ON;"));
22 // Perform schema upgrade here. 48 // Perform schema upgrade here.
23 // 49 //
24 // data_source->upgradeSchema1To2(); 50 // data_source->upgradeSchema1To2();
@@ -30,11 +56,12 @@ DataSourceSQLite::fromFile(const std::string& db_file)
30 "(id INTEGER PRIMARY KEY, openid_uid TEXT, name TEXT);")); 56 "(id INTEGER PRIMARY KEY, openid_uid TEXT, name TEXT);"));
31 DO_OR_RETURN(data_source->db->execute( 57 DO_OR_RETURN(data_source->db->execute(
32 "CREATE TABLE IF NOT EXISTS LinkItems " 58 "CREATE TABLE IF NOT EXISTS LinkItems "
33 "(id INTEGER PRIMARY KEY," 59 "(id INTEGER PRIMARY KEY, owner_id INTEGER NOT NULL,"
34 " FOREIGN KEY(owner_id) REFERENCES Users(id) NOT NULL," 60 " parent_id INTEGER,"
35 " FOREIGN KEY(parent_id) REFERENCES LinkItems(id),"
36 " name TEXT NOT NULL, url TEXT, description TEXT," 61 " name TEXT NOT NULL, url TEXT, description TEXT,"
37 " visibility INTEGER NOT NULL, time INTEGER NOT NULL);")); 62 " visibility INTEGER NOT NULL, time INTEGER NOT NULL,"
63 " FOREIGN KEY(owner_id) REFERENCES Users(id),"
64 " FOREIGN KEY(parent_id) REFERENCES LinkItems(id));"));
38 return data_source; 65 return data_source;
39} 66}
40 67
@@ -52,3 +79,54 @@ mw::E<void> DataSourceSQLite::setSchemaVersion(int64_t v) const
52{ 79{
53 return db->execute(std::format("PRAGMA user_version = {};", v)); 80 return db->execute(std::format("PRAGMA user_version = {};", v));
54} 81}
82
83mw::E<std::vector<LinkItem>>
84DataSourceSQLite::items(std::optional<int64_t> parent)
85{
86 std::vector<LinkTuple> links;
87 if(!parent.has_value())
88 {
89 // Querying root-level links.
90 ASSIGN_OR_RETURN(links, (db->eval<LINK_TUPLE_TYPES>(
91 "SELECT id, owner_id, parent_id, name, url, description, visibility,"
92 " time from LinkItems WHERE parent_id IS NULL;")));
93 }
94 else
95 {
96 ASSIGN_OR_RETURN(mw::SQLiteStatement stat, db->statementFromStr(
97 "SELECT id, owner_id, parent_id, name, url, description, visibility,"
98 " time from LinkItems WHERE parent_id = ?;"));
99 DO_OR_RETURN(stat.bind<int64_t>(*parent));
100 ASSIGN_OR_RETURN(links, (db->eval<LINK_TUPLE_TYPES>(std::move(stat))));
101 }
102 std::vector<LinkItem> result;
103 for(const LinkTuple& t : links)
104 {
105 result.push_back(linkFromTuple(t));
106 }
107 return result;
108}
109
110mw::E<int64_t> DataSourceSQLite::addLink(LinkItem&& link)
111{
112 ASSIGN_OR_RETURN(mw::SQLiteStatement sql, db->statementFromStr(
113 "INSERT INTO LinkItems (id, owner_id, parent_id, name, url,"
114 " description, visibility, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"));
115 if(link.parent_id.has_value())
116 {
117 DO_OR_RETURN(sql.bind(
118 std::nullopt, link.owner_id, *link.parent_id, link.name, link.url,
119 link.description, static_cast<int>(link.visibility),
120 mw::timeToSeconds(mw::Clock::now())));
121 }
122 else
123 {
124 DO_OR_RETURN(sql.bind(
125 std::nullopt, link.owner_id, std::nullopt, link.name, link.url,
126 link.description, static_cast<int>(link.visibility),
127 mw::timeToSeconds(mw::Clock::now())));
128 }
129
130 DO_OR_RETURN(db->execute(std::move(sql)));
131 return db->lastInsertRowID();
132}