813 lines
21 KiB
C++
813 lines
21 KiB
C++
#include "Database.h"
|
|
#include "Logger.h"
|
|
#include "rcdu.h"
|
|
#include "syncmanager.h"
|
|
|
|
#define MAX_ROWS 1000000
|
|
|
|
void toLowerCaseSTD(std::string &str)
|
|
{
|
|
transform(str.begin(), str.end(), str.begin(), (int(*)(int))tolower);
|
|
}
|
|
|
|
string StringReplace(const string& source, const string search, const string replacement)
|
|
{
|
|
string r = source;
|
|
|
|
string::size_type pos = 0;
|
|
|
|
while ( (pos = r.find(search, pos)) != string::npos )
|
|
{
|
|
r.replace( pos, search.size(), replacement );
|
|
pos = pos + replacement.size();
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
CSyncManager::CSyncManager()
|
|
: m_tblmode(-1)
|
|
{
|
|
|
|
}
|
|
|
|
CSyncManager::~CSyncManager()
|
|
{
|
|
|
|
}
|
|
|
|
bool CSyncManager::sync( DataBase &db, RCUDINFOLIST &infolist )
|
|
{
|
|
RCUDINFOLIST::iterator i;
|
|
|
|
// 2014.06.07 dadamin
|
|
// 형상(9.3) 변경으로 테이블 형태 체크
|
|
if( m_tblmode < 0 && targettblmode(db) == false )
|
|
{
|
|
LOG(LERR, "Unknown table mode.");
|
|
return false;
|
|
}
|
|
|
|
_LOG(LINF,"RCDB : %s Type.", m_tblmode == 1 ? "NEW" : "OLD");
|
|
|
|
for (i = infolist.begin(); i != infolist.end(); ++i )
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "sync - " << (*i).getInfoService() << "," << (*i).getInfoCaldepth() << endl;
|
|
#endif //_DEBUG
|
|
SYNCDATAMAP data;
|
|
|
|
if((*i).getInfoCaldepth() == 0)
|
|
{
|
|
// sync directory
|
|
if( deloverdepth(db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth() ) == false )
|
|
break;
|
|
if( insertroot( db, (*i).getInfoUserseq(), (*i).getInfoTranid()) == false )
|
|
break;
|
|
|
|
// get sync data
|
|
if( getrootsum( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), data ) != 0 )
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// sync directory
|
|
if( deloverdepth( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth() ) == false )
|
|
break;
|
|
if( deldeleteddir( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth() ) == false )
|
|
break;
|
|
if( delnotfouddir( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth() ) == false )
|
|
break;
|
|
if( insertdir( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth() ) == false )
|
|
break;
|
|
|
|
// get sync data
|
|
if( getdepthsum( db, (*i).getInfoUserseq(), (*i).getInfoTranid(), (*i).getInfoCaldepth(), data ) != 0 )
|
|
break;
|
|
}
|
|
|
|
// sync data
|
|
if( syndata(db, data) == false )
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int CSyncManager::savedata( int64_t userseq, int64_t tranid, int caldepth, int depth, const char *uri, int64_t length, SYNCDATAMAP &data )
|
|
{
|
|
int loop = depth;
|
|
if( depth > caldepth )
|
|
loop = caldepth;
|
|
else if ( depth < 0 )
|
|
loop = 0;
|
|
|
|
string path = uri;
|
|
|
|
size_t found = 1;
|
|
for ( int i = 0; i <= loop; ++i )
|
|
{
|
|
found = path.find("/", found );
|
|
string s;
|
|
if( found != string::npos )
|
|
{
|
|
s = path.substr(0, found);
|
|
found += 1;
|
|
}
|
|
else
|
|
{
|
|
s = path;
|
|
}
|
|
|
|
SYNCDATAMAP::iterator f;
|
|
|
|
f = data.find(s);
|
|
if (f != data.end())
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "savedata find : " << i << "," << s << "," << length << endl;
|
|
#endif // _DEBUG
|
|
f->second.addused(length);
|
|
}
|
|
else
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "savedata : " << i << "," << s << "," << length << endl;
|
|
#endif // _DEBUG
|
|
|
|
CSyncData v;
|
|
v.setUserseq(userseq);
|
|
v.setTranid(tranid);
|
|
v.setdepth(i);
|
|
v.setpath(s.c_str());
|
|
v.addused(length);
|
|
data[s] = v;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CSyncManager::getrootsum( DataBase &db, int64_t userseq, int64_t tranid, SYNCDATAMAP &data )
|
|
{
|
|
int r = 0;
|
|
ostringstream sql,t;
|
|
|
|
t << tranid;
|
|
string strtranid = t.str();
|
|
const char *paramValues[1];
|
|
|
|
paramValues[0] = strtranid.c_str();
|
|
#ifdef _DEBUG
|
|
cout << "Sum Root Data : " << userseq << "," << paramValues[0] << endl;
|
|
#endif //_DEBUG
|
|
|
|
string tblname = gettablename(tranid);
|
|
sql << "SELECT SUM(get_content_length) FROM " ;
|
|
sql << tblname << " ";
|
|
sql << "WHERE sp_svc_tran_id = $1 AND deleted_yn = 'N' AND is_cache = 'N'";
|
|
|
|
#ifdef _DEBUG
|
|
cout << "sum SQL - " << sql.str() << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 1, paramValues);
|
|
|
|
if(db.PgResult(DataBase::NOT_CLEAR) < 0)
|
|
{
|
|
LOG(LERR, "Database Error.[%s]", db.GetErrorMessage().c_str());
|
|
return r;
|
|
}
|
|
|
|
int64_t sum = 0;
|
|
if(db.GetNoTuples() > 0)
|
|
{
|
|
sum = atoll(db.GetValue(0,0));
|
|
}
|
|
|
|
string s = "/" + t.str();
|
|
savedata( userseq, tranid, 0, 0, s.c_str(), sum, data );
|
|
|
|
db.PgClear();
|
|
|
|
return r;
|
|
}
|
|
|
|
int CSyncManager::getsyncdata( DataBase &db, int64_t userseq, int64_t tranid, int caldepth, SYNCDATAMAP &data )
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "Sum Total Data : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif //_DEBUG
|
|
string tblname = gettablename(tranid);
|
|
|
|
ostringstream sql;
|
|
sql << "SELECT depth, uri, get_content_length, resource_type FROM "
|
|
<< tblname
|
|
// 2011.07.03 : BD-13와 같이 여러개의 서비스 중인 RC 경우 MAX depth 구할 시 DB 부하가 많이 발생함
|
|
// 이에 따라 통상 depth 500이상 경우 없기 때문에 1000으로 고정시켜 DB 부하를 줄였음
|
|
<< " WHERE depth >= 0 and depth <= 1000 AND uri LIKE $1 ||'%' AND "
|
|
<< "deleted_yn = 'N' AND is_cache = 'N' "
|
|
// 2011.06.30 : LIMIT...OFFSET 사용 시 order by 없을 중복 및 누락 발생할 수 있음(이는 PosgtreSQL 매뉴얼에 나와 있음)
|
|
<< "ORDER BY resource_id "
|
|
<< "LIMIT " << MAX_ROWS << " OFFSET $2";
|
|
|
|
int r = 0;
|
|
int64_t offset = 0;
|
|
ostringstream t;
|
|
|
|
t << "/" << tranid;
|
|
string m = t.str();
|
|
while ( true )
|
|
{
|
|
int rows = 0;
|
|
t.str("");
|
|
t << offset;
|
|
|
|
const char *paramValues[2];
|
|
paramValues[0] = m.c_str();
|
|
paramValues[1] = t.str().c_str();
|
|
#ifdef _DEBUG
|
|
cout << "sumdata SQL - " << sql.str() << endl;
|
|
cout << "paramValues - " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 2 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
r = -1;
|
|
LOG(LERR, "sumdata data load fail.[%s]", db.GetErrorMessage().c_str());
|
|
break;
|
|
}
|
|
|
|
rows = db.GetNoTuples();
|
|
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "sum date - " << i << "," << db.GetValue(i,0) << "," << db.GetValue(i,1) << "," << db.GetValue(i,2) << endl;
|
|
#endif // _DEBUG
|
|
int rtype = atoi(db.GetValue(i,3));
|
|
|
|
if( rtype == 0 ) // file
|
|
savedata( userseq, tranid, caldepth, atoi(db.GetValue(i,0)) - 1, db.GetValue(i,1), atoll(db.GetValue(i,2)), data ) ;
|
|
else //dir
|
|
savedata( userseq, tranid, caldepth, atoi(db.GetValue(i,0)) , db.GetValue(i,1), atoll(db.GetValue(i,2)), data ) ;
|
|
}
|
|
|
|
db.PgClear();
|
|
|
|
if( rows < MAX_ROWS )
|
|
break;
|
|
|
|
offset += MAX_ROWS;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
int CSyncManager::getdepthsum( DataBase &db, int64_t userseq, int64_t tranid, int caldepth, SYNCDATAMAP &data )
|
|
{
|
|
int r = 0;
|
|
#ifdef _DEBUG
|
|
cout << "Sum Depth Data : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif //_DEBUG
|
|
|
|
const char *paramValues[3];
|
|
ostringstream t;
|
|
string p1,p2,p3;
|
|
|
|
ostringstream sql;
|
|
string tblname = gettablename(tranid);
|
|
|
|
for(int d = caldepth; d >=0; --d)
|
|
{
|
|
sql.str("");
|
|
sql << "SELECT path_name FROM t_dav_use_dir WHERE"
|
|
<< " depth = $1 AND path_name LIKE $2 ||'%'";
|
|
|
|
t << d;
|
|
p1 = t.str(); t.str("");
|
|
t << "/" << tranid;
|
|
p2 = t.str(); t.str("");
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
|
|
#ifdef _DEBUG
|
|
cout << "select dir sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 2 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
r = -1;
|
|
LOG(LERR, "select dir load fail.[%s][%s]", db.GetErrorMessage().c_str(), paramValues[1]);
|
|
break;
|
|
}
|
|
|
|
vector<string> seldata;
|
|
int rows = db.GetNoTuples();
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
seldata.push_back(db.GetValue(i,0));
|
|
}
|
|
db.PgClear();
|
|
|
|
if(rows == 0) continue;
|
|
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
sql.str("");
|
|
sql << "SELECT SUM(get_content_length) FROM " << tblname;
|
|
|
|
if(d == caldepth)
|
|
{
|
|
sql << " WHERE depth >= $1 ";
|
|
}
|
|
else
|
|
{
|
|
sql << " WHERE (depth = $1 OR depth = $1+1 )";
|
|
}
|
|
|
|
//sql << "AND uri LIKE $2 ||'/%' AND resource_type = 0 ";
|
|
//sql << "AND uri LIKE regexp_replace(lower($2), '(%|_)', '\\\\\\1', 'g') || '%' ";
|
|
//sql << "AND deleted_yn = 'N' AND is_cache = 'N'";
|
|
|
|
// BUG 2019-03-14 huibong 지정된 폴더가 아닌 다른 폴더까지 SUM 처리되는 버그 수정 (#32547)
|
|
// - 폴더 구분자 미사용으로 폴더 용량 계산시 다른 폴더까지 계산됨
|
|
// - /73/mut 계산시 /73/mut-hd 까지 계산되는 버그 수정
|
|
sql << "AND uri LIKE regexp_replace(lower($2), '(%|_)', '\\\\\\1', 'g') || '/%' ";
|
|
sql << "AND deleted_yn = 'N' AND is_cache = 'N' AND resource_type = 0 ";
|
|
|
|
|
|
//string s = StringReplace(seldata[i], "_", "\\_");
|
|
paramValues[1] = seldata[i].c_str();
|
|
#ifdef _DEBUG
|
|
cout << " dir sum sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 2 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
r = -1;
|
|
LOG(LERR, "dir sum fail.[%s][%s]", db.GetErrorMessage().c_str(), paramValues[1]);
|
|
break;
|
|
}
|
|
|
|
savedata( userseq, tranid, caldepth, d, paramValues[1],atoll(db.GetValue(0,0)), data) ;
|
|
}
|
|
db.PgClear();
|
|
|
|
if( r != 0 )
|
|
break;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
static string stringreplace(const string& source, const string search, const string replacement)
|
|
{
|
|
string r = source;
|
|
|
|
string::size_type pos = 0;
|
|
|
|
while ( (pos = r.find(search, pos)) != string::npos )
|
|
{
|
|
r.replace( pos, search.size(), replacement );
|
|
pos = pos + replacement.size();
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
bool CSyncManager::syndata( DataBase &db, SYNCDATAMAP &data )
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "syndata : " << data.size() << endl;
|
|
#endif //_DEBUG
|
|
|
|
for( SYNCDATAMAP::iterator i=data.begin(); i!=data.end(); ++i )
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "sync (" << i->second.getTranid() << ") : "<< i->second.getpath() << "," << i->second.getused() << endl;
|
|
#endif //_DEBUG
|
|
|
|
// replace unsafe chars
|
|
string updatepath = stringreplace( i->second.getpath(), "'", "''" );
|
|
|
|
ostringstream sql;
|
|
sql << "UPDATE t_dav_use_dir SET dir_used = " << i->second.getused()
|
|
<< " WHERE depth = "<< i->second.getdepth() << " AND path_name = '" << updatepath << "'";
|
|
|
|
#ifdef _DEBUG
|
|
cout << "syndata sql : " << sql.str() << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExec(const_cast<char *> (sql.str().c_str()));
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] Update error.[dir_used - " << i->second.getpath() << "]" << endl;
|
|
LOG(LERR, "Update dir_used failed.[path - %s]", i->second.getpath());
|
|
return false;
|
|
}
|
|
_LOG(LINF, "SYNC DATA - Path : %s, Size : %jd",i->second.getpath(), i->second.getused() );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CSyncManager::deloverdepth(DataBase &db, int64_t userseq, int64_t tranid, int caldepth)
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "delete over depth : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif // _DEBUG
|
|
ostringstream sql;
|
|
|
|
sql << "DELETE FROM t_dav_use_dir WHERE depth > $1 AND path_name LIKE $2 ||'%'";
|
|
|
|
const char *paramValues[2];
|
|
ostringstream t;
|
|
string p1,p2;
|
|
|
|
t << caldepth;
|
|
p1 = t.str(); t.str("");
|
|
t << "/" << tranid << "/";
|
|
p2 = t.str(); t.str("");
|
|
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
|
|
#ifdef _DEBUG
|
|
cout << "delete over depth sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 2, paramValues);
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] delete over depth error.[sync root tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "delete over depth failed.[tran id - %jd]", tranid);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CSyncManager::deldeleteddir(DataBase &db, int64_t userseq, int64_t tranid, int caldepth)
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "delete deleted dir : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif // _DEBUG
|
|
|
|
string tblname = gettablename(tranid);
|
|
ostringstream sql;
|
|
|
|
sql << "SELECT uri FROM " << tblname << " WHERE "
|
|
<< "uri IN "
|
|
<< " (SELECT uri FROM " << tblname << " WHERE depth >= 0 AND depth <= $1 "
|
|
<< " AND uri LIKE $2 ||'%' AND resource_type = 1 AND deleted_yn = 'Y' AND is_cache = 'N') "
|
|
<< "AND deleted_yn = 'Y' "
|
|
<< "AND uri NOT IN "
|
|
<< " (SELECT uri FROM " << tblname << " WHERE uri IN (SELECT uri FROM " << tblname << " WHERE depth >= 0 AND depth <= $1 "
|
|
<< " AND uri LIKE $2 ||'%' AND resource_type = 1 AND deleted_yn = 'Y' AND is_cache = 'N') AND deleted_yn = 'N') ";
|
|
|
|
const char *paramValues[2];
|
|
ostringstream t;
|
|
string p1,p2;
|
|
|
|
t << caldepth;
|
|
p1 = t.str(); t.str("");
|
|
t << "/" << tranid;
|
|
p2 = t.str(); t.str("");
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
|
|
#ifdef _DEBUG
|
|
cout << "deleted dir sel sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 2 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
LOG(LERR, "deleted dir load fail.[%s][%s]", db.GetErrorMessage().c_str(), paramValues[1]);
|
|
return false;
|
|
}
|
|
|
|
string strdeldir;
|
|
int rows = db.GetNoTuples();
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
if(i > 0) strdeldir += ",";
|
|
strdeldir += db.GetValue(i,0);
|
|
}
|
|
|
|
// 2014.06.07 dadamin
|
|
// ANY 함수 사용을 {} 포함된 경우 array 로 인되는 경우 방지
|
|
strdeldir = StringReplace(strdeldir,"{", "\\{");
|
|
strdeldir = StringReplace(strdeldir,"}", "\\}");
|
|
|
|
strdeldir = "{" + strdeldir + "}" ;
|
|
db.PgClear();
|
|
|
|
if(rows == 0) return true;
|
|
|
|
sql.str("");
|
|
sql << "DELETE FROM t_dav_use_dir WHERE path_name = ANY($1)";
|
|
|
|
paramValues[0] = strdeldir.c_str();
|
|
#ifdef _DEBUG
|
|
cout << "delete dir sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 1, paramValues);
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] delete dir error.[sync tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "delete dir failed.[%s][tran id - %jd]", db.GetErrorMessage().c_str(), tranid);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CSyncManager::delnotfouddir(DataBase &db, int64_t userseq, int64_t tranid, int caldepth)
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "delete not found dir : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif // _DEBUG
|
|
|
|
string tblname = gettablename(tranid);
|
|
|
|
ostringstream sql;
|
|
|
|
sql << "SELECT L.path_name FROM t_dav_use_dir L LEFT JOIN " << tblname << " R "
|
|
<< "ON L.path_name = R.uri WHERE L.sp_user_seq = $1 AND L.sp_svc_tran_id = $2 AND R.uri IS NULL ";
|
|
|
|
const char *paramValues[2];
|
|
ostringstream t;
|
|
string p1,p2;
|
|
|
|
t << userseq;
|
|
p1 = t.str(); t.str("");
|
|
t << tranid;
|
|
p2 = t.str(); t.str("");
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
|
|
#ifdef _DEBUG
|
|
cout << "deleted not found sel sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 2 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
LOG(LERR, "deleted dir load fail.[%s][%s]", db.GetErrorMessage().c_str(), paramValues[1]);
|
|
return false;
|
|
}
|
|
|
|
string strnotfound;
|
|
int rows = db.GetNoTuples();
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
if(i > 0) strnotfound += ",";
|
|
strnotfound += db.GetValue(i,0);
|
|
}
|
|
// 2014.06.07 dadamin
|
|
// ANY 함수 사용을 {} 포함된 경우 array 로 인되는 경우 방지
|
|
strnotfound = StringReplace(strnotfound,"{", "\\{");
|
|
strnotfound = StringReplace(strnotfound,"}", "\\}");
|
|
|
|
strnotfound = "{" + strnotfound + "}" ;
|
|
|
|
db.PgClear();
|
|
|
|
if(rows == 0) return true;
|
|
|
|
sql.str("");
|
|
sql << "DELETE FROM t_dav_use_dir WHERE path_name = ANY($1)";
|
|
|
|
paramValues[0] = strnotfound.c_str();
|
|
#ifdef _DEBUG
|
|
cout << "delete not found sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 1, paramValues);
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] delete not found error.[sync tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "delete not found failed.[%s][tran id - %jd]", db.GetErrorMessage().c_str(), tranid);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CSyncManager::insertroot(DataBase &db, int64_t userseq, int64_t tranid)
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "insert root : " << userseq << "," << tranid << endl;
|
|
#endif //_DEBUG
|
|
|
|
const char *paramValues[3];
|
|
ostringstream t;
|
|
string p1,p2,p3;
|
|
ostringstream sql;
|
|
|
|
t << userseq;
|
|
p1 = t.str(); t.str("");
|
|
t << tranid;
|
|
p2 = t.str(); t.str("");
|
|
t << "/" << tranid;
|
|
p3 = t.str(); t.str("");
|
|
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
paramValues[2] = p3.c_str();
|
|
|
|
sql << "SELECT * FROM t_dav_use_dir "
|
|
<< "WHERE sp_user_seq = $1 AND sp_svc_tran_id = $2 AND depth = 0";
|
|
|
|
#ifdef _DEBUG
|
|
cout << "select root sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << "," << paramValues[2] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 2, paramValues);
|
|
|
|
int row = db.GetNoTuples();
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] Select root error.[sync root tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "Select root failed.[tran id - %jd]", tranid);
|
|
return false;
|
|
}
|
|
|
|
if( row > 0 )
|
|
return true;
|
|
|
|
sql.str("");
|
|
sql << "INSERT INTO t_dav_use_dir (sp_user_seq, sp_svc_tran_id, depth, path_name)"
|
|
<< " VALUES ($1,$2,0,$3)";
|
|
|
|
#ifdef _DEBUG
|
|
cout << "insert root sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << "," << paramValues[2] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 3, paramValues);
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] Insert root error.[sync root tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "Insert root failed.[tran id - %jd]", tranid);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CSyncManager::insertdir(DataBase &db, int64_t userseq, int64_t tranid, int caldepth)
|
|
{
|
|
#ifdef _DEBUG
|
|
cout << "insert dir : " << userseq << "," << tranid << "," << caldepth << endl;
|
|
#endif // _DEBUG
|
|
|
|
string tblname = gettablename(tranid);
|
|
|
|
ostringstream sql;
|
|
|
|
sql << "SELECT L.uri FROM " << tblname << " L "
|
|
<< "LEFT JOIN t_dav_use_dir R ON L.uri = R.path_name "
|
|
<< "WHERE L.sp_user_seq = $1 AND L.sp_svc_tran_id = $2 "
|
|
<< "AND L.deleted_yn = 'N' and L.is_cache = 'N' AND L.resource_type = 1 AND L.depth >= 0 "
|
|
<< "AND L.depth <= $3 AND R.path_name IS NULL ORDER BY L.uri";
|
|
|
|
const char *paramValues[3];
|
|
ostringstream t;
|
|
string p1,p2,p3;
|
|
|
|
t << userseq;
|
|
p1 = t.str(); t.str("");
|
|
t << tranid;
|
|
p2 = t.str(); t.str("");
|
|
t << caldepth;
|
|
p3 = t.str(); t.str("");
|
|
|
|
paramValues[0] = p1.c_str();
|
|
paramValues[1] = p2.c_str();
|
|
paramValues[2] = p3.c_str();
|
|
|
|
#ifdef _DEBUG
|
|
cout << "insert dir sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << "," << paramValues[1] << "," << paramValues[2] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams( const_cast<char *> (sql.str().c_str()), 3 , paramValues);
|
|
|
|
if( db.PgResult(DataBase::NOT_CLEAR) < 0 )
|
|
{
|
|
LOG(LERR, "insert dir load fail.[%s][%s]", db.GetErrorMessage().c_str(), paramValues[1]);
|
|
return false;
|
|
}
|
|
|
|
string strinserdir;
|
|
int rows = db.GetNoTuples();
|
|
for( int i = 0; i < rows; ++i )
|
|
{
|
|
if(i > 0) strinserdir += ",";
|
|
strinserdir += db.GetValue(i,0);
|
|
}
|
|
// 2014.06.07 dadamin
|
|
// ANY 함수 사용을 {} 포함된 경우 array 로 인되는 경우 방지
|
|
strinserdir = StringReplace(strinserdir,"{", "\\{");
|
|
strinserdir = StringReplace(strinserdir,"}", "\\}");
|
|
|
|
strinserdir = "{" + strinserdir + "}" ;
|
|
db.PgClear();
|
|
|
|
if(rows == 0) return true;
|
|
|
|
sql.str("");
|
|
sql << "INSERT INTO t_dav_use_dir (sp_user_seq, sp_svc_tran_id, depth, path_name) "
|
|
<< "SELECT DISTINCT ON (uri) sp_user_seq, sp_svc_tran_id, depth, uri FROM " << tblname
|
|
<< " WHERE uri = ANY($1)";
|
|
|
|
paramValues[0] = strinserdir.c_str();
|
|
#ifdef _DEBUG
|
|
cout << "insert dir sql : " << sql.str() << endl;
|
|
cout << " param : " << paramValues[0] << endl;
|
|
#endif // _DEBUG
|
|
|
|
db.PgDoExecParams(const_cast<char *> (sql.str().c_str()), 1, paramValues);
|
|
|
|
if( db.PgResult(DataBase::CLEAR) < 0)
|
|
{
|
|
cerr << "[error] insert dir error.[sync tran id - " << tranid << "]" << endl;
|
|
LOG(LERR, "insert dir failed.[%s][tran id - %jd]", db.GetErrorMessage().c_str(), tranid);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 2014.06.07 dadamin
|
|
// 형상(9.3) 변경으로 테이블명 수정
|
|
bool CSyncManager::targettblmode( DataBase &db )
|
|
{
|
|
db.PgDoExec("SELECT * FROM pg_tables WHERE schemaname = 'public' AND tablename = 't_dav_resource'");
|
|
if (db.PgResult(DataBase::NOT_CLEAR) < 0)
|
|
{
|
|
db.PgClear();
|
|
cerr << "[error] failed Target Table mode." << endl;
|
|
LOG(LERR, "failed Target Table mode.[%s]", db.GetErrorMessage().c_str());
|
|
return false;
|
|
}
|
|
|
|
if (db.GetNoTuples() > 0)
|
|
{
|
|
m_tblmode = 0;
|
|
}
|
|
else
|
|
{
|
|
m_tblmode = 1;
|
|
}
|
|
|
|
db.PgClear();
|
|
|
|
return true;
|
|
}
|
|
|
|
string CSyncManager::gettablename(int64_t tranid)
|
|
{
|
|
string r;
|
|
ostringstream tmp;
|
|
|
|
switch (m_tblmode)
|
|
{
|
|
case 1:
|
|
tmp << "t_meta_" << tranid;
|
|
break;
|
|
case 0:
|
|
default:
|
|
tmp << "t_dav_resource";
|
|
break;
|
|
}
|
|
|
|
r = tmp.str();
|
|
LOG(LDBG, "Working Table Name %s", r.c_str());
|
|
|
|
return r;
|
|
}
|