| 22 |
* |
* |
| 23 |
* $Revision$ |
* $Revision$ |
| 24 |
* $Log$ |
* $Log$ |
| 25 |
|
* Revision 1.118.2.7 2006/10/04 09:25:21 tani |
| 26 |
|
* activate: accept only guest session or login user's session. |
| 27 |
|
* |
| 28 |
|
* Revision 1.118.2.6 2006/10/04 08:31:05 tani |
| 29 |
|
* activate: don't valid session for activation by user. |
| 30 |
|
* |
| 31 |
|
* Revision 1.118.2.5 2006/08/24 09:59:20 aga4096 |
| 32 |
|
* ・[ #8723 ] STABLE2 のALでDB接続文字コード指定 のパッチをあてた. |
| 33 |
|
* |
| 34 |
|
* Revision 1.118.2.4 2006/06/30 02:46:02 aga4096 |
| 35 |
|
* ・MySQL5.0.22では certify.php で常に No items found. になる場合があるのを修正. |
| 36 |
|
* |
| 37 |
|
* Revision 1.118.2.3 2006/04/12 09:20:12 aga4096 |
| 38 |
|
* ・insert_index で item_type_id が0になる場合があるのを修正. |
| 39 |
|
* |
| 40 |
|
* Revision 1.118.2.2 2006/02/28 04:49:17 aga4096 |
| 41 |
|
* ・NIJC code, guestのon/offを書き換えたときに item_status をリセットする. |
| 42 |
|
* |
| 43 |
|
* Revision 1.118.2.1 2006/02/14 05:13:17 aga4096 |
| 44 |
|
* ・アイテムが private/index_a と public/index_b に登録された状態で、 private/index_aを削除するとおかしくなるのを修正. |
| 45 |
|
* |
| 46 |
* Revision 1.118 2006/01/10 10:56:30 tani |
* Revision 1.118 2006/01/10 10:56:30 tani |
| 47 |
* selectiveHarvesting:stat.item_idでorder by(asc) |
* selectiveHarvesting:stat.item_idでorder by(asc) |
| 48 |
* |
* |
| 1174 |
return sql; |
return sql; |
| 1175 |
} |
} |
| 1176 |
|
|
| 1177 |
|
/** |
| 1178 |
|
* |
| 1179 |
|
* Set the character code for database connection |
| 1180 |
|
* |
| 1181 |
|
* @param type DBTYPE_MYSQL or DBTYPE_SQLITE |
| 1182 |
|
* @return RES_OK |
| 1183 |
|
* @return RES_DB_INITIALIZE_ERROR |
| 1184 |
|
* @see result_t |
| 1185 |
|
*/ |
| 1186 |
|
static result_t setCharset( dbtype_t type ) { |
| 1187 |
|
SQLRETURN sqlcode; |
| 1188 |
|
SQLHANDLE hstmt = NULL; |
| 1189 |
|
string sql; |
| 1190 |
|
result_t ret; |
| 1191 |
|
ret = RES_OK; |
| 1192 |
|
#ifdef USE_MYSQL_CHARSET |
| 1193 |
|
if( type == DBTYPE_MYSQL ) { |
| 1194 |
|
sql = "SET NAMES "; |
| 1195 |
|
sql += MYSQL_CHARSET; |
| 1196 |
|
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 1197 |
|
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) == SQL_SUCCESS ) ) { |
| 1198 |
|
ret = RES_OK; |
| 1199 |
|
syslog_printf( "setCharset succeed" ); |
| 1200 |
|
} else { |
| 1201 |
|
string s( "SQLExecDirect in setCharset "); |
| 1202 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 1203 |
|
s += string( ", sql=" ) + string( sql ); |
| 1204 |
|
setLastErrorString( s.c_str() ); |
| 1205 |
|
ret = RES_DB_INITIALIZE_ERROR; |
| 1206 |
|
} |
| 1207 |
|
SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); |
| 1208 |
|
} else { |
| 1209 |
|
string s( "SQLAllocHandle in setCharset "); |
| 1210 |
|
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 1211 |
|
setLastErrorString( s.c_str() ); |
| 1212 |
|
ret = RES_DB_INITIALIZE_ERROR; |
| 1213 |
|
} |
| 1214 |
|
} |
| 1215 |
|
#endif |
| 1216 |
|
return ret; |
| 1217 |
|
} |
| 1218 |
|
|
| 1219 |
|
|
| 1220 |
/** |
/** |
| 1221 |
* |
* |
| 1275 |
return RES_DB_CONNECT_ERROR; |
return RES_DB_CONNECT_ERROR; |
| 1276 |
} |
} |
| 1277 |
syslog_printf( "initializeDB succeed" ); |
syslog_printf( "initializeDB succeed" ); |
| 1278 |
return RES_OK; |
return setCharset( dbtype ); |
| 1279 |
} |
} |
| 1280 |
|
|
| 1281 |
/** |
/** |
| 1361 |
result_t activate( sessionid_t sid, userid_t uid, bool activate ) |
result_t activate( sessionid_t sid, userid_t uid, bool activate ) |
| 1362 |
{ |
{ |
| 1363 |
if( hdbc == NULL ) return RES_DB_NOT_INITIALIZED; |
if( hdbc == NULL ) return RES_DB_NOT_INITIALIZED; |
| 1364 |
if( !isValidSessionID( sid ) ) return RES_NO_SUCH_SESSION; |
if( sid != session_t::SID_GUEST |
| 1365 |
|
&& !isValidSessionID( sid ) ) return RES_NO_SUCH_SESSION; |
| 1366 |
|
|
| 1367 |
string sql; |
string sql; |
| 1368 |
SQLHANDLE hstmt = NULL; |
SQLHANDLE hstmt = NULL; |
| 1976 |
if ( ret == RES_OK ){ |
if ( ret == RES_OK ){ |
| 1977 |
// private index作成 |
// private index作成 |
| 1978 |
index_t index; |
index_t index; |
|
index.setItemTypeID(item::ITID_INDEX); |
|
|
index.setContributorUID(*uid); |
|
| 1979 |
index.setParentIndexID(item::IID_ROOT); |
index.setParentIndexID(item::IID_ROOT); |
| 1980 |
index.setOwnerUID(*uid); |
index.setOwnerUID(*uid); |
| 1981 |
index.setOpenLevel(index::OL_PRIVATE); |
index.setOpenLevel(index::OL_PRIVATE); |
| 3055 |
userid_t uid; |
userid_t uid; |
| 3056 |
ret = sessionID2UID( sid, &uid ); |
ret = sessionID2UID( sid, &uid ); |
| 3057 |
if ( ret == RES_OK ){ |
if ( ret == RES_OK ){ |
|
index.setItemTypeID(item::ITID_INDEX); |
|
|
index.setContributorUID(uid); |
|
| 3058 |
index.setParentIndexID(item::IID_ROOT); |
index.setParentIndexID(item::IID_ROOT); |
| 3059 |
index.setOwnerGID(*gid); |
index.setOwnerGID(*gid); |
| 3060 |
index.setOpenLevel(index::OL_GROUP_ONLY); |
index.setOpenLevel(index::OL_GROUP_ONLY); |
| 5841 |
} |
} |
| 5842 |
|
|
| 5843 |
/** インデックスを作成する。引数のチェックは行わない。 |
/** インデックスを作成する。引数のチェックは行わない。 |
| 5844 |
|
* item_type_id, contributor_uid を上書きする。 |
| 5845 |
*/ |
*/ |
| 5846 |
static result_t insertIndexInternal( sessionid_t sid, index_t *index, indexid_t *xid ){ |
static result_t insertIndexInternal( sessionid_t sid, index_t *index, indexid_t *xid ){ |
| 5847 |
itemid_t iid; |
itemid_t iid; |
| 5848 |
|
|
| 5849 |
|
index->setItemTypeID(item::ITID_INDEX); |
| 5850 |
|
index->setContributorUID(0); |
| 5851 |
result_t result = insertItem( sid, index, &iid ); |
result_t result = insertItem( sid, index, &iid ); |
| 5852 |
if ( result == RES_OK ){ |
if ( result == RES_OK ){ |
| 5853 |
string nullString("NULL"); |
string nullString("NULL"); |
| 6514 |
for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。 |
for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。 |
| 6515 |
string strXID = unsignedIntToString(descXID[i]); |
string strXID = unsignedIntToString(descXID[i]); |
| 6516 |
string linkTable = dbprefix + "_xoonips_index_item_link"; |
string linkTable = dbprefix + "_xoonips_index_item_link"; |
| 6517 |
|
string indexTable = dbprefix + "_xoonips_index"; |
| 6518 |
|
|
| 6519 |
// descXID[i] のアイテムの中で、被参照数が1のものを列挙 → 迷子にならないように移動 |
|
| 6520 |
// 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を迷子にならないように親に移動 |
| 6521 |
// しかしsum内に<predicate>を書いてもいいのだろうか? 代わりにnullifとcoalesceならsqliteは通るが・・・ |
if ( index->getOpenLevel() == index::OL_PRIVATE ){ |
| 6522 |
// → 互換性の高い方法がよくわからないので、とりあえず自己joinにする。 |
string sql( "SELECT t1.index_item_link_id, t1.item_id, count(*) " |
| 6523 |
string sql( "SELECT t1.index_item_link_id " |
" FROM " + linkTable + " AS t1 " |
| 6524 |
" FROM " + linkTable + " AS t1 " |
" LEFT JOIN " + linkTable + " AS t2 ON t1.item_id = t2.item_id " |
| 6525 |
" 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 " |
| 6526 |
" WHERE t1.index_id=" + strXID + " and t2.item_id is NULL" ); |
" WHERE t1.index_id=" + strXID + |
| 6527 |
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
" and tx2.open_level = " + unsignedIntToString(index::OL_PRIVATE) + |
| 6528 |
SQLUINTEGER sLinkID = 0; |
" group by t1.item_id " ); |
| 6529 |
SQLLEN len = 0; |
if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){ |
| 6530 |
SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len ); |
SQLUINTEGER sLinkID = 0, sItemID = 0, sCount = 0; |
| 6531 |
while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
SQLLEN len1 = 0, len2 = 0, len3 = 0; |
| 6532 |
string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) ); |
SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len1 ); |
| 6533 |
result = querySimple( "deleteIndex", sql2 ); |
SQLBindCol( hstmt, 2, SQL_C_ULONG, &sItemID, 0, &len2 ); |
| 6534 |
if( result != RES_OK ) |
SQLBindCol( hstmt, 3, SQL_C_ULONG, &sCount , 0, &len3 ); |
| 6535 |
|
while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){ |
| 6536 |
|
if ( sCount == 1 ){ |
| 6537 |
|
string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) ); |
| 6538 |
|
result = querySimple( "deleteIndex", sql2 ); |
| 6539 |
|
if( result != RES_OK ) |
| 6540 |
|
break; |
| 6541 |
|
} |
| 6542 |
|
} |
| 6543 |
|
if ( result != RES_OK ) |
| 6544 |
break; |
break; |
| 6545 |
|
}else{ |
| 6546 |
|
string s( "SQLExecDirect in deleteIndex" ); |
| 6547 |
|
s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode ); |
| 6548 |
|
s += "sql="; |
| 6549 |
|
s += string( sql ); |
| 6550 |
|
setLastErrorString( s.c_str( ) ); |
| 6551 |
|
result = RES_DB_QUERY_ERROR; |
| 6552 |
} |
} |
|
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; |
|
| 6553 |
} |
} |
| 6554 |
|
|
| 6555 |
// descXID[i] のアイテムを全て削除 |
// descXID[i] のアイテムを全て削除 |
| 6556 |
sql = "DELETE from " + linkTable + " where index_id=" + strXID; |
string sql = "DELETE from " + linkTable + " where index_id=" + strXID; |
| 6557 |
result = querySimple( functionName, sql ); |
result = querySimple( functionName, sql ); |
| 6558 |
if ( result == RES_OK ){ |
if ( result == RES_OK ){ |
| 6559 |
// descXID[i] を削除 |
// descXID[i] を削除 |
| 6574 |
for ( int i = 0; i < affectedIIDsLen; i++ ){ |
for ( int i = 0; i < affectedIIDsLen; i++ ){ |
| 6575 |
insertMetadataEventAuto( affectedIIDs[i] ); |
insertMetadataEventAuto( affectedIIDs[i] ); |
| 6576 |
} |
} |
|
|
|
| 6577 |
}else{ |
}else{ |
| 6578 |
string s( "SQLAllocHandle in deleteIndex" ); |
string s( "SQLAllocHandle in deleteIndex" ); |
| 6579 |
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode ); |
| 6700 |
SQLLEN cbKey = SQL_NTS, cbValue = SQL_NTS; |
SQLLEN cbKey = SQL_NTS, cbValue = SQL_NTS; |
| 6701 |
result_t ret = RES_ERROR; |
result_t ret = RES_ERROR; |
| 6702 |
|
|
| 6703 |
|
// nijc_code か guestのON/OFF を書き換えたときは、item_statusをリセットする. |
| 6704 |
|
bool isNijcOrGuest = ( strcmp( key, XNP_CONFIG_REPOSITORY_NIJC_CODE ) == 0 || strcmp( key, XNP_CONFIG_PUBLIC_ITEM_TARGET_USER_KEY ) == 0 ); |
| 6705 |
|
char *oldValue = 0; |
| 6706 |
|
if ( isNijcOrGuest ) |
| 6707 |
|
getConfigValue( key, &oldValue ); |
| 6708 |
|
|
| 6709 |
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) { |
| 6710 |
string sql( "UPDATE " + dbprefix + "_xoonips_config SET value=? WHERE name=?"); |
string sql( "UPDATE " + dbprefix + "_xoonips_config SET value=? WHERE name=?"); |
| 6711 |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
| 6776 |
setLastErrorString( s.c_str( ) ); |
setLastErrorString( s.c_str( ) ); |
| 6777 |
ret = RES_ERROR; |
ret = RES_ERROR; |
| 6778 |
} |
} |
| 6779 |
|
|
| 6780 |
|
// nijc_code か guestのON/OFF を書き換えたときは、item_statusをリセットする. |
| 6781 |
|
if ( ret == RES_OK && isNijcOrGuest && ( oldValue == 0 || strcmp( value, oldValue ) != 0 ) ) |
| 6782 |
|
refreshItemStatus(); |
| 6783 |
|
if ( oldValue ) |
| 6784 |
|
freeString( oldValue ); |
| 6785 |
|
|
| 6786 |
return ret; |
return ret; |
| 6787 |
} |
} |
| 6788 |
|
|
| 7624 |
SQLRETURN sqlcode; |
SQLRETURN sqlcode; |
| 7625 |
SQLLEN count = 0; |
SQLLEN count = 0; |
| 7626 |
userid_t sess_uid; |
userid_t sess_uid; |
| 7627 |
|
|
| 7628 |
|
bool is_moderator = false; |
| 7629 |
|
|
| 7630 |
if( ( ret = sessionID2UID( sid, &sess_uid ) ) != RES_OK ) return ret; |
if( ( ret = sessionID2UID( sid, &sess_uid ) ) != RES_OK ) return ret; |
| 7631 |
|
|
| 7632 |
sql = "SELECT DISTINCT tlink.index_id, tlink.item_id"; |
sql = "SELECT DISTINCT tlink.index_id, tlink.item_id"; |
| 7633 |
sql += " FROM " + dbprefix + "_xoonips_index_item_link AS tlink"; |
sql += " FROM " + dbprefix + "_xoonips_index_item_link AS tlink"; |
| 7634 |
sql += " LEFT JOIN " + dbprefix + "_xoonips_index AS tx ON tlink.index_id = tx.index_id"; |
sql += " LEFT JOIN " + dbprefix + "_xoonips_index AS tx ON tlink.index_id = tx.index_id"; |
| 7635 |
sql += " LEFT JOIN " + dbprefix + "_xoonips_item_basic AS ti ON tlink.item_id = ti.item_id"; |
sql += " LEFT JOIN " + dbprefix + "_xoonips_item_basic AS ti ON tlink.item_id = ti.item_id"; |
| 7636 |
sql += " LEFT JOIN " + dbprefix + "_xoonips_groups_users_link AS tgulink ON tgulink.gid = tx.gid"; |
|
| 7637 |
sql += " WHERE open_level<=" + unsignedIntToString( index::OL_GROUP_ONLY ); |
is_moderator = isModerator( sid, sess_uid ); |
| 7638 |
|
if( ! is_moderator ) { |
| 7639 |
|
sql += " LEFT JOIN " + dbprefix + "_xoonips_groups_users_link AS tgulink ON tgulink.gid = tx.gid"; |
| 7640 |
|
} |
| 7641 |
|
sql += " WHERE open_level<=" + unsignedIntToString( index::OL_GROUP_ONLY ); |
| 7642 |
sql += " AND certify_state=" + unsignedIntToString( index::CERTIFY_REQUIRED ); |
sql += " AND certify_state=" + unsignedIntToString( index::CERTIFY_REQUIRED ); |
| 7643 |
sql += " AND item_type_id !=" + unsignedIntToString( item::ITID_INDEX ); |
sql += " AND item_type_id !=" + unsignedIntToString( item::ITID_INDEX ); |
| 7644 |
sql += " AND ( is_admin=1 AND tgulink.uid=" + unsignedIntToString( sess_uid ); |
|
| 7645 |
sql += string( isModerator( sid, sess_uid ) ? " OR 1)" : " OR 0)" ); //モデレータならOR 1,それ以外は OR 0 |
if( ! is_moderator ) { |
| 7646 |
|
sql += " AND is_admin=1 AND tgulink.uid=" + unsignedIntToString( sess_uid ); |
| 7647 |
|
} |
| 7648 |
|
|
| 7649 |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() ); |
| 7650 |
|
|
| 7651 |
if( countResultRows( sql.c_str(), &count ) == RES_OK ){ |
if( countResultRows( sql.c_str(), &count ) == RES_OK ){ |