| 22 |
* |
* |
| 23 |
* $Revision$ |
* $Revision$ |
| 24 |
* $Log$ |
* $Log$ |
| 25 |
* Revision 1.113.2.4 2005/12/06 05:09:38 aga4096 |
* Revision 1.120 2006/04/11 10:31:27 tani |
| 26 |
* ・開放忘れを修正. |
* merge to main trunk (from REL20060213 to merge_to_20060411) |
| 27 |
|
* REL20060213からmerge_to_20060411までのSTABLE_2の差分をCURRENTにマージ. |
| 28 |
|
* |
| 29 |
|
* Revision 1.118.2.2 2006/02/28 04:49:17 aga4096 |
| 30 |
|
* ・NIJC code, guestのon/offを書き換えたときに item_status をリセットする. |
| 31 |
|
* |
| 32 |
|
* Revision 1.118.2.1 2006/02/14 05:13:17 aga4096 |
| 33 |
|
* ・アイテムが private/index_a と public/index_b に登録された状態で、 private/index_aを削除するとおかしくなるのを修正. |
| 34 |
|
* |
| 35 |
|
* Revision 1.119 2006/04/07 08:19:51 tani |
| 36 |
|
* doiをDBから取得する時の型指定をBLOBにあわせて修正. |
| 37 |
|
* |
| 38 |
|
* Revision 1.118 2006/01/10 10:56:30 tani |
| 39 |
|
* selectiveHarvesting:stat.item_idでorder by(asc) |
| 40 |
|
* |
| 41 |
|
* Revision 1.117 2006/01/06 05:50:32 aga4096 |
| 42 |
|
* ・ ctype.h をinclude. |
| 43 |
|
* |
| 44 |
|
* Revision 1.116 2005/11/22 11:29:54 tani |
| 45 |
|
* deleteItem: アイテム削除と同時にRelated toも削除する. |
| 46 |
|
* getRelatedTo: isActivatedBySessionのチェックを外す(冗長なので). |
| 47 |
|
* |
| 48 |
|
* Revision 1.115 2005/11/17 10:59:36 tani |
| 49 |
|
* アイテム間リンク機能: insertRelatedTo, deleteRelatedTo, getRelatedToを追加. |
| 50 |
|
* |
| 51 |
|
* Revision 1.114 2005/11/16 03:59:06 tani |
| 52 |
|
* XOONIPS_STABLEの分岐点〜MergePnt_20051116間のXooNIps_STABLE上の修正をCURRENTにマージ. |
| 53 |
* |
* |
| 54 |
* Revision 1.113.2.3 2005/11/01 10:36:14 tani |
* Revision 1.113.2.3 2005/11/01 10:36:14 tani |
| 55 |
* _insertItem: dierctフラグによって書き込む日付情報の値を分岐する. |
* _insertItem: dierctフラグによって書き込む日付情報の値を分岐する. |
| 510 |
#include <sql.h> |
#include <sql.h> |
| 511 |
#include <sqlext.h> |
#include <sqlext.h> |
| 512 |
#include <libxml/xmlreader.h> |
#include <libxml/xmlreader.h> |
| 513 |
|
#include <ctype.h> |
| 514 |
|
|
| 515 |
using namespace std; |
using namespace std; |
| 516 |
|
|
| 3806 |
SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &publication_mday, 0, &cbPublication_mday ); |
SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &publication_mday, 0, &cbPublication_mday ); |
| 3807 |
SQLBindParameter(hstmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, XNP_ITEM_LANG_LEN, 0, lang, 0, &cbLang ); |
SQLBindParameter(hstmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, XNP_ITEM_LANG_LEN, 0, lang, 0, &cbLang ); |
| 3808 |
|
|
| 3809 |
|
//アイテム情報をitem構造体からSQL_CHAR配列へコピーする |
| 3810 |
strncpy2( (char*)title, item -> getTitle(), XNP_ITEM_TITLE_LEN ); |
strncpy2( (char*)title, item -> getTitle(), XNP_ITEM_TITLE_LEN ); |
| 3811 |
strncpy2( (char*)keywords, item -> getKeywords(), XNP_ITEM_KEYWORDS_LEN ); |
strncpy2( (char*)keywords, item -> getKeywords(), XNP_ITEM_KEYWORDS_LEN ); |
| 3812 |
strncpy2( (char*)description, item -> getDescription(), XNP_ITEM_DESCRIPTION_LEN ); |
strncpy2( (char*)description, item -> getDescription(), XNP_ITEM_DESCRIPTION_LEN ); |
| 4009 |
SQLBindCol( hstmt, 11, SQL_C_SLONG, &publication_month, 0, &cbPublication_month ); |
SQLBindCol( hstmt, 11, SQL_C_SLONG, &publication_month, 0, &cbPublication_month ); |
| 4010 |
SQLBindCol( hstmt, 12, SQL_C_SLONG, &publication_mday, 0, &cbPublication_mday ); |
SQLBindCol( hstmt, 12, SQL_C_SLONG, &publication_mday, 0, &cbPublication_mday ); |
| 4011 |
|
|
| 4012 |
|
//取得したアイテムの情報をitem構造体へコピーする |
| 4013 |
|
//DOIはBLOB型→char*型へ変換のため,引数でSQL_C_BINARYを明示する |
| 4014 |
*itemsLen = 0; |
*itemsLen = 0; |
| 4015 |
for( int i = 0; ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS && i < iidsLen ; i++ ){ |
for( int i = 0; ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS && i < iidsLen ; i++ ){ |
| 4016 |
dst[ i ].setItemID( item_id ); |
dst[ i ].setItemID( item_id ); |
| 4018 |
dst[ i ].setTitle( getResultCol( hstmt, 3 ).c_str() ); |
dst[ i ].setTitle( getResultCol( hstmt, 3 ).c_str() ); |
| 4019 |
dst[ i ].setKeywords( getResultCol( hstmt, 4 ).c_str() ); |
dst[ i ].setKeywords( getResultCol( hstmt, 4 ).c_str() ); |
| 4020 |
dst[ i ].setDescription( getResultCol( hstmt, 5 ).c_str() ); |
dst[ i ].setDescription( getResultCol( hstmt, 5 ).c_str() ); |
| 4021 |
dst[ i ].setDOI( getResultCol( hstmt, 6 ).c_str() ); |
dst[ i ].setDOI( getResultCol( hstmt, 6, SQL_C_BINARY ).c_str() ); |
| 4022 |
dst[ i ].setContributorUID( uid ); |
dst[ i ].setContributorUID( uid ); |
| 4023 |
dst[ i ].setCreationDate( creation_date ); |
dst[ i ].setCreationDate( creation_date ); |
| 4024 |
dst[ i ].setLastUpdateDate( last_update_date ); |
dst[ i ].setLastUpdateDate( last_update_date ); |
| 4286 |
SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, XNP_ITEM_LANG_LEN, 0, lang, 0, &cbLang ); |
SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, XNP_ITEM_LANG_LEN, 0, lang, 0, &cbLang ); |
| 4287 |
SQLBindParameter(hstmt, 12, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &item_id, 0, &cbItem_id ); |
SQLBindParameter(hstmt, 12, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &item_id, 0, &cbItem_id ); |
| 4288 |
|
|
| 4289 |
|
//DBから得られたカラムの値をitem構造体へコピーする |
| 4290 |
strncpy2( (char*)title, item -> getTitle(), XNP_ITEM_TITLE_LEN ); |
strncpy2( (char*)title, item -> getTitle(), XNP_ITEM_TITLE_LEN ); |
| 4291 |
strncpy2( (char*)keywords, item -> getKeywords(), XNP_ITEM_KEYWORDS_LEN ); |
strncpy2( (char*)keywords, item -> getKeywords(), XNP_ITEM_KEYWORDS_LEN ); |
| 4292 |
strncpy2( (char*)description, item -> getDescription(), XNP_ITEM_DESCRIPTION_LEN ); |
strncpy2( (char*)description, item -> getDescription(), XNP_ITEM_DESCRIPTION_LEN ); |
| 4391 |
/** |
/** |
| 4392 |
* |
* |
| 4393 |
* アイテム(Basic Information)を削除する. |
* アイテム(Basic Information)を削除する. |
| 4394 |
|
* インデックスキーワード,アイテム間リンクからも削除する. |
| 4395 |
|
* |
| 4396 |
* |
* |
| 4397 |
* @param sid セッションID |
* @param sid セッションID |
| 4398 |
* @param item 削除したいアイテムの情報 |
* @param item 削除したいアイテムの情報 |
| 4435 |
1. delete item from index keywords |
1. delete item from index keywords |
| 4436 |
2. delete item from binders |
2. delete item from binders |
| 4437 |
3. delete item |
3. delete item |
| 4438 |
|
4. delete item from related_to |
| 4439 |
*/ |
*/ |
| 4440 |
|
|
| 4441 |
//1. delete item from index keywords |
//1. delete item from index keywords |
| 4501 |
ret = RES_ERROR; |
ret = RES_ERROR; |
| 4502 |
} |
} |
| 4503 |
|
|
|
|
|
| 4504 |
// 3. delete item |
// 3. delete item |
| 4505 |
sql = "DELETE FROM " + dbprefix + "_xoonips_item_basic "; |
sql = "DELETE FROM " + dbprefix + "_xoonips_item_basic "; |
| 4506 |
sql += "WHERE item_id = " + string( unsignedIntToString( itemid ) ); |
sql += "WHERE item_id = " + string( unsignedIntToString( itemid ) ); |
| 4532 |
ret = RES_ERROR; |
ret = RES_ERROR; |
| 4533 |
} |
} |
| 4534 |
|
|
| 4535 |
|
// 4. delete records from related_to |
| 4536 |
|
sql = "DELETE FROM " + dbprefix + "_xoonips_related_to "; |
| 4537 |
|
sql += "WHERE parent_id = " + string( unsignedIntToString( itemid ) ); |
| 4538 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 4539 |
|
SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ); |
| 4540 |
|
} |
| 4541 |
|
|
| 4542 |
if ( ret == RES_OK ){ |
if ( ret == RES_OK ){ |
| 4543 |
ret = insertMetadataEventAuto( itemid ); |
ret = insertMetadataEventAuto( itemid ); |
| 4544 |
} |
} |
| 6468 |
for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。 |
for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。 |
| 6469 |
string strXID = unsignedIntToString(descXID[i]); |
string strXID = unsignedIntToString(descXID[i]); |
| 6470 |
string linkTable = dbprefix + "_xoonips_index_item_link"; |
string linkTable = dbprefix + "_xoonips_index_item_link"; |
| 6471 |
|
string indexTable = dbprefix + "_xoonips_index"; |
| 6472 |
|
|
| 6473 |
// descXID[i] のアイテムの中で、被参照数が1のものを列挙 → 迷子にならないように移動 |
|
| 6474 |
// HAVINGを使うべき? "select item_id, count(*) as v1, sum(index_id=$index_id) as v2 from $link_table having v1=1 and v2=1" |
// descXID[i]がPrivate以下 && descXID[i]内のアイテムIを参照するPrivateなindexが1個しかない → Iを迷子にならないように親に移動 |
| 6475 |
// しかしsum内に<predicate>を書いてもいいのだろうか? 代わりにnullifとcoalesceならsqliteは通るが・・・ |
if ( index->getOpenLevel() == index::OL_PRIVATE ){ |
| 6476 |
// → 互換性の高い方法がよくわからないので、とりあえず自己joinにする。 |
string sql( "SELECT t1.index_item_link_id, t1.item_id, count(*) " |
| 6477 |
string sql( "SELECT t1.index_item_link_id " |
" FROM " + linkTable + " AS t1 " |
| 6478 |
" FROM " + linkTable + " AS t1 " |
" LEFT JOIN " + linkTable + " AS t2 ON t1.item_id = t2.item_id " |
| 6479 |
" LEFT JOIN " + linkTable + " AS t2 ON t1.item_id = t2.item_id and t2.index_id <> t1.index_id " |
" LEFT JOIN " + indexTable + " AS tx2 on t2.index_id = tx2.index_id " |
| 6480 |
" WHERE t1.index_id=" + strXID + " and t2.item_id is NULL" ); |
" WHERE t1.index_id=" + strXID + |
| 6481 |
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
" and tx2.open_level = " + unsignedIntToString(index::OL_PRIVATE) + |
| 6482 |
SQLUINTEGER sLinkID = 0; |
" group by t1.item_id " ); |
| 6483 |
SQLLEN len = 0; |
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 6484 |
SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len ); |
SQLUINTEGER sLinkID = 0, sItemID = 0, sCount = 0; |
| 6485 |
while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
SQLLEN len1 = 0, len2 = 0, len3 = 0; |
| 6486 |
string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) ); |
SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len1 ); |
| 6487 |
result = querySimple( "deleteIndex", sql2 ); |
SQLBindCol( hstmt, 2, SQL_C_ULONG, &sItemID, 0, &len2 ); |
| 6488 |
if( result != RES_OK ) |
SQLBindCol( hstmt, 3, SQL_C_ULONG, &sCount , 0, &len3 ); |
| 6489 |
|
while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
| 6490 |
|
if ( sCount == 1 ){ |
| 6491 |
|
string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) ); |
| 6492 |
|
result = querySimple( "deleteIndex", sql2 ); |
| 6493 |
|
if( result != RES_OK ) |
| 6494 |
|
break; |
| 6495 |
|
} |
| 6496 |
|
} |
| 6497 |
|
if ( result != RES_OK ) |
| 6498 |
break; |
break; |
| 6499 |
|
}else{ |
| 6500 |
|
string s( "SQLExecDirect in deleteIndex" ); |
| 6501 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 6502 |
|
s += "sql="; |
| 6503 |
|
s += string( sql ); |
| 6504 |
|
setLastErrorString( s.c_str( ) ); |
| 6505 |
|
result = RES_DB_QUERY_ERROR; |
| 6506 |
} |
} |
|
if ( result != RES_OK ) |
|
|
break; |
|
|
}else{ |
|
|
string s( "SQLExecDirect in deleteIndex" ); |
|
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
|
|
s += "sql="; |
|
|
s += string( sql ); |
|
|
setLastErrorString( s.c_str( ) ); |
|
|
result = RES_DB_QUERY_ERROR; |
|
|
break; |
|
| 6507 |
} |
} |
| 6508 |
|
|
| 6509 |
// descXID[i] のアイテムを全て削除 |
// descXID[i] のアイテムを全て削除 |
| 6510 |
sql = "DELETE from " + linkTable + " where index_id=" + strXID; |
string sql = "DELETE from " + linkTable + " where index_id=" + strXID; |
| 6511 |
result = querySimple( functionName, sql ); |
result = querySimple( functionName, sql ); |
| 6512 |
if ( result == RES_OK ){ |
if ( result == RES_OK ){ |
| 6513 |
// descXID[i] を削除 |
// descXID[i] を削除 |
| 6528 |
for ( int i = 0; i < affectedIIDsLen; i++ ){ |
for ( int i = 0; i < affectedIIDsLen; i++ ){ |
| 6529 |
insertMetadataEventAuto( affectedIIDs[i] ); |
insertMetadataEventAuto( affectedIIDs[i] ); |
| 6530 |
} |
} |
|
|
|
| 6531 |
}else{ |
}else{ |
| 6532 |
string s( "SQLAllocHandle in deleteIndex" ); |
string s( "SQLAllocHandle in deleteIndex" ); |
| 6533 |
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 6654 |
SQLLEN cbKey = SQL_NTS, cbValue = SQL_NTS; |
SQLLEN cbKey = SQL_NTS, cbValue = SQL_NTS; |
| 6655 |
result_t ret = RES_ERROR; |
result_t ret = RES_ERROR; |
| 6656 |
|
|
| 6657 |
|
// nijc_code か guestのON/OFF を書き換えたときは、item_statusをリセットする. |
| 6658 |
|
bool isNijcOrGuest = ( strcmp( key, XNP_CONFIG_REPOSITORY_NIJC_CODE ) == 0 || strcmp( key, XNP_CONFIG_PUBLIC_ITEM_TARGET_USER_KEY ) == 0 ); |
| 6659 |
|
char *oldValue = 0; |
| 6660 |
|
if ( isNijcOrGuest ) |
| 6661 |
|
getConfigValue( key, &oldValue ); |
| 6662 |
|
|
| 6663 |
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 6664 |
string sql( "UPDATE " + dbprefix + "_xoonips_config SET value=? WHERE name=?"); |
string sql( "UPDATE " + dbprefix + "_xoonips_config SET value=? WHERE name=?"); |
| 6665 |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
| 6730 |
setLastErrorString( s.c_str( ) ); |
setLastErrorString( s.c_str( ) ); |
| 6731 |
ret = RES_ERROR; |
ret = RES_ERROR; |
| 6732 |
} |
} |
| 6733 |
|
|
| 6734 |
|
// nijc_code か guestのON/OFF を書き換えたときは、item_statusをリセットする. |
| 6735 |
|
if ( ret == RES_OK && isNijcOrGuest && ( oldValue == 0 || strcmp( value, oldValue ) != 0 ) ) |
| 6736 |
|
refreshItemStatus(); |
| 6737 |
|
if ( oldValue ) |
| 6738 |
|
freeString( oldValue ); |
| 6739 |
|
|
| 6740 |
return ret; |
return ret; |
| 6741 |
} |
} |
| 6742 |
|
|
| 6994 |
void freeChangeLog( const changelog_t* ptr ){ delete[] ( changelog_t* )ptr; } |
void freeChangeLog( const changelog_t* ptr ){ delete[] ( changelog_t* )ptr; } |
| 6995 |
void freePubmed( const pubmed_t* ptr ){ delete[] ( pubmed_t* )ptr; } |
void freePubmed( const pubmed_t* ptr ){ delete[] ( pubmed_t* )ptr; } |
| 6996 |
void freeInt( const int* ptr ){ delete[] ( int* )ptr; } |
void freeInt( const int* ptr ){ delete[] ( int* )ptr; } |
|
void freeAmazonbook( const amazonbook_t* ptr ){ delete[] ( amazonbook_t* )ptr; } |
|
| 6997 |
|
|
| 6998 |
static string errstr; |
static string errstr; |
| 6999 |
const char* getLastErrorString() |
const char* getLastErrorString() |
| 7192 |
*DocID = atoi( ( char* )value ); |
*DocID = atoi( ( char* )value ); |
| 7193 |
xmlFree( value ); |
xmlFree( value ); |
| 7194 |
value = NULL; |
value = NULL; |
|
xmlFree(name); |
|
| 7195 |
return true; |
return true; |
| 7196 |
} |
} |
| 7197 |
} |
} |
| 8406 |
if ( until != 0 ) sql += " unix_timestamp(timestamp) <= " + unsignedIntToString(until) + " and "; |
if ( until != 0 ) sql += " unix_timestamp(timestamp) <= " + unsignedIntToString(until) + " and "; |
| 8407 |
sql += |
sql += |
| 8408 |
" stat.item_id >= " + unsignedIntToString(startIID) + |
" stat.item_id >= " + unsignedIntToString(startIID) + |
| 8409 |
|
" order by stat.item_id " + |
| 8410 |
" limit " + unsignedIntToString(limit); |
" limit " + unsignedIntToString(limit); |
| 8411 |
sqlexec_t s( "updateItemStatus", sql, &ret ); |
sqlexec_t s( "updateItemStatus", sql, &ret ); |
| 8412 |
//setLastErrorString( "selectiveHarvesting..." ); |
//setLastErrorString( "selectiveHarvesting..." ); |
| 8432 |
} |
} |
| 8433 |
|
|
| 8434 |
|
|
| 8435 |
|
/** |
| 8436 |
|
* |
| 8437 |
|
* アイテム間リンク情報を追加する. |
| 8438 |
|
* Platformユーザ以上の権限が必要. |
| 8439 |
|
* |
| 8440 |
|
* TODO itemidが閲覧できないアイテムをさしている場合,追加できない |
| 8441 |
|
* TODO parentid,itemidの何れかまたは一方が指すアイテムが存在しないとき,追加できない |
| 8442 |
|
* |
| 8443 |
|
* @param sid セッションID |
| 8444 |
|
* @param parentid リンク元アイテムのID |
| 8445 |
|
* @param itemid リンク先(被リンク)アイテムのID |
| 8446 |
|
* @return RES_OK |
| 8447 |
|
* @return RES_ERROR |
| 8448 |
|
* @return RES_NO_SUCH_SESSION |
| 8449 |
|
* @return RES_DB_QUERY_ERROR |
| 8450 |
|
* @return RES_DB_NOT_INITIALIZED |
| 8451 |
|
* @return RES_NO_WRITE_ACCESS_RIGHT parentidが編集できないアイテムをさしている,<br/>またはitemidが閲覧できないアイテムを指している,<br/>または XooNIpsユーザでない(activate待ち) |
| 8452 |
|
* |
| 8453 |
|
*/ |
| 8454 |
|
result_t insertRelatedTo( sessionid_t sid, itemid_t parentid, itemid_t itemid ) |
| 8455 |
|
{ |
| 8456 |
|
if( hdbc == NULL ) return RES_DB_NOT_INITIALIZED; |
| 8457 |
|
if( !isValidSessionID( sid ) ) return RES_NO_SUCH_SESSION; |
| 8458 |
|
if( !isActivatedBySession( sid ) ) return RES_NO_WRITE_ACCESS_RIGHT; |
| 8459 |
|
if( !getItemPermission( sid, parentid, item::OP_MODIFY ) ) return RES_NO_WRITE_ACCESS_RIGHT; |
| 8460 |
|
if( !getItemPermission( sid, itemid, item::OP_READ ) ) return RES_NO_READ_ACCESS_RIGHT; |
| 8461 |
|
|
| 8462 |
|
string sql; |
| 8463 |
|
SQLHANDLE hstmt = NULL; |
| 8464 |
|
SQLRETURN sqlcode; |
| 8465 |
|
result_t ret = RES_ERROR; |
| 8466 |
|
|
| 8467 |
|
|
| 8468 |
|
sql = "SELECT * FROM " + dbprefix + "_xoonips_related_to WHERE parent_id=" |
| 8469 |
|
+ string( unsignedIntToString( parentid ) ) + " AND item_id=" + string( unsignedIntToString( itemid ) ); |
| 8470 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 8471 |
|
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 8472 |
|
if( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
| 8473 |
|
//nothing to do because already registered |
| 8474 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 8475 |
|
return RES_OK; |
| 8476 |
|
} |
| 8477 |
|
} |
| 8478 |
|
}else{ |
| 8479 |
|
string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in insertRelatedTo" ); |
| 8480 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 8481 |
|
setLastErrorString( s.c_str( ) ); |
| 8482 |
|
return RES_ERROR; |
| 8483 |
|
} |
| 8484 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 8485 |
|
|
| 8486 |
|
sql = "INSERT INTO " + dbprefix + "_xoonips_related_to (parent_id, item_id) VALUES (" |
| 8487 |
|
+ string( unsignedIntToString( parentid ) ) + ", " + string( unsignedIntToString( itemid ) ) + ")"; |
| 8488 |
|
|
| 8489 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 8490 |
|
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 8491 |
|
ret = RES_OK; |
| 8492 |
|
}else{ |
| 8493 |
|
string s( "SQLExecuteDirect in insertRelatedTo " ); |
| 8494 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 8495 |
|
setLastErrorString( s.c_str( ) ); |
| 8496 |
|
ret = RES_DB_QUERY_ERROR; |
| 8497 |
|
} |
| 8498 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 8499 |
|
}else{ |
| 8500 |
|
string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in insertRelatedTo" ); |
| 8501 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 8502 |
|
setLastErrorString( s.c_str( ) ); |
| 8503 |
|
ret = RES_ERROR; |
| 8504 |
|
} |
| 8505 |
|
|
| 8506 |
|
return ret; |
| 8507 |
|
} |
| 8508 |
|
|
| 8509 |
|
|
| 8510 |
|
/** |
| 8511 |
|
* |
| 8512 |
|
* アイテム間リンク情報を削除する. |
| 8513 |
|
* |
| 8514 |
|
* @param sid セッションID |
| 8515 |
|
* @param parentid 削除したいリンクのリンク元アイテムのID |
| 8516 |
|
* @param itemid 削除したいリンクのリンク先(被リンク)アイテムのID |
| 8517 |
|
* @return RES_OK 削除に成功した,または指定されたリンク情報が存在しなかった. |
| 8518 |
|
* @return RES_ERROR |
| 8519 |
|
* @return RES_NO_SUCH_SESSION |
| 8520 |
|
* @return RES_DB_QUERY_ERROR |
| 8521 |
|
* @return RES_DB_NOT_INITIALIZED |
| 8522 |
|
* @return RES_NO_WRITE_ACCESS_RIGHT XooNIpsユーザでない(activate待ち),またはparentidのアイテム編集権限が無い |
| 8523 |
|
*/ |
| 8524 |
|
result_t deleteRelatedTo( sessionid_t sid, itemid_t parentid, itemid_t itemid ) |
| 8525 |
|
{ |
| 8526 |
|
if( hdbc == NULL ) return RES_DB_NOT_INITIALIZED; |
| 8527 |
|
if( !isValidSessionID( sid ) ) return RES_NO_SUCH_SESSION; |
| 8528 |
|
if( !isActivatedBySession( sid ) ) return RES_NO_WRITE_ACCESS_RIGHT; |
| 8529 |
|
if( !getItemPermission( sid, parentid, item::OP_MODIFY ) ) return RES_NO_WRITE_ACCESS_RIGHT; |
| 8530 |
|
|
| 8531 |
|
result_t ret = RES_ERROR; |
| 8532 |
|
string sql; |
| 8533 |
|
SQLRETURN sqlcode; |
| 8534 |
|
SQLHANDLE hstmt = NULL; |
| 8535 |
|
|
| 8536 |
|
sql = "DELETE FROM " + dbprefix + "_xoonips_related_to "; |
| 8537 |
|
sql += "WHERE parent_id=" + string( unsignedIntToString( parentid ) ) |
| 8538 |
|
+ " AND item_id = " + string( unsignedIntToString( itemid ) ); |
| 8539 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 8540 |
|
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 8541 |
|
ret = RES_OK; |
| 8542 |
|
}else{ |
| 8543 |
|
string s( "SQLExecuteDirect in deleteRelatedTo " ); |
| 8544 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 8545 |
|
setLastErrorString( s.c_str( ) ); |
| 8546 |
|
ret = RES_DB_QUERY_ERROR; |
| 8547 |
|
} |
| 8548 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 8549 |
|
}else{ |
| 8550 |
|
string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in deleteRelatedTo" ); |
| 8551 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 8552 |
|
setLastErrorString( s.c_str( ) ); |
| 8553 |
|
ret = RES_ERROR; |
| 8554 |
|
} |
| 8555 |
|
return ret; |
| 8556 |
|
} |
| 8557 |
|
|
| 8558 |
|
/** |
| 8559 |
|
* |
| 8560 |
|
* アイテム間リンク情報を取得する. |
| 8561 |
|
* リンク先アイテムの閲覧権限が無い場合,そのリンク情報は返さない. |
| 8562 |
|
* |
| 8563 |
|
* @param sid セッションID |
| 8564 |
|
* @param parentid リンク元アイテムのID |
| 8565 |
|
* @param itemids 結果を受け取る配列(paerntidからリンクしているアイテムのID) |
| 8566 |
|
* @param itemidsLen itemidsの数を受け取る変数 |
| 8567 |
|
* @return RES_OK |
| 8568 |
|
* @return RES_ERROR |
| 8569 |
|
* @return RES_NO_SUCH_SESSION |
| 8570 |
|
* @return RES_DB_QUERY_ERROR |
| 8571 |
|
* @return RES_DB_NOT_INITIALIZED |
| 8572 |
|
* @return RES_NO_WRITE_ACCESS_RIGHT parentidが指すにアクセス権が無い, XooNIpsユーザでない(activate待ち) |
| 8573 |
|
*/ |
| 8574 |
|
result_t getRelatedTo( sessionid_t sid, itemid_t parentid, itemid_t** itemids, int* itemidsLen ) |
| 8575 |
|
{ |
| 8576 |
|
if( hdbc == NULL ) return RES_DB_NOT_INITIALIZED; |
| 8577 |
|
if( !isValidSessionID( sid ) ) return RES_NO_SUCH_SESSION; |
| 8578 |
|
if( !getItemPermission( sid, parentid, item::OP_READ ) ) return RES_NO_READ_ACCESS_RIGHT; |
| 8579 |
|
|
| 8580 |
|
result_t ret = RES_ERROR; |
| 8581 |
|
string sql; |
| 8582 |
|
SQLRETURN sqlcode; |
| 8583 |
|
SQLHANDLE hstmt = NULL; |
| 8584 |
|
|
| 8585 |
|
sql = "SELECT count(*) FROM " + dbprefix + "_xoonips_related_to "; |
| 8586 |
|
sql += "WHERE parent_id=" + string( unsignedIntToString( parentid ) ); |
| 8587 |
|
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
| 8588 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 8589 |
|
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 8590 |
|
SQLUINTEGER cnt_tmp = 0;//リンクの総数(閲覧権限の有無に拘らない数) |
| 8591 |
|
SQLLEN len = 0; |
| 8592 |
|
SQLBindCol( hstmt, 1, SQL_C_ULONG, &cnt_tmp, 0, &len ); |
| 8593 |
|
if( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
| 8594 |
|
int count = 0; //閲覧可能なアイテムへのリンクの数 |
| 8595 |
|
itemid_t *ids_tmp = new itemid_t[ cnt_tmp ]; |
| 8596 |
|
if( cnt_tmp > 0 ){ |
| 8597 |
|
//retrieve IDs |
| 8598 |
|
SQLHANDLE hstmt2 = NULL; |
| 8599 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt2 ) ) == SQL_SUCCESS ) { |
| 8600 |
|
sql = "SELECT item_id FROM " + dbprefix + "_xoonips_related_to "; |
| 8601 |
|
sql += "WHERE parent_id=" + string( unsignedIntToString( parentid ) ); |
| 8602 |
|
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
| 8603 |
|
if( ( sqlcode = SQLExecDirect( hstmt2, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 8604 |
|
SQLUINTEGER iid = 0; |
| 8605 |
|
SQLLEN len = 0; |
| 8606 |
|
SQLBindCol( hstmt2, 1, SQL_C_ULONG, &iid, 0, &len ); |
| 8607 |
|
for( SQLUINTEGER i = 0; ( sqlcode = SQLFetch( hstmt2 ) ) == SQL_SUCCESS && i < cnt_tmp ; i++ ){ |
| 8608 |
|
if( getItemPermission( sid, iid, item::OP_READ ) ){ |
| 8609 |
|
ids_tmp[ count ] = iid; |
| 8610 |
|
count++; |
| 8611 |
|
} |
| 8612 |
|
} |
| 8613 |
|
*itemids = new itemid_t[ count ]; |
| 8614 |
|
if( count > 0 ) memcpy( *itemids, ids_tmp, sizeof( itemid_t ) * count ); |
| 8615 |
|
*itemidsLen = count; |
| 8616 |
|
delete[] ids_tmp; |
| 8617 |
|
ret = RES_OK; |
| 8618 |
|
}else{ |
| 8619 |
|
setLastErrorString( "SQLExecDirect in getRelatedTo" ); |
| 8620 |
|
ret = RES_DB_QUERY_ERROR; |
| 8621 |
|
} |
| 8622 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt2 ); |
| 8623 |
|
}else{ |
| 8624 |
|
string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in getRelatedTo" ); |
| 8625 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 8626 |
|
setLastErrorString( s.c_str( ) ); |
| 8627 |
|
ret = RES_ERROR; |
| 8628 |
|
} |
| 8629 |
|
}else{ |
| 8630 |
|
*itemids = new itemid_t[ 0 ]; |
| 8631 |
|
*itemidsLen = 0; |
| 8632 |
|
ret = RES_OK; |
| 8633 |
|
} |
| 8634 |
|
|
| 8635 |
|
}else{ |
| 8636 |
|
string s( "SQLFetch in getRelatedTo " ); |
| 8637 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 8638 |
|
setLastErrorString( s.c_str( ) ); |
| 8639 |
|
ret = RES_DB_QUERY_ERROR; |
| 8640 |
|
} |
| 8641 |
|
}else{ |
| 8642 |
|
string s( "SQLExecuteDirect in getRelatedTo " ); |
| 8643 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 8644 |
|
setLastErrorString( s.c_str( ) ); |
| 8645 |
|
ret = RES_DB_QUERY_ERROR; |
| 8646 |
|
} |
| 8647 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 8648 |
|
}else{ |
| 8649 |
|
string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in getRelatedTo" ); |
| 8650 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 8651 |
|
setLastErrorString( s.c_str( ) ); |
| 8652 |
|
ret = RES_ERROR; |
| 8653 |
|
} |
| 8654 |
|
return ret; |
| 8655 |
|
} |