winix/plugins/thread/tdb.cpp

278 lines
5.9 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "tdb.h"
#include "core/log.h"
namespace Thread
{
Error Db::GetThreadByDirId(long dir_id, Thread & thread)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
query.Clear();
query << R("select thread.id, thread.parent_id, thread.dir_id, thread.closed, thread.items, "
"thread.last_item, item.date_modification, item.user_id "
"from core.thread left join core.item on thread.last_item = item.id "
"where thread.dir_id = ") << dir_id << R(";");
r = AssertQuery(query);
AssertResult(r, PGRES_TUPLES_OK);
int rows = Rows(r);
if( rows > 1 )
log << log1 << "Db: there is more than one thread with dir_id: " << dir_id << logend;
else
if( rows == 0 )
throw Error(WINIX_ERR_NO_THREAD);
int cid = AssertColumn(r, "id");
int cparent_id = AssertColumn(r, "parent_id");
int cdir_id = AssertColumn(r, "dir_id");
int cclosed = AssertColumn(r, "closed");
int citems = AssertColumn(r, "items");
int clast_item = AssertColumn(r, "last_item");
int cdate_modification = PQfnumber(r, "date_modification"); // !! tych kolumn mo¿e nie byæ? czemu PQfnumber a nie AssertColumn?
int cuser_id = PQfnumber(r, "user_id");
thread.id = AssertValueLong(r, 0, cid);
thread.parent_id = AssertValueLong(r, 0, cparent_id);
thread.dir_id = AssertValueLong(r, 0, cdir_id);
thread.closed = AssertValueLong(r, 0, cclosed) == 0 ? false : true;
thread.items = AssertValueLong(r, 0, citems);
thread.last_item.id = AssertValueLong(r, 0, clast_item);
thread.last_item.date_modification = AssertValueTm(r, 0, cdate_modification);
thread.last_item.user_id = AssertValueLong(r, 0, cuser_id);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error Db::GetThreads(long parent_id, std::vector<Thread> & thread_tab)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
query.Clear();
query << R("select thread.id, thread.parent_id, thread.dir_id, thread.closed, "
"thread.items, thread.last_item, item.date_modification, item.user_id, item.guest_name "
"from core.thread left join core.item on thread.last_item = item.id "
"where thread.parent_id = ") << parent_id << R(" order by date_modification asc;");
r = AssertQuery(query);
AssertResult(r, PGRES_TUPLES_OK);
int rows = Rows(r);
Thread thread;
int cid = AssertColumn(r, "id");
int cparent_id = AssertColumn(r, "parent_id");
int cdir_id = AssertColumn(r, "dir_id");
int cclosed = AssertColumn(r, "closed");
int citems = AssertColumn(r, "items");
int clast_item = AssertColumn(r, "last_item");
int cdate_modification = PQfnumber(r, "date_modification"); // !! czemu tutaj jest pqfnumber zamiast assertcolumn?
int cuser_id = PQfnumber(r, "user_id");
int cguest_name = PQfnumber(r, "guest_name");
for(int i=0 ; i<rows ; ++i)
{
thread.id = AssertValueLong(r, i, cid);
thread.parent_id = AssertValueLong(r, i, cparent_id);
thread.dir_id = AssertValueLong(r, i, cdir_id);
thread.closed = AssertValueLong(r, i, cclosed) == 0 ? false : true;
thread.items = AssertValueLong(r, i, citems);
thread.last_item.id = AssertValueLong(r, i, clast_item);
thread.last_item.date_modification = AssertValueTm(r, i, cdate_modification);
thread.last_item.user_id = AssertValueLong(r, i, cuser_id);
thread.last_item.guest_name = AssertValueWide(r, i, cguest_name);
thread_tab.push_back(thread);
}
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error Db::AddThread(Thread & thread)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
query.Clear();
query << R("insert into core.thread (parent_id, dir_id, closed, items, last_item) values (")
<< thread.parent_id
<< thread.dir_id
<< (thread.closed ? 1 : 0 )
<< thread.items
<< thread.last_item.id
<< R(");");
r = AssertQuery(query);
AssertResult(r, PGRES_COMMAND_OK);
thread.id = AssertCurrval("core.thread_id_seq");
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error Db::EditThreadAddItem(long dir_id, long item_id)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
query.Clear();
query << R("update core.thread set (last_item, items) = (")
<< item_id
<< R(", items+1) where dir_id=")
<< dir_id
<< R(";");
r = AssertQuery(query);
AssertResult(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error Db::EditThreadRemoveItem(long dir_id)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
long last_item_id = -1;
query.Clear();
query << R("select id from core.item where parent_id=")
<< dir_id
<< R(" order by date_creation desc limit 1;");
r = AssertQuery(query);
AssertResult(r, PGRES_TUPLES_OK);
if( Rows(r) == 1 )
last_item_id = AssertValueLong(r, 0, 0);
ClearResult(r);
query.Clear();
query << R("update core.thread set (items, last_item) = (items-1,")
<< last_item_id
<< R(") where dir_id=")
<< dir_id
<< R(";");
r = AssertQuery(query);
AssertResult(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error Db::RemoveThread(long dir_id)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
query.Clear();
query << R("delete from core.thread where dir_id=") << dir_id << R(";");
r = AssertQuery(query);
AssertResult(r, PGRES_COMMAND_OK);
long rows = AffectedRows(r);
if( rows > 0 )
log << log2 << "Db: deleted " << rows << " rows from core.thread" << logend;
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
} // namespace