2008-12-10 05:42:49 +01:00
/*
* This file is a part of CMSLU - - Content Management System like Unix
* and is not publicly distributed
*
* Copyright ( c ) 2008 , Tomasz Sowa
* All rights reserved .
*
*/
# include "db.h"
Db : : Db ( )
{
pg_conn = 0 ;
}
Db : : ~ Db ( )
{
Close ( ) ;
}
void Db : : Init ( const std : : string & d , const std : : string & u , const std : : string & p )
{
db_database = d ;
db_user = u ;
db_pass = p ;
Connect ( ) ;
}
void Db : : Connect ( )
{
2008-12-11 03:46:16 +01:00
Close ( ) ;
2008-12-10 05:42:49 +01:00
std : : ostringstream buf ;
buf < < " dbname= " < < db_database < < " user= " < < db_user < < " password= " < < db_pass ;
pg_conn = PQconnectdb ( buf . str ( ) . c_str ( ) ) ;
if ( ! pg_conn )
log < < log1 < < " Db: Fatal error during connecting " < < logend ;
if ( PQsetClientEncoding ( pg_conn , " LATIN2 " ) = = - 1 )
log < < log1 < < " Db: Can't set the proper client encoding " < < logend ;
}
void Db : : Close ( )
{
if ( pg_conn )
{
PQfinish ( pg_conn ) ;
pg_conn = 0 ;
}
}
void Db : : AssertConnection ( )
{
if ( ! pg_conn )
{
log < < log1 < < " Db: Trying to connect into the database... " ;
Connect ( ) ;
if ( ! pg_conn )
// logend from Connect()
throw Error ( Error : : db_fatal_error_during_connecting ) ;
log < < log1 < < " ok " < < logend ;
}
if ( PQstatus ( pg_conn ) ! = CONNECTION_OK )
{
log < < log2 < < " Db: connection into the database is lost, trying to recover... " < < logend ;
PQreset ( pg_conn ) ;
if ( PQstatus ( pg_conn ) ! = CONNECTION_OK )
{
log < < log2 < < " no " < < logend ;
throw Error ( Error : : db_fatal_error_during_connecting ) ;
}
else
{
log < < log2 < < " ok " < < logend ;
2008-12-21 22:17:09 +01:00
if ( PQsetClientEncoding ( pg_conn , " LATIN2 " ) = = - 1 )
log < < log1 < < " Db: Can't set the proper client encoding " < < logend ;
2008-12-10 05:42:49 +01:00
}
}
}
std : : string Db : : Escape ( const std : : string & s )
{
std : : string result ;
result . resize ( s . length ( ) * 2 + 1 ) ;
size_t len = PQescapeStringConn ( pg_conn , const_cast < char * > ( result . c_str ( ) ) , s . c_str ( ) , s . length ( ) , 0 ) ;
result . resize ( len ) ;
return result ;
}
std : : string Db : : Escape ( const char * s )
{
std : : string result ;
int len ;
for ( len = 0 ; s [ len ] ! = 0 ; + + len ) ;
result . resize ( len * 2 + 1 ) ;
size_t len_new = PQescapeStringConn ( pg_conn , const_cast < char * > ( result . c_str ( ) ) , s , len , 0 ) ;
result . resize ( len_new ) ;
return result ;
}
// ------------------
PGresult * Db : : AssertQuery ( const std : : string & q )
{
PGresult * r = PQexec ( pg_conn , q . c_str ( ) ) ;
if ( ! r )
{
log < < log1 < < " Db: Problem with query: " < < PQerrorMessage ( pg_conn ) < < logend ;
throw Error ( Error : : db_incorrect_query ) ;
}
return r ;
}
void Db : : AssertResultStatus ( PGresult * r , ExecStatusType t )
{
if ( PQresultStatus ( r ) ! = t )
{
log < < " Db: Incorrect result status: " < < PQerrorMessage ( pg_conn ) < < logend ;
throw Error ( Error : : db_incorrent_result_status ) ;
}
}
int Db : : AssertColumn ( PGresult * r , const char * column_name )
{
int c = PQfnumber ( r , column_name ) ;
if ( c = = - 1 )
{
log < < log1 < < " Db: there is no column: " < < column_name < < logend ;
throw Error ( Error : : db_no_column ) ;
}
return c ;
}
const char * Db : : AssertValue ( PGresult * r , int row , int col )
{
const char * res = PQgetvalue ( r , row , col ) ;
if ( ! res )
{
log < < log1 < < " Db: there is no such an item in the result, row: " < < row < < " , col: " < < col < < logend ;
throw Error ( Error : : db_no_item ) ;
}
return res ;
}
2008-12-14 06:28:28 +01:00
2008-12-10 05:42:49 +01:00
void Db : : ClearResult ( PGresult * r )
{
if ( r )
PQclear ( r ) ;
}
bool Db : : CheckUser ( std : : string & login , std : : string & password , long & user_id )
{
PGresult * r = 0 ;
bool user_ok = false ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select id from core.user where login=' " < < Escape ( login ) < < " ' and password=' " < < Escape ( password ) < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
int rows = PQntuples ( r ) ;
if ( rows = = 0 )
throw Error ( Error : : db_incorrect_login ) ;
if ( rows > 1 )
{
log < < log1 < < " Db: there is more than one user: " < < login < < " (with the same password) " < < logend ;
throw Error ( Error : : db_more_than_one_login ) ;
}
int cuser_id = AssertColumn ( r , " id " ) ;
const char * fuser_id = AssertValue ( r , 0 , cuser_id ) ;
user_id = atol ( fuser_id ) ;
user_ok = true ;
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
return user_ok ;
}
bool Db : : AddItemCreateUrlSubject ( Item & item )
{
bool is_that_url ;
PGresult * r = 0 ;
int index = 1 ;
const int max_index = 100 ;
char appendix [ 20 ] ;
appendix [ 0 ] = 0 ;
try
{
do
{
std : : ostringstream query ;
// this Escape can be put at the beginning (performance)
2008-12-14 06:28:28 +01:00
query < < " select id from core.item where url=' " < < Escape ( item . url ) < < appendix < < " ' and parent_id=' " < < item . parent_id < < " '; " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
if ( PQntuples ( r ) ! = 0 )
{
sprintf ( appendix , " _(%d) " , + + index ) ;
is_that_url = true ;
}
else
{
2008-12-14 06:28:28 +01:00
item . url + = appendix ;
2008-12-10 05:42:49 +01:00
is_that_url = false ;
}
ClearResult ( r ) ;
r = 0 ;
}
while ( is_that_url & & index < = max_index ) ;
}
catch ( const Error & )
{
is_that_url = true ; // for return false
}
ClearResult ( r ) ;
return ! is_that_url ;
}
// for testing consistency
void Db : : CheckAllUrlSubjectModifyItem ( Item & item )
{
PGresult * r = 0 ;
try
{
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " update core.item set url= " ;
2008-12-10 05:42:49 +01:00
2008-12-14 06:28:28 +01:00
// url
2008-12-10 05:42:49 +01:00
if ( AddItemCreateUrlSubject ( item ) )
2008-12-14 06:28:28 +01:00
query < < ' \' ' < < Escape ( item . url ) < < ' \' ' ;
2008-12-10 05:42:49 +01:00
else
{
query < < ' \' ' < < item . id < < ' \' ' ;
2008-12-14 06:28:28 +01:00
item . url . clear ( ) ;
2008-12-10 05:42:49 +01:00
}
query < < " where id=' " < < item . id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
// for checking consistency
void Db : : CheckAllUrlSubject ( )
{
PGresult * r = 0 ;
Item item ;
try
{
AssertConnection ( ) ;
std : : ostringstream query , query2 ;
2008-12-14 06:28:28 +01:00
query < < " select item.id, subject from core.item left join core.content on item.content_id = content.id where url is null or url='' " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
int rows = PQntuples ( r ) ;
int cid = AssertColumn ( r , " id " ) ;
int csubject = AssertColumn ( r , " subject " ) ;
for ( int i = 0 ; i < rows ; + + i )
{
2008-12-14 06:28:28 +01:00
item . id = atol ( AssertValue ( r , i , cid ) ) ;
2008-12-10 05:42:49 +01:00
item . subject = AssertValue ( r , i , csubject ) ;
CheckAllUrlSubjectModifyItem ( item ) ;
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
long Db : : AssertCurrval ( const char * table )
{
PGresult * r ;
std : : ostringstream query ;
query < < " select currval(' " < < table < < " '); " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
if ( PQntuples ( r ) ! = 1 )
{
log < < log1 < < " Db: error (currval) for table: " < < table < < " , " < < PQerrorMessage ( pg_conn ) < < logend ;
throw Error ( Error : : db_err_currval ) ;
}
long res = strtol ( AssertValue ( r , 0 , 0 ) , 0 , 10 ) ;
return res ;
}
2008-12-14 06:28:28 +01:00
Error Db : : AddItemIntoItem ( Item & item )
2008-12-10 05:42:49 +01:00
{
PGresult * r = 0 ;
Error result = Error : : ok ;
bool url_without_id = false ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " insert into core.item (user_id, group_id, privileges, type, parent_id, content_id, url) values ( " ;
query < < ' \' ' < < item . user_id < < " ', " ;
query < < ' \' ' < < item . group_id < < " ', " ;
query < < ' \' ' < < item . privileges < < " ', " ;
query < < ' \' ' < < static_cast < int > ( item . type ) < < " ', " ;
query < < ' \' ' < < item . parent_id < < " ', " ;
query < < ' \' ' < < item . content_id < < " ', " ;
2008-12-10 05:42:49 +01:00
url_without_id = AddItemCreateUrlSubject ( item ) ;
if ( url_without_id )
2008-12-14 06:28:28 +01:00
query < < ' \' ' < < Escape ( item . url ) < < " '); " ;
2008-12-10 05:42:49 +01:00
else
2008-12-14 06:28:28 +01:00
query < < " currval('core.item_id_seq') " < < " ); " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
item . id = AssertCurrval ( " core.item_id_seq " ) ;
if ( ! url_without_id )
2008-12-14 06:28:28 +01:00
ToString ( item . url , item . id ) ;
2008-12-10 05:42:49 +01:00
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
2008-12-14 06:28:28 +01:00
Error Db : : AddItemIntoContent ( Item & item )
{
PGresult * r = 0 ;
Error result = Error : : ok ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " insert into core.content (subject, content, content_type) values ( " ;
query < < ' \' ' < < Escape ( item . subject ) < < " ', " ;
query < < ' \' ' < < Escape ( item . content ) < < " ', " ;
query < < ' \' ' < < item . content_type < < " '); " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
item . content_id = AssertCurrval ( " core.content_id_seq " ) ;
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
Error Db : : AddItem ( Item & item )
{
Error result = AddItemIntoContent ( item ) ;
if ( result = = Error : : ok )
result = AddItemIntoItem ( item ) ;
return result ;
}
Error Db : : EditItemInItem ( Item & item , bool with_subject )
2008-12-10 05:42:49 +01:00
{
PGresult * r = 0 ;
Error result = Error : : ok ;
bool url_without_id = false ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
2008-12-21 22:17:09 +01:00
query < < " update core.item set (user_id, group_id, privileges, type, parent_id " ;
2008-12-10 05:42:49 +01:00
if ( with_subject )
2008-12-21 22:17:09 +01:00
query < < " , url " ;
2008-12-10 05:42:49 +01:00
2008-12-14 06:28:28 +01:00
query < < " ) = ( " ;
query < < ' \' ' < < item . user_id < < " ', " ;
query < < ' \' ' < < item . group_id < < " ', " ;
query < < ' \' ' < < item . privileges < < " ', " ;
query < < ' \' ' < < static_cast < int > ( item . type ) < < " ', " ;
query < < ' \' ' < < item . parent_id < < " ' " ;
2008-12-10 05:42:49 +01:00
if ( with_subject )
{
url_without_id = AddItemCreateUrlSubject ( item ) ;
if ( url_without_id )
2008-12-14 06:28:28 +01:00
query < < " , ' " < < Escape ( item . url ) < < " ' " ;
2008-12-10 05:42:49 +01:00
else
2008-12-14 06:28:28 +01:00
query < < " , ' " < < item . id < < " ' " ;
2008-12-10 05:42:49 +01:00
}
query < < " ) where id=' " < < item . id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
if ( with_subject & & ! url_without_id )
2008-12-14 06:28:28 +01:00
ToString ( item . url , item . id ) ;
2008-12-10 05:42:49 +01:00
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
2008-12-14 06:28:28 +01:00
Error Db : : EditItemInContent ( Item & item )
{
PGresult * r = 0 ;
Error result = Error : : ok ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " update core.content set (subject, content, content_type) = ( " ;
query < < ' \' ' < < Escape ( item . subject ) < < " ', " ;
query < < ' \' ' < < Escape ( item . content ) < < " ', " ;
query < < ' \' ' < < item . content_type < < " ' " ;
query < < " ) where id=' " < < item . content_id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
2008-12-21 22:17:09 +01:00
Error Db : : EditItemGetId ( Item & item )
{
PGresult * r = 0 ;
Error result = Error : : ok ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select item.id, content.id from core.item left join core.content on item.content_id = content.id where item.parent_id=' " ;
query < < item . parent_id < < " ' and item.url=' " < < Escape ( item . url ) < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
if ( PQntuples ( r ) ! = 1 | | PQnfields ( r ) ! = 2 )
throw Error ( Error : : db_no_item ) ;
// we cannot use AssertColumn() with a name because both columns are called 'id'
item . id = atol ( AssertValue ( r , 0 , 0 ) ) ;
item . content_id = atol ( AssertValue ( r , 0 , 1 ) ) ;
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
2008-12-14 06:28:28 +01:00
2008-12-21 22:17:09 +01:00
Error Db : : EditItemGetContentId ( Item & item )
2008-12-14 06:28:28 +01:00
{
2008-12-21 22:17:09 +01:00
PGresult * r = 0 ;
Error result = Error : : ok ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select content_id from core.item left join core.content on item.content_id = content.id where item.id=' " ;
query < < item . id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
if ( PQntuples ( r ) ! = 1 | | PQnfields ( r ) ! = 1 )
throw Error ( Error : : db_no_item ) ;
2008-12-14 06:28:28 +01:00
2008-12-21 22:17:09 +01:00
item . content_id = atol ( AssertValue ( r , 0 , 0 ) ) ;
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
// item.id must be set
Error Db : : EditItemById ( Item & item , bool with_subject )
{
Error result = EditItemGetContentId ( item ) ;
2008-12-14 06:28:28 +01:00
if ( result = = Error : : ok )
2008-12-21 22:17:09 +01:00
{
result = EditItemInContent ( item ) ;
2008-12-14 06:28:28 +01:00
2008-12-21 22:17:09 +01:00
if ( result = = Error : : ok )
result = EditItemInItem ( item , with_subject ) ;
}
return result ;
}
// item.url and item.parent_id must be set
Error Db : : EditItemByUrl ( Item & item , bool with_subject )
{
Error result = EditItemGetId ( item ) ;
if ( result = = Error : : ok )
{
result = EditItemInContent ( item ) ;
if ( result = = Error : : ok )
result = EditItemInItem ( item , with_subject ) ;
}
2008-12-14 06:28:28 +01:00
return result ;
}
2008-12-21 22:17:09 +01:00
2008-12-10 05:42:49 +01:00
PGresult * Db : : GetItemsQuery ( Item & item_ref )
{
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " select * from core.item left join core.content on item.content_id = content.id where type!='0' and parent_id=' " < < item_ref . parent_id < < " ' " ;
2008-12-10 05:42:49 +01:00
if ( item_ref . id ! = - 1 )
2008-12-14 06:28:28 +01:00
query < < " and item.id=' " < < item_ref . id < < " ' " ;
2008-12-10 05:42:49 +01:00
2008-12-14 06:28:28 +01:00
if ( ! item_ref . url . empty ( ) )
query < < " and url=' " < < Escape ( item_ref . url ) < < " ' " ;
2008-12-10 05:42:49 +01:00
query < < ' ; ' ;
return AssertQuery ( query . str ( ) ) ;
}
void Db : : GetItems ( std : : vector < Item > & item_table , Item & item_ref )
{
item_table . clear ( ) ;
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
r = GetItemsQuery ( item_ref ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
Item item ;
int rows = PQntuples ( r ) ;
ItemColumns col ;
col . SetColumns ( r ) ;
for ( int i = 0 ; i < rows ; + + i )
{
col . SetItem ( r , i , item ) ;
item_table . push_back ( item ) ;
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
void Db : : GetItem ( std : : vector < Item > & item_table , long id )
{
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " select * from core.item left join core.content on item.content_id = content.id where type='1' and item.id=' " < < id < < " '; " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
Item item ;
int rows = PQntuples ( r ) ;
if ( rows > 1 )
log < < log1 < < " Db: we have more than one item with id: " < < id < < logend ;
ItemColumns col ;
col . SetColumns ( r ) ;
for ( int i = 0 ; i < rows ; + + i )
{
col . SetItem ( r , i , item ) ;
item_table . push_back ( item ) ;
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
2008-12-14 06:28:28 +01:00
2008-12-21 22:17:09 +01:00
bool Db : : GetPriv ( Item & item , long id )
{
bool result = false ;
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select user_id, group_id, privileges, subject, content from core.item left join core.content on item.content_id = content.id where item.id=' " < < id < < " '; " ; // !! tymczasowo odczytujemy z content i subject
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
int rows = PQntuples ( r ) ;
if ( rows ! = 1 )
throw Error ( ) ;
ItemColumns col ;
col . SetColumns ( r ) ;
col . SetItem ( r , 0 , item ) ;
result = true ;
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
return result ;
}
2008-12-14 06:28:28 +01:00
bool Db : : DelItemDelItem ( const Item & item )
2008-12-10 05:42:49 +01:00
{
2008-12-14 06:28:28 +01:00
long rows = 0 ;
2008-12-10 05:42:49 +01:00
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " delete from core.item where id=' " < < item . id < < " '; " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
const char * crows = PQcmdTuples ( r ) ;
if ( crows )
{
rows = atol ( crows ) ;
if ( rows > 1 )
log < < log1 < < " Db: more than one item were deleted " < < logend ;
2008-12-14 06:28:28 +01:00
else
if ( rows = = 0 )
log < < log1 < < " Db: no item has been deleted " < < logend ;
2008-12-10 05:42:49 +01:00
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
return rows ! = 0 ;
}
2008-12-14 06:28:28 +01:00
void Db : : DelItemDelContent ( const Item & item )
{
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " delete from core.content where id=' " < < item . content_id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_COMMAND_OK ) ;
const char * crows = PQcmdTuples ( r ) ;
if ( crows )
{
long rows = atol ( crows ) ;
if ( rows > 1 )
log < < log1 < < " Db: more than one content were deleted " < < logend ;
else
if ( rows = = 0 )
log < < log1 < < " Db: no content has been deleted " < < logend ;
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
Error Db : : DelItemCountContents ( const Item & item , long & contents )
{
Error result = Error : : ok ;
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select count('id') from core.item where content_id=' " < < item . content_id < < " '; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
contents = atol ( AssertValue ( r , 0 , 0 ) ) ;
log < < log1 < < " counters: " < < contents < < logend ; // !!
}
catch ( const Error & e )
{
result = e ;
}
ClearResult ( r ) ;
return result ;
}
bool Db : : DelItem ( const Item & item )
{
long contents ;
Error result = DelItemCountContents ( item , contents ) ;
if ( result = = Error : : ok & & contents = = 1 )
DelItemDelContent ( item ) ;
return DelItemDelItem ( item ) ;
}
2008-12-10 05:42:49 +01:00
void Db : : GetDirs ( DirContainer & dir_table )
{
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
2008-12-14 06:28:28 +01:00
query < < " select * from core.item left join core.content on item.content_id = content.id where type='0'; " ;
2008-12-10 05:42:49 +01:00
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
Item item ;
int rows = PQntuples ( r ) ;
ItemColumns col ;
col . SetColumns ( r ) ;
for ( int i = 0 ; i < rows ; + + i )
{
col . SetItem ( r , i , item ) ;
dir_table . PushBack ( item ) ;
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
2008-12-21 22:17:09 +01:00
void Db : : GetUsers ( UGContainer < User > & user_table )
{
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select id, login, super_user, group_id from core.user left outer join core.group_mem on core.user.id = core.group_mem.user_id order by id asc; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
int rows = PQntuples ( r ) ;
int cid = AssertColumn ( r , " id " ) ;
int cname = AssertColumn ( r , " login " ) ;
int csuper_user = AssertColumn ( r , " super_user " ) ;
int cgroup_id = AssertColumn ( r , " group_id " ) ;
User u ;
long last_id = - 1 ;
UGContainer < User > : : Iterator iter ;
for ( int i = 0 ; i < rows ; + + i )
{
u . id = atol ( AssertValue ( r , i , cid ) ) ;
if ( u . id ! = last_id )
{
u . name = AssertValue ( r , i , cname ) ;
u . super_user = static_cast < bool > ( atoi ( AssertValue ( r , i , csuper_user ) ) ) ;
log < < log1 < < " Db: get user: id: " < < u . id < < " , name: " < < u . name < < " , super_user: " < < u . super_user < < logend ;
iter = user_table . PushBack ( u ) ;
last_id = u . id ;
}
long group_id = atol ( AssertValue ( r , i , cgroup_id ) ) ;
if ( ! PQgetisnull ( r , i , cgroup_id ) & & group_id ! = - 1 & & ! user_table . Empty ( ) )
{
iter - > groups . push_back ( group_id ) ;
log < < log3 < < " Db: user: " < < iter - > name < < " is a member of group_id: " < < group_id < < logend ;
}
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
void Db : : GetGroups ( UGContainer < Group > & group_table )
{
PGresult * r = 0 ;
try
{
AssertConnection ( ) ;
std : : ostringstream query ;
query < < " select id, core.group.group, user_id from core.group left outer join core.group_mem on core.group.id = core.group_mem.group_id order by id asc; " ;
r = AssertQuery ( query . str ( ) ) ;
AssertResultStatus ( r , PGRES_TUPLES_OK ) ;
int rows = PQntuples ( r ) ;
int cid = AssertColumn ( r , " id " ) ;
int cname = AssertColumn ( r , " group " ) ;
int cuser_id = AssertColumn ( r , " user_id " ) ;
Group g ;
long last_id = - 1 ;
UGContainer < Group > : : Iterator iter ;
for ( int i = 0 ; i < rows ; + + i )
{
g . id = atol ( AssertValue ( r , i , cid ) ) ;
if ( g . id ! = last_id )
{
g . name = AssertValue ( r , i , cname ) ;
log < < log3 < < " Db: get group, id: " < < g . id < < " , group: " < < g . name < < logend ;
iter = group_table . PushBack ( g ) ;
last_id = g . id ;
}
long user_id = atol ( AssertValue ( r , i , cuser_id ) ) ;
if ( ! PQgetisnull ( r , i , cuser_id ) & & user_id ! = - 1 & & ! group_table . Empty ( ) )
{
iter - > members . push_back ( user_id ) ;
log < < log3 < < " Db: get group member: user_id: " < < user_id < < logend ;
}
}
}
catch ( const Error & )
{
}
ClearResult ( r ) ;
}
2008-12-10 05:42:49 +01:00