WIP: remove the old database abstraction layer
remove such classes: - DbBase - DbConn - DbTextStream - Db while here: - remove: TextStream, SLog, TexTextStream
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2021, Tomasz Sowa
|
||||
* Copyright (c) 2010-2024, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,313 +33,126 @@
|
||||
*/
|
||||
|
||||
#include "tdb.h"
|
||||
#include "core/log.h"
|
||||
|
||||
namespace Winix
|
||||
|
||||
namespace Winix::Thread
|
||||
{
|
||||
|
||||
|
||||
|
||||
namespace Thread
|
||||
void TDb::GetAnswers(long file_id, std::vector<ThreadFiles> & answer_id_tab)
|
||||
{
|
||||
morm::Finder<ThreadFiles> finder(model_connector);
|
||||
|
||||
|
||||
|
||||
//Error TDb::AddThread(const Thread & thread)
|
||||
//{
|
||||
// query.Clear();
|
||||
// query << R("insert into plugins.thread (file_id, replies, last_item, closed) values (")
|
||||
// << thread.file_id
|
||||
// << thread.replies
|
||||
// << thread.last_item_id
|
||||
// << (thread.closed ? 1 : 0 )
|
||||
// << R(");");
|
||||
//
|
||||
//return DoCommand(query);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
void TDb::SetThreadColumns(PGresult * r)
|
||||
{
|
||||
cfile_id = AssertColumn(r, "file_id");
|
||||
creplies = AssertColumn(r, "replies");
|
||||
cclosed = AssertColumn(r, "closed");
|
||||
// clast_item = AssertColumn(r, "last_item");
|
||||
// cdate_modification = AssertColumn(r, "date_modification");
|
||||
// cuser_id = AssertColumn(r, "user_id");
|
||||
// cguest = AssertColumn(r, "guest_name");
|
||||
finder.
|
||||
select().
|
||||
where().
|
||||
eq(L"file_id", file_id).
|
||||
get_vector(answer_id_tab);
|
||||
}
|
||||
|
||||
|
||||
void TDb::SetThread(PGresult * r, int col, Thread & thread)
|
||||
bool TDb::AddAnswer(long file_id, long answer_id)
|
||||
{
|
||||
thread.file_id = AssertValueLong(r, col, cfile_id);
|
||||
thread.replies = AssertValueLong(r, col, creplies);
|
||||
thread.closed = AssertValueBool(r, col, cclosed);
|
||||
//thread.last_item_id = AssertValueLong(r, col, clast_item);
|
||||
//thread.last_item_date_modification = AssertValueDate(r, col, cdate_modification);
|
||||
//thread.last_item_user_id = AssertValueLong(r, col, cuser_id);
|
||||
//AssertValueWide(r, col, cguest, thread.last_item_guest_name);
|
||||
}
|
||||
bool status = false;
|
||||
|
||||
ThreadFiles tf;
|
||||
tf.set_connector(model_connector);
|
||||
tf.clear();
|
||||
tf.file_id = file_id;
|
||||
tf.answer_id = answer_id;
|
||||
|
||||
|
||||
|
||||
//Error TDb::GetThread(long file_id, Thread & thread)
|
||||
//{
|
||||
// PGresult * r = 0;
|
||||
// Error status = WINIX_ERR_OK;
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// query.Clear();
|
||||
// query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, "
|
||||
// "item.date_modification, item.user_id, item.guest_name "
|
||||
// "from plugins.thread left join core.item on thread.last_item = item.id "
|
||||
// "where thread.file_id = ") << file_id << R(";");
|
||||
//
|
||||
// r = AssertQuery(query);
|
||||
// AssertResult(r, PGRES_TUPLES_OK);
|
||||
//
|
||||
// int rows = Rows(r);
|
||||
//
|
||||
// if( rows > 1 )
|
||||
// log << log1 << "ThreadDb: there is more than one thread with file_id: " << file_id << logend;
|
||||
// else
|
||||
// if( rows == 0 )
|
||||
// throw Error(WINIX_ERR_NO_THREAD);
|
||||
//
|
||||
// SetThreadColumns(r);
|
||||
// SetThread(r, 0, thread);
|
||||
// }
|
||||
// catch(const Error & e)
|
||||
// {
|
||||
// status = e;
|
||||
// }
|
||||
//
|
||||
// ClearResult(r);
|
||||
//
|
||||
//return status;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//Error TDb::GetThreads(const std::vector<long> & file_id_tab, std::vector<Thread> & thread_tab)
|
||||
//{
|
||||
// PGresult * r = 0;
|
||||
// Error status = WINIX_ERR_OK;
|
||||
// thread_tab.clear();
|
||||
//
|
||||
// if( file_id_tab.empty() )
|
||||
// return status;
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// CreateIdList(file_id_tab, list_id);
|
||||
//
|
||||
// // they should be sorted by file_id (they are used in a binary search later)
|
||||
// query.Clear();
|
||||
// query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, "
|
||||
// "item.date_modification, item.user_id, item.guest_name "
|
||||
// "from plugins.thread left join core.item on thread.last_item = item.id "
|
||||
// "where thread.file_id in ") << R(list_id) << R(" order by file_id asc;");
|
||||
//
|
||||
// r = AssertQuery(query);
|
||||
// AssertResult(r, PGRES_TUPLES_OK);
|
||||
//
|
||||
// int rows = Rows(r);
|
||||
// SetThreadColumns(r);
|
||||
//
|
||||
// for(int i=0 ; i<rows ; ++i)
|
||||
// {
|
||||
// SetThread(r, i, thread_temp);
|
||||
// thread_tab.push_back(thread_temp);
|
||||
// }
|
||||
// }
|
||||
// catch(const Error & e)
|
||||
// {
|
||||
// status = e;
|
||||
// }
|
||||
//
|
||||
// ClearResult(r);
|
||||
//
|
||||
//return status;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
Error TDb::GetAnswers(long file_id, std::vector<long> & answer_id_tab)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
Error status = WINIX_ERR_OK;
|
||||
answer_id_tab.clear();
|
||||
|
||||
try
|
||||
if( tf.insert(false) )
|
||||
{
|
||||
query.Clear();
|
||||
query << R("select answer_id from plugins.thread_files "
|
||||
"where file_id = ") << file_id << R(";");
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_TUPLES_OK);
|
||||
pt::TextStream query;
|
||||
query << "UPDATE plugins.thread SET (last_item, replies) = ("
|
||||
<< answer_id
|
||||
<< ", replies+1) WHERE file_id="
|
||||
<< file_id
|
||||
<< ";";
|
||||
|
||||
int rows = Rows(r);
|
||||
answer_id_tab.resize(rows);
|
||||
|
||||
for(int i=0 ; i<rows ; ++i)
|
||||
answer_id_tab[i] = AssertValueLong(r, i, 0);
|
||||
status = do_query(query);
|
||||
}
|
||||
catch(const Error & e)
|
||||
{
|
||||
status = e;
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Error TDb::AddAnswer(long file_id, long answer_id)
|
||||
{
|
||||
query.Clear();
|
||||
query << R("insert into plugins.thread_files (file_id, answer_id) values (")
|
||||
<< file_id
|
||||
<< answer_id
|
||||
<< R(");");
|
||||
|
||||
Error status = DoCommand(query);
|
||||
|
||||
if( status != WINIX_ERR_OK )
|
||||
return status;
|
||||
|
||||
query.Clear();
|
||||
query << R("update plugins.thread set (last_item, replies) = (")
|
||||
<< answer_id
|
||||
<< R(", replies+1) where file_id=")
|
||||
<< file_id
|
||||
<< R(";");
|
||||
|
||||
return DoCommand(query);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
long TDb::FindLastAnswer(long file_id)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
//Error status = WINIX_ERR_OK;
|
||||
morm::Finder<ThreadFiles> finder(model_connector);
|
||||
long last_item_id = -1;
|
||||
|
||||
try
|
||||
{
|
||||
query.Clear();
|
||||
query << R("select id from plugins.thread_files left join core.item on item.id=answer_id where file_id=")
|
||||
<< file_id
|
||||
<< R(" order by date_creation desc limit 1;");
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_TUPLES_OK);
|
||||
ThreadFiles tf = finder.
|
||||
select().
|
||||
raw("LEFT JOIN core.item ON item.id=thread_files.answer_id").
|
||||
raw("LEFT JOIN core.content ON item.content_id=content.id").
|
||||
where().
|
||||
eq(L"file_id", file_id).
|
||||
raw("ORDER BY content.date_creation DESC").
|
||||
raw("LIMIT 1;").
|
||||
get();
|
||||
|
||||
if( Rows(r) == 1 )
|
||||
last_item_id = AssertValueLong(r, 0, 0);
|
||||
}
|
||||
catch(const Error & e)
|
||||
{
|
||||
//status = e;
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
if( tf.found() )
|
||||
last_item_id = tf.answer_id;
|
||||
|
||||
return last_item_id;
|
||||
return last_item_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error TDb::RemoveAnswer(long answer_id)
|
||||
bool TDb::RemoveAnswer(long answer_id)
|
||||
{
|
||||
PGresult * r1 = 0;
|
||||
PGresult * r2 = 0;
|
||||
Error status = WINIX_ERR_OK;
|
||||
|
||||
try
|
||||
bool status = false;
|
||||
morm::Finder<ThreadFiles> finder(model_connector);
|
||||
|
||||
std::vector<ThreadFiles> thread_files;
|
||||
finder.select().where().eq(L"answer_id", answer_id).get_vector(thread_files);
|
||||
|
||||
file_id_tab.resize(thread_files.size());
|
||||
|
||||
for(size_t i=0 ; i<thread_files.size() ; ++i)
|
||||
{
|
||||
// selecting files which have answer_id as an answer
|
||||
query.Clear();
|
||||
query << R("select file_id from plugins.thread_files where answer_id = ")
|
||||
<< answer_id
|
||||
<< R(";");
|
||||
file_id_tab[i] = thread_files[i].file_id;
|
||||
}
|
||||
|
||||
r1 = AssertQuery(query);
|
||||
AssertResult(r1, PGRES_TUPLES_OK);
|
||||
|
||||
int rows = Rows(r1);
|
||||
file_id_tab.resize(rows);
|
||||
pt::TextStream query;
|
||||
query << "DELETE FROM plugins.thread_files WHERE answer_id = " << answer_id << ";";
|
||||
|
||||
for(int i=0 ; i<rows ; ++i)
|
||||
file_id_tab[i] = AssertValueLong(r1, i, 0);
|
||||
|
||||
|
||||
// deleting those answers
|
||||
query.Clear();
|
||||
query << R("delete from plugins.thread_files where answer_id = ")
|
||||
<< answer_id
|
||||
<< R(";");
|
||||
|
||||
r2 = AssertQuery(query);
|
||||
AssertResult(r2, PGRES_COMMAND_OK);
|
||||
|
||||
rows = AffectedRows(r2);
|
||||
|
||||
if( rows > 0 )
|
||||
log << log2 << "ThreadDb: deleted " << rows << " rows from plugins.thread_files" << logend;
|
||||
|
||||
// setting new last_items to the files
|
||||
if( do_query(query) )
|
||||
{
|
||||
status = RemoveAnswerRecalcLast(file_id_tab);
|
||||
}
|
||||
catch(const Error & e)
|
||||
{
|
||||
status = e;
|
||||
}
|
||||
|
||||
ClearResult(r1);
|
||||
ClearResult(r2);
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
Error TDb::RemoveAnswerRecalcLast(long file_id)
|
||||
bool TDb::RemoveAnswerRecalcLast(long file_id)
|
||||
{
|
||||
long last_item_id = FindLastAnswer(file_id);
|
||||
|
||||
query.Clear();
|
||||
query << R("update plugins.thread set (replies, last_item) = (replies-1,")
|
||||
pt::TextStream query;
|
||||
query << "UPDATE plugins.thread SET (replies, last_item) = (replies-1,"
|
||||
<< last_item_id
|
||||
<< R(") where file_id=")
|
||||
<< ") WHERE file_id="
|
||||
<< file_id
|
||||
<< R(";");
|
||||
<< ";";
|
||||
|
||||
return DoCommand(query);
|
||||
return do_query(query);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error TDb::RemoveAnswerRecalcLast(const std::vector<long> & file_id_tab)
|
||||
bool TDb::RemoveAnswerRecalcLast(const std::vector<long> & file_id_tab)
|
||||
{
|
||||
for(size_t i=0 ; i<file_id_tab.size() ; ++i)
|
||||
bool status = true;
|
||||
|
||||
for(size_t i=0 ; status && i < file_id_tab.size() ; ++i)
|
||||
{
|
||||
long file_id = file_id_tab[i];
|
||||
Error status = RemoveAnswerRecalcLast(file_id);
|
||||
|
||||
if( status != WINIX_ERR_OK )
|
||||
return status;
|
||||
status = RemoveAnswerRecalcLast(file_id);
|
||||
}
|
||||
|
||||
return WINIX_ERR_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -348,155 +161,89 @@ Error TDb::RecalcThread(long file_id)
|
||||
long replies = CalcAnswers(file_id);
|
||||
long last_item = FindLastAnswer(file_id);
|
||||
|
||||
query.Clear();
|
||||
query << R("update plugins.thread set (replies, last_item) = (")
|
||||
pt::TextStream query;
|
||||
query << "UPDATE plugins.thread SET (replies, last_item) = ("
|
||||
<< replies
|
||||
<< last_item
|
||||
<< R(") where file_id=")
|
||||
<< ") WHERE file_id="
|
||||
<< file_id
|
||||
<< R(";");
|
||||
<< ";";
|
||||
|
||||
return DoCommand(query);
|
||||
return do_query(query);
|
||||
}
|
||||
|
||||
|
||||
long TDb::CalcAnswers(long file_id)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
morm::Finder<ThreadFiles> finder(model_connector);
|
||||
long answers = 0;
|
||||
|
||||
try
|
||||
{
|
||||
query.Clear();
|
||||
query << R("select count(file_id) from plugins.thread_files where file_id=") << file_id << R(";");
|
||||
ThreadFiles tf = finder.
|
||||
select(morm::Select::no_auto_generated_columns).
|
||||
raw("SELECT COUNT(file_id) as file_id FROM plugins.thread_files").
|
||||
where().
|
||||
eq(L"file_id", file_id).
|
||||
get();
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_TUPLES_OK);
|
||||
if( tf.found() )
|
||||
answers = tf.file_id;
|
||||
|
||||
if( Rows(r) == 1 )
|
||||
answers = AssertValueLong(r, 0, 0);
|
||||
}
|
||||
catch(const Error &)
|
||||
{
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
return answers;
|
||||
return answers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Error TDb::RemoveThread(long file_id)
|
||||
bool TDb::RemoveThread(long file_id)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
Error status = WINIX_ERR_OK;
|
||||
|
||||
try
|
||||
bool status = false;
|
||||
|
||||
pt::TextStream query;
|
||||
query << "DELETE FROM plugins.thread WHERE file_id=" << file_id;
|
||||
|
||||
if( do_query(query) )
|
||||
{
|
||||
query.Clear();
|
||||
query << R("delete from plugins.thread where file_id=") << file_id << R(";");
|
||||
query.clear();
|
||||
query << "DELETE FROM plugins.thread_files WHERE file_id=" << file_id;
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_COMMAND_OK);
|
||||
|
||||
long rows = AffectedRows(r);
|
||||
|
||||
if( rows > 0 )
|
||||
log << log2 << "ThreadDb: deleted " << rows << " rows from plugins.thread" << logend;
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
query.Clear();
|
||||
query << R("delete from plugins.thread_files where file_id=") << file_id << R(";");
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_COMMAND_OK);
|
||||
|
||||
rows = AffectedRows(r);
|
||||
|
||||
if( rows > 0 )
|
||||
log << log2 << "ThreadDb: deleted " << rows << " rows from plugins.thread_files" << logend;
|
||||
status = do_query(query);
|
||||
}
|
||||
catch(const Error & e)
|
||||
{
|
||||
status = e;
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error TDb::RemoveAnswerOnly(long answer_id)
|
||||
bool TDb::RemoveAnswerOnly(long answer_id)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
Error status = WINIX_ERR_OK;
|
||||
|
||||
try
|
||||
{
|
||||
query.Clear();
|
||||
query << R("delete from plugins.thread_files where answer_id=") << answer_id << R(";");
|
||||
pt::TextStream query;
|
||||
query << "DELETE FROM plugins.thread_files WHERE answer_id=" << answer_id;
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_COMMAND_OK);
|
||||
|
||||
long rows = AffectedRows(r);
|
||||
|
||||
if( rows > 0 )
|
||||
log << log2 << "ThreadDb: deleted " << rows << " rows from plugins.thread_files" << logend;
|
||||
}
|
||||
catch(const Error & e)
|
||||
{
|
||||
status = e;
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
return status;
|
||||
return do_query(query);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void TDb::GetAllThreadsId(std::vector<long> & file_id)
|
||||
// this method reads all threads, need to be refactored
|
||||
void TDb::GetAllThreads(std::vector<Thread> & threads)
|
||||
{
|
||||
PGresult * r = 0;
|
||||
file_id.clear();
|
||||
|
||||
try
|
||||
morm::Finder<Thread> finder(model_connector);
|
||||
finder.select().get_vector(threads);
|
||||
}
|
||||
|
||||
|
||||
bool TDb::do_query(pt::TextStream & query)
|
||||
{
|
||||
if( model_connector)
|
||||
{
|
||||
query.Clear();
|
||||
query << R("select file_id from plugins.thread;");
|
||||
morm::DbConnector * db_connector = model_connector->get_db_connector();
|
||||
|
||||
r = AssertQuery(query);
|
||||
AssertResult(r, PGRES_TUPLES_OK);
|
||||
|
||||
int rows = Rows(r);
|
||||
file_id.resize(rows);
|
||||
|
||||
for(int i=0 ; i<rows ; ++i)
|
||||
file_id[i] = AssertValueLong(r, i, 0);
|
||||
if( db_connector )
|
||||
{
|
||||
return db_connector->query(query);
|
||||
}
|
||||
}
|
||||
catch(const Error &)
|
||||
{
|
||||
}
|
||||
|
||||
ClearResult(r);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
} // namespace Winix
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user