From eedd1c6b6a612daeb0e4e154bc0200df6826aa1d Mon Sep 17 00:00:00 2001 From: MetroWind Date: Fri, 12 Sep 2025 14:41:42 -0700 Subject: Implement items() and addLink() in data source. --- src/data.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 5 deletions(-) (limited to 'src/data.cpp') 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 @@ +#include #include #include #include @@ -8,8 +9,33 @@ #include "data.hpp" +// id, owner_id, parent_id, name, url, desc, visibility, time. +#define LINK_TUPLE_TYPES int64_t,int64_t,int64_t,std::string,std::string,std::string,int,int64_t + namespace { +using LinkTuple = std::tuple; +LinkItem linkFromTuple(const LinkTuple& t) +{ + LinkItem l; + l.id = std::get<0>(t); + l.owner_id = std::get<1>(t); + int64_t p = std::get<2>(t); + if(p == 0) + { + l.parent_id = std::nullopt; + } + else + { + l.parent_id = p; + } + l.name = std::get<3>(t); + l.url = std::get<4>(t); + l.description = std::get<5>(t); + l.visibility = static_cast(std::get<6>(t)); + l.time = mw::secondsToTime(std::get<7>(t)); + return l; +} } // namespace @@ -18,7 +44,7 @@ DataSourceSQLite::fromFile(const std::string& db_file) { auto data_source = std::make_unique(); ASSIGN_OR_RETURN(data_source->db, mw::SQLite::connectFile(db_file)); - + DO_OR_RETURN(data_source->db->execute("PRAGMA foreign_keys = ON;")); // Perform schema upgrade here. // // data_source->upgradeSchema1To2(); @@ -30,11 +56,12 @@ DataSourceSQLite::fromFile(const std::string& db_file) "(id INTEGER PRIMARY KEY, openid_uid TEXT, name TEXT);")); DO_OR_RETURN(data_source->db->execute( "CREATE TABLE IF NOT EXISTS LinkItems " - "(id INTEGER PRIMARY KEY," - " FOREIGN KEY(owner_id) REFERENCES Users(id) NOT NULL," - " FOREIGN KEY(parent_id) REFERENCES LinkItems(id)," + "(id INTEGER PRIMARY KEY, owner_id INTEGER NOT NULL," + " parent_id INTEGER," " name TEXT NOT NULL, url TEXT, description TEXT," - " visibility INTEGER NOT NULL, time INTEGER NOT NULL);")); + " visibility INTEGER NOT NULL, time INTEGER NOT NULL," + " FOREIGN KEY(owner_id) REFERENCES Users(id)," + " FOREIGN KEY(parent_id) REFERENCES LinkItems(id));")); return data_source; } @@ -52,3 +79,54 @@ mw::E DataSourceSQLite::setSchemaVersion(int64_t v) const { return db->execute(std::format("PRAGMA user_version = {};", v)); } + +mw::E> +DataSourceSQLite::items(std::optional parent) +{ + std::vector links; + if(!parent.has_value()) + { + // Querying root-level links. + ASSIGN_OR_RETURN(links, (db->eval( + "SELECT id, owner_id, parent_id, name, url, description, visibility," + " time from LinkItems WHERE parent_id IS NULL;"))); + } + else + { + ASSIGN_OR_RETURN(mw::SQLiteStatement stat, db->statementFromStr( + "SELECT id, owner_id, parent_id, name, url, description, visibility," + " time from LinkItems WHERE parent_id = ?;")); + DO_OR_RETURN(stat.bind(*parent)); + ASSIGN_OR_RETURN(links, (db->eval(std::move(stat)))); + } + std::vector result; + for(const LinkTuple& t : links) + { + result.push_back(linkFromTuple(t)); + } + return result; +} + +mw::E DataSourceSQLite::addLink(LinkItem&& link) +{ + ASSIGN_OR_RETURN(mw::SQLiteStatement sql, db->statementFromStr( + "INSERT INTO LinkItems (id, owner_id, parent_id, name, url," + " description, visibility, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")); + if(link.parent_id.has_value()) + { + DO_OR_RETURN(sql.bind( + std::nullopt, link.owner_id, *link.parent_id, link.name, link.url, + link.description, static_cast(link.visibility), + mw::timeToSeconds(mw::Clock::now()))); + } + else + { + DO_OR_RETURN(sql.bind( + std::nullopt, link.owner_id, std::nullopt, link.name, link.url, + link.description, static_cast(link.visibility), + mw::timeToSeconds(mw::Clock::now()))); + } + + DO_OR_RETURN(db->execute(std::move(sql))); + return db->lastInsertRowID(); +} -- cgit v1.2.3-70-g09d2