You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
12 KiB
367 lines
12 KiB
#include "listmanager_dummy.hh"
|
|
#include "pEpSQLite.hh"
|
|
#include <exception>
|
|
|
|
using namespace std;
|
|
|
|
namespace pEp {
|
|
bool ListManagerDummy::log_enabled = false;
|
|
|
|
// public
|
|
ListManagerDummy::ListManagerDummy(const string& db_path) : db(pEpSQLite(db_path))
|
|
{
|
|
pEpLogClass("called");
|
|
}
|
|
|
|
// private
|
|
void ListManagerDummy::ensure_db_initialized()
|
|
{
|
|
if (!db.is_open()) {
|
|
is_db_initialized = false;
|
|
try {
|
|
db.create_or_open_db();
|
|
} catch (...) {
|
|
db.close_db();
|
|
DBException e{ "ListManagerDummy - error opening db" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
if (!is_db_initialized) {
|
|
try {
|
|
db_config();
|
|
create_tables();
|
|
} catch (...) {
|
|
db.close_db();
|
|
DBException e{ "ListManagerDummy - db init failed" };
|
|
throw_with_nested(e);
|
|
}
|
|
is_db_initialized = true;
|
|
}
|
|
}
|
|
|
|
// private
|
|
void ListManagerDummy::db_config()
|
|
{
|
|
try {
|
|
string sql;
|
|
sql = "PRAGMA foreign_keys=ON";
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy - db config failed" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// private
|
|
void ListManagerDummy::create_tables()
|
|
{
|
|
try {
|
|
string sql;
|
|
|
|
sql = "CREATE TABLE IF NOT EXISTS lists("
|
|
"address TEXT NOT NULL,"
|
|
"moderator_address TEXT NOT NULL,"
|
|
"PRIMARY KEY(address));";
|
|
db.execute(sql);
|
|
|
|
sql = "CREATE TABLE IF NOT EXISTS member_of("
|
|
"address TEXT NOT NULL,"
|
|
"list_address TEXT NOT NULL,"
|
|
"PRIMARY KEY (address, list_address),"
|
|
"FOREIGN KEY(list_address) REFERENCES lists(address) ON DELETE CASCADE);";
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e("ListManagerDummy - create tables failed");
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::close_db()
|
|
{
|
|
pEpLogClass("called");
|
|
db.close_db();
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::delete_db()
|
|
{
|
|
pEpLogClass("called");
|
|
try {
|
|
db.delete_db();
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: delete_db() failed" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::list_add(const std::string& addr_list, const std::string& addr_mgr)
|
|
{
|
|
pEpLogClass("list_add(addr_list: \"" + addr_list + "\", addr_mgr: \"" + addr_mgr + "\")");
|
|
if (list_exists(addr_list)) {
|
|
AlreadyExistsException e{ "list_add(addr_list: \"" + addr_list + "\", addr_mgr: \"" +
|
|
addr_mgr + "\") - List already exists" };
|
|
throw e;
|
|
}
|
|
|
|
try {
|
|
string sql = "INSERT INTO lists(address, moderator_address) VALUES ('" + addr_list +
|
|
"','" + addr_mgr + "');";
|
|
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: list_add(addr_list: \"" + addr_list +
|
|
"\"\taddr_mgr: \"" + addr_mgr + "\") - failed with exception" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::list_delete(const std::string& addr_list)
|
|
{
|
|
pEpLogClass("list_delete(addr_list: \"" + addr_list + "\")");
|
|
if (!list_exists(addr_list)) {
|
|
ListDoesNotExistException e{ "list_delete(addr_list: \"" + addr_list +
|
|
"\") - List does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
try {
|
|
string sql;
|
|
sql = "DELETE FROM lists WHERE lists.address = '" + addr_list + "';";
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: list_delete(addr_list: \"" + addr_list +
|
|
"\") - failed with exception" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::member_add(const std::string& addr_list, const std::string& addr_member)
|
|
{
|
|
pEpLogClass(
|
|
"member_add(addr_list: \"" + addr_list + "\", addr_member: \"" + addr_member + "\")");
|
|
if (!list_exists(addr_list)) {
|
|
ListDoesNotExistException e{ "member_add(addr_list: \"" + addr_list + "\", addr_member: \"" +
|
|
addr_member + "\") - list does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
if (member_exists(addr_list, addr_member)) {
|
|
AlreadyExistsException e{ "member_add(addr_list: \"" + addr_list + "\", addr_member: \"" +
|
|
addr_member + "\") - member already exists" };
|
|
throw e;
|
|
}
|
|
|
|
try {
|
|
string sql = "INSERT INTO member_of(address, list_address) VALUES ('" + addr_member +
|
|
"', '" + addr_list + "');";
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: member_add(addr_list: \"" + addr_list +
|
|
"\", addr_member: \"" + addr_member + "\") - failed with exception" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
void ListManagerDummy::member_remove(const std::string& addr_list, const std::string& addr_member)
|
|
{
|
|
pEpLogClass(
|
|
"member_remove(addr_list: \"" + addr_list + "\", addr_member: '\"" + addr_member + "\")");
|
|
if (!list_exists(addr_list)) {
|
|
ListDoesNotExistException e{ "member_remove(addr_list: \"" + addr_list +
|
|
"\", addr_member: '\"" + addr_member +
|
|
"\") - list does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
if (!member_exists(addr_list, addr_member)) {
|
|
MemberDoesNotExistException e{ "member_remove(addr_list: \"" + addr_list +
|
|
"\", addr_member: '\"" + addr_member +
|
|
"\") - member does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
try {
|
|
string sql;
|
|
sql = "DELETE FROM member_of WHERE (member_of.address = '" + addr_member +
|
|
"') AND (member_of.list_address = '" + addr_list + "');";
|
|
db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: member_remove(" + addr_list + ", " + addr_member +
|
|
") - failed with exception" };
|
|
throw_with_nested(e);
|
|
}
|
|
}
|
|
|
|
// public
|
|
std::vector<std::string> ListManagerDummy::lists()
|
|
{
|
|
pEpLogClass("called");
|
|
ensure_db_initialized();
|
|
vector<string> ret;
|
|
ResultSet rs;
|
|
|
|
try {
|
|
string sql;
|
|
sql = "SELECT address FROM lists";
|
|
rs = db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: lists() failed" };
|
|
throw_with_nested(e);
|
|
}
|
|
|
|
for (const RSRecord& rec : rs) {
|
|
ret.push_back(rec.at("address"));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// public
|
|
std::string ListManagerDummy::moderator(const std::string& addr_list)
|
|
{
|
|
pEpLogClass("moderator(list_address:\"" + addr_list + "\")");
|
|
if (!list_exists(addr_list)) {
|
|
ListDoesNotExistException e{ "moderator(list_address:\"" + addr_list +
|
|
"\") - List does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
string ret;
|
|
ResultSet rs;
|
|
|
|
try {
|
|
string sql;
|
|
sql = "SELECT moderator_address FROM lists "
|
|
"WHERE lists.address = '" +
|
|
addr_list + "';";
|
|
rs = db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: moderator(list_address:\"" + addr_list +
|
|
"\") - failed" };
|
|
throw_with_nested(e);
|
|
}
|
|
|
|
if (!rs.empty()) {
|
|
for (const RSRecord& rec : rs) {
|
|
ret = rec.at("moderator_address");
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// public
|
|
std::vector<std::string> ListManagerDummy::members(const std::string& addr_list)
|
|
{
|
|
pEpLogClass("members(list_address:\"" + addr_list + "\")");
|
|
if (!list_exists(addr_list)) {
|
|
ListDoesNotExistException e{ "members(list_address:\"" + addr_list +
|
|
"\") - List does not exist" };
|
|
throw e;
|
|
}
|
|
|
|
vector<string> ret;
|
|
ResultSet rs;
|
|
|
|
try {
|
|
string sql;
|
|
sql = "SELECT address FROM member_of "
|
|
"WHERE list_address = '" +
|
|
addr_list + "'";
|
|
rs = db.execute(sql);
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: members(list_address:\"" + addr_list + "\")" };
|
|
throw_with_nested(e);
|
|
}
|
|
|
|
if (!rs.empty()) {
|
|
for (const RSRecord& rec : rs) {
|
|
ret.push_back(rec.at("address"));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool ListManagerDummy::list_exists(const std::string& addr_list)
|
|
{
|
|
pEpLogClass("list_exists(addr_list:\"" + addr_list + "\")");
|
|
bool ret{ false };
|
|
ensure_db_initialized();
|
|
|
|
ResultSet rs;
|
|
int rescount = 0;
|
|
try {
|
|
string sql;
|
|
sql = "SELECT COUNT(address) AS rescount "
|
|
"FROM lists "
|
|
"WHERE address = '" +
|
|
addr_list + "';";
|
|
rs = db.execute(sql);
|
|
rescount = pEpSQLite::eval_sql_count(rs, "rescount");
|
|
} catch (...) {
|
|
DBException e{ "ListManagerDummy: list_exists(addr_list:\"" + addr_list + "\")" };
|
|
throw_with_nested(e);
|
|
}
|
|
// Check FATAL inconsistency
|
|
if (rescount > 1) {
|
|
DBException e{ "ListManagerDummy: list_exists(addr_list:\"" + addr_list +
|
|
"\") - FATAL DB CONSTRAINT ERROR: list exists more than once" };
|
|
throw_with_nested(e);
|
|
}
|
|
|
|
if (rescount == 1) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ListManagerDummy::member_exists(const std::string& addr_list, const std::string& addr_member)
|
|
{
|
|
pEpLogClass(
|
|
"member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" + addr_member + "\")");
|
|
bool ret{ false };
|
|
ensure_db_initialized();
|
|
|
|
ResultSet rs;
|
|
int rescount = 0;
|
|
try {
|
|
string sql;
|
|
sql = "SELECT COUNT(address) AS rescount "
|
|
"FROM member_of "
|
|
"WHERE (address = '" +
|
|
addr_member + "' AND list_address = '" + addr_list + "');";
|
|
rs = db.execute(sql);
|
|
rescount = pEpSQLite::eval_sql_count(rs, "rescount");
|
|
} catch (...) {
|
|
DBException e{ "member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" +
|
|
addr_member + "\")" };
|
|
throw_with_nested(e);
|
|
}
|
|
// Check FATAL inconsistency
|
|
if (rescount > 1) {
|
|
DBException e{ "member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" +
|
|
addr_member +
|
|
"\") - FATAL DB CONSTRAINT ERROR: list exists more than once" };
|
|
throw_with_nested(e);
|
|
}
|
|
|
|
if (rescount == 1) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
// public
|
|
ListManagerDummy::~ListManagerDummy()
|
|
{
|
|
pEpLogClass("called");
|
|
db.close_db();
|
|
}
|
|
} // namespace pEp
|