Develop and Download Open Source Software

Browse CVS Repository

Diff of /xoonips/AL/commonal.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.103 by tani, Tue Aug 23 07:34:24 2005 UTC revision 1.104 by aga4096, Mon Aug 29 02:05:34 2005 UTC
# Line 22  Line 22 
22   *   *
23   * $Revision$   * $Revision$
24   * $Log$   * $Log$
25     * Revision 1.104  2005/08/29 02:05:34  aga4096
26     * ・xnp_update_item_status(), xnp_refresh_item_status(), xnp_selective_harvesting() を追加.
27     *
28   * Revision 1.103  2005/08/23 07:34:24  tani   * Revision 1.103  2005/08/23 07:34:24  tani
29   * Language対応: getItems, _insetItem, updateItem   * Language対応: getItems, _insetItem, updateItem
30   *   *
# Line 463  static dbtype_t dbtype; //!< MySQL/SQLit Line 466  static dbtype_t dbtype; //!< MySQL/SQLit
466  static SQLHANDLE henv = NULL;  static SQLHANDLE henv = NULL;
467  static SQLHANDLE hdbc = NULL;  static SQLHANDLE hdbc = NULL;
468    
469    typedef enum {
470        ME_CREATED = 1,
471        ME_MODIFIED,
472        ME_DELETED
473    } metadataevent_t;
474    
475    //構造体 dateがNULLなら0
476    typedef struct{
477        time_t createdTimestamp;
478        time_t modifiedTimestamp;
479        time_t deletedTimestamp;
480        int isDeleted;
481    } itemstatus_t;
482    
483  static bool processEsummary(xmlTextReaderPtr reader, pubmed_t* p);  static bool processEsummary(xmlTextReaderPtr reader, pubmed_t* p);
484  static bool processEsearch(xmlTextReaderPtr reader, pubmed_t* p, int* DocID );  static bool processEsearch(xmlTextReaderPtr reader, pubmed_t* p, int* DocID );
485  static void processEfetch(xmlTextReaderPtr reader, pubmed_t* p);  static void processEfetch(xmlTextReaderPtr reader, pubmed_t* p);
# Line 475  static void setLastErrorString( const ch Line 492  static void setLastErrorString( const ch
492  static result_t checkTitleConflict( sessionid_t sid, indexid_t parentIndexID, const char *title, bool *conflict );  static result_t checkTitleConflict( sessionid_t sid, indexid_t parentIndexID, const char *title, bool *conflict );
493  static result_t _insertItem( sessionid_t sid, const item_t* item, itemid_t* itemid, bool direct );  static result_t _insertItem( sessionid_t sid, const item_t* item, itemid_t* itemid, bool direct );
494  static result_t getEvents(sessionid_t sid, event_t** events, int* eventsLen, string condition );  static result_t getEvents(sessionid_t sid, event_t** events, int* eventsLen, string condition );
495    static result_t insertMetadataEvent( metadataevent_t me, itemid_t iid );
496    static result_t getMetadataEvent( itemid_t iid, itemstatus_t *status );
497    static result_t insertMetadataEventAuto( itemid_t iid, bool isCreate = false );
498    
499  static void syslog_printf( char* format, ... )  static void syslog_printf( char* format, ... )
500  {  {
# Line 486  static void syslog_printf( char* format, Line 506  static void syslog_printf( char* format,
506  #endif  #endif
507  }  }
508    
509    /**  ',' . implode( ',', pi ) の形の文字列を作成する。先頭にcommaがあるので注意
510     * @param pi   int配列
511     * @param len  配列の長さ
512     */
513    static string getCsvStr( const itemid_t *pi, int len ){
514        char *buf = new char[(sizeof(int)*3+1)*len+1];
515        buf[0] = '\0';
516        char *p = buf;
517        for ( int i = 0; i < len; i++ ){
518            int len = sprintf( p, ",%u", pi[i] );
519            p += len;
520        }
521        string iids_str(buf);
522        delete[] buf;
523        return iids_str;
524    }
525    
526  /**  /**
527   *   *
528   * public_item_target_userの設定値が'all'ならtrueをかえす   * public_item_target_userの設定値が'all'ならtrueをかえす
# Line 595  static bool isModeratorBySession( sessio Line 632  static bool isModeratorBySession( sessio
632  }  }
633    
634    
635    // SQLAllocHandle〜SQLExecDirectのエラー処理とhstmtの開放が面倒なのでクラス化する
636    class sqlexec_t {
637    private:
638        SQLRETURN sqlcode;
639        SQLHANDLE hstmt;
640    public:
641        SQLRETURN getSqlcode(){ return sqlcode; }
642        SQLHANDLE getHstmt(){ return hstmt; }
643        //SQLRETURN SQLFetch(){ return sqlcode = SQLFetch(hstmt); } // あまりwrapperを作りたくないので廃止
644        
645        /** コンストラクタ: SQLAllocHandle, SQLExecDirectを行う。成功ならgetSqlcode()==SQL_SUCCESS
646         * @param functionName エラーログに書く関数名
647         * @param sql 実行すべきSQL
648         * @param ret エラーコードの出力先
649         */
650        sqlexec_t( const char *functionName, string &sql, result_t *ret ){
651            sqlcode = 0;
652            hstmt = 0;
653            
654            if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) {
655                if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){
656                    return;
657                }else {
658                    string s( "SQLExecDirect in  " );
659                    s += functionName;
660                    s += " ";
661                    s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode );
662                    s += " sql=";
663                    s += string( sql );
664                    setLastErrorString( s.c_str( ) );
665                    *ret = RES_DB_QUERY_ERROR;
666                    return;
667                }
668            }else {
669                string s( "SQLAllocHandle(SQL_HANDLE_STMT,...) in " );
670                s += functionName;
671                s += " ";
672                s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode );
673                setLastErrorString( s.c_str( ) );
674                *ret = RES_ERROR;
675                return;
676            }
677        }
678        ~sqlexec_t(){
679            if ( hstmt )
680                SQLFreeHandle( SQL_HANDLE_STMT, hstmt );
681        }
682    };
683    
684    
685  /** SQLを実行する。結果は捨てる。  /** SQLを実行する。結果は捨てる。
# Line 4160  result_t updateItem( sessionid_t sid, co Line 4245  result_t updateItem( sessionid_t sid, co
4245                                      syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );                                      syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );
4246                                      querySimple( "updateItem", sql );                                      querySimple( "updateItem", sql );
4247                                  }                                  }
4248                                  ret = RES_OK;                                  ret = insertMetadataEventAuto( item_id, true );
4249                              }else{                              }else{
4250                                  string s( "SQLExecDirect in updateItem" );                                  string s( "SQLExecDirect in updateItem" );
4251                                  s += odbcDiagString( SQL_HANDLE_STMT, hstmt2, sqlcode );                                  s += odbcDiagString( SQL_HANDLE_STMT, hstmt2, sqlcode );
# Line 4355  result_t deleteItem( sessionid_t sid, it Line 4440  result_t deleteItem( sessionid_t sid, it
4440          ret = RES_ERROR;          ret = RES_ERROR;
4441      }      }
4442            
4443        if ( ret == RES_OK ){
4444            ret = insertMetadataEventAuto( itemid );
4445        }
4446      return ret;      return ret;
4447  }  }
4448    
# Line 4782  result_t setCertifyState( sessionid_t si Line 4870  result_t setCertifyState( sessionid_t si
4870          + " WHERE index_id=" + unsignedIntToString( xid )          + " WHERE index_id=" + unsignedIntToString( xid )
4871          + " AND item_id=" + unsignedIntToString( iid );          + " AND item_id=" + unsignedIntToString( iid );
4872      syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );      syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );
4873      return querySimple( "setCertifyState", sql );      result_t ret = querySimple( "setCertifyState", sql );
4874        if ( ret != RES_OK )
4875            return ret;
4876        return insertMetadataEventAuto( iid );
4877  }  }
4878    
4879  /**  /**
# Line 4870  result_t registerItem( sessionid_t sid, Line 4961  result_t registerItem( sessionid_t sid,
4961          syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );          syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );
4962          ret = querySimple( "registerItem", sql );          ret = querySimple( "registerItem", sql );
4963      }      }
4964        if ( ret == RES_OK ){
4965            ret = insertMetadataEventAuto( iid );
4966        }
4967      return ret;      return ret;
4968  }  }
4969    
# Line 4910  result_t unregisterItem( sessionid_t sid Line 5004  result_t unregisterItem( sessionid_t sid
5004          syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );          syslog_printf( "\nsql at %d=%s", __LINE__, sql.c_str() );
5005          ret = querySimple( "unregisterItem", sql );          ret = querySimple( "unregisterItem", sql );
5006      }      }
5007        if ( ret == RES_OK ){
5008            ret = insertMetadataEventAuto( iid );
5009        }
5010      return ret;      return ret;
5011  }  }
5012    
# Line 6103  result_t updateIndexInternal( sessionid_ Line 6200  result_t updateIndexInternal( sessionid_
6200          }          }
6201      }      }
6202            
6203        if ( newIndex->getOpenLevel() == index::OL_PUBLIC ){
6204            // ここでnewIndex以下の承認済みアイテムについて insertMetadataEventAuto を行う
6205            string xid_str;
6206            {
6207                indexid_t *descXID = 0;
6208                int descXIDLen;
6209                result = getDescendantIndexID( newIndex->getIndexID(), &descXID, &descXIDLen );
6210                if ( result != RES_OK ){
6211                    setLastErrorString( "in updateIndex: getDescendantIndexID failed" );
6212                    return RES_ERROR;
6213                }
6214                
6215                xid_str = getCsvStr( descXID, descXIDLen );
6216                delete[] descXID;
6217            }
6218            
6219            string sql =
6220              " select distinct item_id from " + dbprefix + "_xoonips_index_item_link "
6221              " where certify_state = " + unsignedIntToString(index::CERTIFIED) +
6222              "  and index_id in ( 0 " + xid_str + ")";
6223            sqlexec_t s( "updateIndex", sql, &result );
6224            if ( s.getSqlcode() == SQL_SUCCESS ){
6225                SQLUINTEGER iid = 0;
6226                SQLLEN cbIID = 0;
6227                SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &iid       , 0, &cbIID       );
6228                
6229                result = RES_OK;
6230                while ( SQLFetch( s.getHstmt() ) == SQL_SUCCESS ){
6231                    result = insertMetadataEventAuto( iid );
6232                    if ( result != RES_OK )
6233                        break;
6234                }
6235            }
6236            else return result;
6237        }
6238        
6239      return result;      return result;
6240    
6241  }  }
# Line 6162  result_t updateIndex( sessionid_t sid, i Line 6295  result_t updateIndex( sessionid_t sid, i
6295      return result;      return result;
6296  }  }
6297    
6298  /**  result_t deleteIndexInternal( sessionid_t sid, indexid_t xid, const index_t *&index, indexid_t *&descXID, itemid_t *&affectedIIDs )
  *  
  * インデックスキーワードを削除する  
  *  
  * @param sid セッションID  
  * @param xid 削除するインデックスキーワード  
  * @return RES_OK 成功  
  *  
  */  
 result_t deleteIndex( sessionid_t sid,  indexid_t xid )  
6299  {  {
6300      char *functionName = "deleteIndex";      char *functionName = "deleteIndex";
6301      result_t result;      result_t result;
# Line 6181  result_t deleteIndex( sessionid_t sid, Line 6305  result_t deleteIndex( sessionid_t sid,
6305      result = sessionID2UID( sid, &uid ); // sid から uid を得る      result = sessionID2UID( sid, &uid ); // sid から uid を得る
6306      if( result != RES_OK ) return result;      if( result != RES_OK ) return result;
6307            
     const index_t *index;  
6308      result = getIndex( sid, xid, &index );      result = getIndex( sid, xid, &index );
6309      if ( result != RES_OK )      if ( result != RES_OK )
6310          return result;          return result;
6311            
6312      if ( index->getIndexID() == item::IID_ROOT || index->getParentIndexID() == item::IID_ROOT ){      if ( index->getIndexID() == item::IID_ROOT || index->getParentIndexID() == item::IID_ROOT ){
         result = RES_ERROR;  
6313          setLastErrorString( "in deleteIndex: cannot delete system-created-index." );          setLastErrorString( "in deleteIndex: cannot delete system-created-index." );
6314            return RES_ERROR;
6315      }      }
6316      else {      
6317          if ( !isWritableInternal( sid, uid, index ) ){      if ( !isWritableInternal( sid, uid, index ) ){
6318              result = RES_NO_WRITE_ACCESS_RIGHT;          setLastErrorString( "in deleteIndex: no write access right." );
6319              setLastErrorString( "in deleteIndex: no write access right." );          return RES_NO_WRITE_ACCESS_RIGHT;
6320        }
6321        
6322        // 削除対象を列挙
6323        int descXIDLen;
6324        result = getDescendantIndexID( xid, &descXID, &descXIDLen );
6325        if ( result != RES_OK ){
6326            setLastErrorString( "in deleteIndex: getDescendantIndexID failed" );
6327            return RES_ERROR;
6328        }
6329        
6330        // 削除対象の中にBindersが入っている場合は、削除できない。
6331        for ( int i = 0; i < descXIDLen; i++ ){
6332            if ( descXID[i] == item::IID_BINDERS ){
6333                setLastErrorString( "in deleteIndex: target index contains Binders." );
6334                return RES_ERROR;
6335          }          }
6336          else {      }
6337              // 削除対象を列挙      
6338              indexid_t *descXID = 0;      int affectedIIDsLen = 0;
6339              int descXIDLen;      if ( index->getOpenLevel() == index::OL_PUBLIC ){
6340              result = getDescendantIndexID( xid, &descXID, &descXIDLen );          // ここでnewIndex以下の承認済みアイテムを記憶しておいて あとで insertMetadataEventAuto を行う
6341              if ( result != RES_OK ){          string sql = "select count(*) from " + dbprefix + "_xoonips_item_basic";
6342                  setLastErrorString( "in deleteIndex: getDescendantIndexID failed" );          unsigned int iidsLen;
6343                  return RES_ERROR;          result = queryGetUnsignedInt( "deleteIndex", sql, &iidsLen );
6344              }          if ( result != RES_OK )
6345                            return result;
6346              // 削除対象の中にBindersが入っている場合は、削除できない。          affectedIIDs = new itemid_t[iidsLen];
6347              for ( int i = 0; i < descXIDLen; i++ ){          string xid_str = getCsvStr( descXID, descXIDLen );
6348                  if ( descXID[i] == item::IID_BINDERS ){          sql = "select item_id from " + dbprefix + "_xoonips_index_item_link "
6349                      setLastErrorString( "in deleteIndex: target index contains Binders." );            "where certify_state=" + unsignedIntToString(index::CERTIFIED) +
6350                      return RES_ERROR;            " and index_id in ( 0 " + xid_str + ") ";
6351                  }          sqlexec_t s( "deleteIndex", sql, &result );
6352              }          if ( s.getSqlcode() != SQL_SUCCESS )
6353                return result;
6354            
6355            SQLUINTEGER iid = 0;
6356            SQLLEN cbIID = 0;
6357            SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &iid       , 0, &cbIID       );
6358            
6359            for ( affectedIIDsLen = 0; affectedIIDsLen < iidsLen &&  ( SQLFetch( s.getHstmt() ) == SQL_SUCCESS ); affectedIIDsLen++ ){
6360                affectedIIDs[affectedIIDsLen] = iid;
6361            }
6362        }
6363        
6364        SQLRETURN sqlcode;
6365        SQLHANDLE hstmt = NULL;    
6366        if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) {
6367            result = RES_OK;
6368            string strParentXID = unsignedIntToString( index->getParentIndexID() );
6369            for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。
6370                string strXID = unsignedIntToString(descXID[i]);
6371                string linkTable = dbprefix + "_xoonips_index_item_link";
6372                            
6373              SQLRETURN sqlcode;              // descXID[i] のアイテムの中で、被参照数が1のものを列挙 → 迷子にならないように移動
6374              SQLHANDLE hstmt = NULL;                  // HAVINGを使うべき? "select item_id, count(*) as v1, sum(index_id=$index_id) as v2 from $link_table having v1=1 and v2=1"
6375              if( ( sqlcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ) == SQL_SUCCESS ) {              // しかしsum内に<predicate>を書いてもいいのだろうか? 代わりにnullifとcoalesceならsqliteは通るが・・・
6376                  result = RES_OK;              //  → 互換性の高い方法がよくわからないので、とりあえず自己joinにする。
6377                  string strParentXID = unsignedIntToString( index->getParentIndexID() );              string sql( "SELECT t1.index_item_link_id "
6378                  for ( int i = descXIDLen-1; i >= 0; i-- ){ // 逆方向にして、途中で失敗した場合の惨事を防ぐ。descXIDは幅優先探索順に並んでいるので。                  " FROM " + linkTable + " AS t1 "
6379                      string strXID = unsignedIntToString(descXID[i]);                  " LEFT JOIN " + linkTable + " AS t2 ON t1.item_id = t2.item_id and t2.index_id <> t1.index_id "
6380                      string linkTable = dbprefix + "_xoonips_index_item_link";                  " WHERE t1.index_id=" + strXID + " and t2.item_id is NULL" );
6381                                    if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){
6382                      // descXID[i] のアイテムの中で、被参照数が1のものを列挙 → 迷子にならないように移動                  SQLUINTEGER sLinkID = 0;
6383                      // HAVINGを使うべき? "select item_id, count(*) as v1, sum(index_id=$index_id) as v2 from $link_table having v1=1 and v2=1"                  SQLLEN len = 0;
6384                      // しかしsum内に<predicate>を書いてもいいのだろうか? 代わりにnullifとcoalesceならsqliteは通るが・・・                  SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len );
6385                      //  → 互換性の高い方法がよくわからないので、とりあえず自己joinにする。                  while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){
6386                      string sql( "SELECT t1.index_item_link_id "                      string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) );
6387                          " FROM " + linkTable + " AS t1 "                      result = querySimple( "deleteIndex", sql2 );
6388                          " LEFT JOIN " + linkTable + " AS t2 ON t1.item_id = t2.item_id and t2.index_id <> t1.index_id "                      if( result != RES_OK )
                         " WHERE t1.index_id=" + strXID + " and t2.item_id is NULL" );  
                     if( ( sqlcode = SQLExecDirect( hstmt, (SQLCHAR*)sql.c_str(), sql.length() ) ) == SQL_SUCCESS ){  
                         SQLUINTEGER sLinkID = 0;  
                         SQLLEN len = 0;  
                         SQLBindCol( hstmt, 1, SQL_C_ULONG, &sLinkID, 0, &len );  
                         while ( ( sqlcode = SQLFetch( hstmt ) ) == SQL_SUCCESS ){  
                             string sql2( "UPDATE " + linkTable + " set index_id= " + strParentXID + " where index_item_link_id = " + unsignedIntToString(sLinkID) );  
                             result = querySimple( "deleteIndex", sql2 );  
                             if( result != RES_OK )  
                                 break;  
                         }  
                         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;  
6389                          break;                          break;
                     }  
                       
                     // descXID[i] のアイテムを全て削除  
                     sql = "DELETE from " + linkTable + " where index_id=" + strXID;  
                     result = querySimple( functionName, sql );  
                     if ( result == RES_OK ){  
                         // descXID[i] を削除  
                         sql = "DELETE from " + dbprefix + "_xoonips_item_basic where item_id =" + strXID;  
                         result = querySimple( functionName, sql );  
                         if ( result == RES_OK ){  
                             sql = "DELETE from " + dbprefix + "_xoonips_index      where index_id=" + strXID;  
                             result = querySimple( functionName, sql );  
                         }  
                     }  
6390                  }                  }
6391                    if ( result != RES_OK )
6392                        break;
6393              }else{              }else{
6394                  string s( "SQLAllocHandle in deleteIndex" );                  string s( "SQLExecDirect in deleteIndex" );
6395                  s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode );                  s += odbcDiagString( SQL_HANDLE_STMT, hstmt, sqlcode );
6396                    s += "sql=";
6397                    s += string( sql );
6398                  setLastErrorString( s.c_str( ) );                  setLastErrorString( s.c_str( ) );
6399                  result = RES_ERROR;                  result = RES_DB_QUERY_ERROR;
6400                    break;
6401              }              }
6402                            
6403              freeIndexID( descXID );              // descXID[i] のアイテムを全て削除
6404                sql = "DELETE from " + linkTable + " where index_id=" + strXID;
6405                result = querySimple( functionName, sql );
6406                if ( result == RES_OK ){
6407                    // descXID[i] を削除
6408                    sql = "DELETE from " + dbprefix + "_xoonips_item_basic where item_id =" + strXID;
6409                    result = querySimple( functionName, sql );
6410                    if ( result == RES_OK ){
6411                        sql = "DELETE from " + dbprefix + "_xoonips_index      where index_id=" + strXID;
6412                        result = querySimple( functionName, sql );
6413                    }
6414                }
6415          }          }
6416            
6417            // 影響を受けたはずのアイテムを insertMetadataEventAutoする
6418            for ( int i = 0; i < affectedIIDsLen; i++ ){
6419                insertMetadataEventAuto( affectedIIDs[i] );
6420            }
6421            
6422        }else{
6423            string s( "SQLAllocHandle in deleteIndex" );
6424            s += odbcDiagString( SQL_HANDLE_DBC, hdbc, sqlcode );
6425            setLastErrorString( s.c_str( ) );
6426            result = RES_ERROR;
6427      }      }
6428        
6429        return result;
6430    }
6431    
6432    /**
6433     *
6434     * インデックスキーワードを削除する
6435     *
6436     * @param sid セッションID
6437     * @param xid 削除するインデックスキーワード
6438     * @return RES_OK 成功
6439     *
6440     */
6441    result_t deleteIndex( sessionid_t sid,  indexid_t xid )
6442    {
6443        const index_t *index = 0;
6444        indexid_t *descXID = 0;
6445        itemid_t *affectedIIDs = 0;
6446        result_t result =  deleteIndexInternal( sid, xid, index, descXID, affectedIIDs );
6447        if ( index ) freeIndex( index );
6448        if ( descXID ) delete[] descXID;
6449        if ( affectedIIDs ) delete[] affectedIIDs;
6450      return result;      return result;
6451  }  }
6452    
# Line 7129  result_t extractPublicItemId(sessionid_t Line 7301  result_t extractPublicItemId(sessionid_t
7301      ret = sessionID2UID( sid, &uid );      ret = sessionID2UID( sid, &uid );
7302      if( ret != RES_OK ) return ret;      if( ret != RES_OK ) return ret;
7303            
7304      // 文字列 ',' . implode( ',', iids ) を作成      string iids_str = getCsvStr( iids, iidsLen );
     char *buf = new char[(sizeof(int)*3+1)*iidsLen+1];  
     buf[0] = '\0';  
     char *p = buf;  
     for ( int i = 0; i < iidsLen; i++ ){  
         int len = sprintf( p, ",%u", iids[i] );  
         p += len;  
     }  
     string iids_str(buf);  
     delete[] buf;  
       
7305            
7306      string sql =      string sql =
7307        " select ti.item_id, count(tx.index_id) "        " select ti.item_id, count(tx.index_id) "
# Line 7916  static result_t getEvents(sessionid_t si Line 8078  static result_t getEvents(sessionid_t si
8078      return ret;      return ret;
8079  }  }
8080    
8081    static result_t insertMetadataEvent( metadataevent_t me, itemid_t iid )
8082    {
8083        string sql;
8084        
8085        if ( me == ME_CREATED ){
8086            sql = "replace " + dbprefix + "_xoonips_item_status "
8087             " ( item_id, created_timestamp, modified_timestamp, deleted_timestamp, is_deleted ) values "
8088             " ( " + unsignedIntToString(iid) + ", unix_timestamp(now()), NULL, NULL, 0 )";
8089        }
8090        else if ( me == ME_MODIFIED ){
8091            sql = "update " + dbprefix + "_xoonips_item_status "
8092             " set modified_timestamp=unix_timestamp(now()), is_deleted=0 where item_id=" + unsignedIntToString(iid);
8093        }
8094        else if ( me == ME_DELETED ){
8095            sql = "update " + dbprefix + "_xoonips_item_status "
8096             " set deleted_timestamp=unix_timestamp(now()), is_deleted=1 where item_id=" + unsignedIntToString(iid);
8097        }
8098        else {
8099            return RES_ERROR;
8100        }
8101        
8102        return querySimple( "insertMetadataEvent", sql );
8103    }
8104    
8105    static result_t getMetadataEvent( itemid_t iid, itemstatus_t *status )
8106    {
8107        result_t ret = RES_ERROR;
8108        
8109        // allocate events[]
8110        string sql = "select created_timestamp, modified_timestamp, deleted_timestamp, is_deleted from "
8111         + dbprefix + "_xoonips_item_status where item_id=" + unsignedIntToString(iid);
8112        sqlexec_t s( "getMetadataEvent", sql, &ret );
8113        if ( s.getSqlcode() == SQL_SUCCESS ){
8114            SQLUINTEGER created, modified, deleted, isDeleted = 0;
8115            SQLLEN cbCreated = 0, cbModified = 0, cbDeleted = 0, cbIsDeleted = 0;
8116            SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &created  , 0, &cbCreated   );
8117            SQLBindCol( s.getHstmt(), 2, SQL_C_ULONG, &modified , 0, &cbModified  );
8118            SQLBindCol( s.getHstmt(), 3, SQL_C_ULONG, &deleted  , 0, &cbDeleted   );
8119            SQLBindCol( s.getHstmt(), 4, SQL_C_ULONG, &isDeleted, 0, &cbIsDeleted );
8120            
8121            if ( SQLFetch( s.getHstmt() ) == SQL_SUCCESS ){
8122                status->createdTimestamp  = created;
8123                status->modifiedTimestamp = modified;
8124                status->deletedTimestamp  = deleted;
8125                status->isDeleted = isDeleted;
8126                ret = RES_OK;
8127            }
8128            else {
8129                ret = RES_NO_SUCH_ITEM;
8130            }
8131        }
8132        return ret;
8133    }
8134    
8135    /** 適切にinsertMeatadataEventを行う
8136     * repository         item
8137     * is_deleted==0  &&  public    : isCreate ? ME_CREATED : ME_MODIFIED;
8138     * is_deleted==0  &&  nonpublic : ME_DELETED
8139     * is_deleted!=0  &&  public    : ME_CREATED
8140     * is_deleted!=0  &&  nonpubic  : -
8141     *
8142     */
8143    static result_t insertMetadataEventAuto( itemid_t iid, bool isCreate )
8144    {
8145        itemstatus_t is;
8146        result_t res = getMetadataEvent( iid, &is );
8147        if ( res != RES_OK ){
8148            if ( res == RES_NO_SUCH_ITEM )
8149                is.isDeleted = 1;
8150            else
8151                return res;
8152        }
8153        
8154        bool isPublic = getItemPermission( session::SID_GUEST, iid, item::OP_READ );
8155        
8156        metadataevent_t me;
8157        if ( is.isDeleted == 0 ){
8158            if ( isPublic )
8159                me = isCreate ? ME_CREATED : ME_MODIFIED;
8160            else
8161                me = ME_DELETED;
8162        }
8163        else {
8164            if ( isPublic )
8165                me = ME_CREATED;
8166            else
8167                return RES_OK;
8168        }
8169        
8170        return insertMetadataEvent( me, iid );
8171    }
8172    
8173    
8174    
8175    
8176    result_t updateItemStatus()
8177    {
8178        result_t ret = RES_ERROR;
8179        
8180        if ( isGuestEnabled() ){
8181            {
8182                // アイテムが公開済みで、item_statusが削除または非存在のものを修正
8183                string sql = "select distinct txil.item_id, tis.is_deleted "
8184                  " from "      + dbprefix + "_xoonips_index as tx, "
8185                                + dbprefix + "_xoonips_index_item_link as txil "
8186                  " left join " + dbprefix + "_xoonips_item_status as tis on txil.item_id = tis.item_id "
8187                  " where  tx.index_id=txil.index_id "
8188                    " and  txil.certify_state = " + unsignedIntToString( index::CERTIFIED ) +
8189                    " and  tx.open_level = " + unsignedIntToString( index::OL_PUBLIC );
8190                sqlexec_t s( "updateItemStatus", sql, &ret );
8191                if ( s.getSqlcode() == SQL_SUCCESS ){
8192                    SQLUINTEGER iid = 0, isDeleted = 0;
8193                    SQLLEN cbIID = 0, cbIsDeleted = 0;
8194                    SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &iid       , 0, &cbIID       );
8195                    SQLBindCol( s.getHstmt(), 2, SQL_C_ULONG, &isDeleted , 0, &cbIsDeleted );
8196                    
8197                    while ( SQLFetch( s.getHstmt() ) == SQL_SUCCESS ){
8198                        string sql;
8199                        if ( cbIsDeleted == SQL_NULL_DATA )
8200                            sql = "insert into " + dbprefix + "_xoonips_item_status "
8201                              "( item_id, created_timestamp, is_deleted ) values "
8202                              "( " + unsignedIntToString(iid) + ", unix_timestamp(now()), 0 )";
8203                        else
8204                            sql = "update "+ dbprefix + "_xoonips_item_status "
8205                              " set created_timestamp=unix_timestamp(now()), is_deleted=0 "
8206                              " where item_id=" + unsignedIntToString(iid);
8207                        ret = querySimple( "updateItemStatus", sql );
8208                        if ( ret ) return ret;
8209                    }
8210                }
8211                else return ret;
8212            }
8213            {
8214                // アイテムが非公開で、item_status.is_deleted=0のものを修正
8215                string sql = "select tis.item_id "
8216                  " from "      + dbprefix + "_xoonips_item_status as tis  "
8217                  " left join " + dbprefix + "_xoonips_index_item_link as tl on tl.item_id = tis.item_id and certify_state = " + unsignedIntToString(index::CERTIFIED) +
8218                  " left join " + dbprefix + "_xoonips_index           as tx on tx.index_id =tl.index_id and tx.open_level = " + unsignedIntToString(index::OL_PUBLIC) +
8219                  " where is_deleted=0 and tx.index_id is NULL ";
8220                sqlexec_t s( "updateItemStatus", sql, &ret );
8221                if ( s.getSqlcode() == SQL_SUCCESS ){
8222                    SQLUINTEGER iid = 0;
8223                    SQLLEN cbIID = 0;
8224                    SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &iid       , 0, &cbIID       );
8225                    
8226                    while ( SQLFetch( s.getHstmt() ) == SQL_SUCCESS ){
8227                        string sql;
8228                        sql = "update " + dbprefix + "_xoonips_item_status "
8229                          " set is_deleted=1, deleted_timestamp=unix_timestamp(now()) "
8230                          " where item_id=" + unsignedIntToString(iid);
8231                        ret = querySimple( "updateItemStatus", sql );
8232                        if ( ret ) return ret;
8233                    }
8234                }
8235                else return ret;
8236            }
8237        }
8238        else {
8239            string sql = "delete from " + dbprefix + "_xoonips_item_status";
8240            ret = querySimple( "updateItemStatus", sql );
8241        }
8242        return ret;
8243    }
8244    
8245    /** item_statusテーブルをクリアしてupdateItemStatusを行う */
8246    result_t refreshItemStatus()
8247    {
8248        string sql = "delete from " + dbprefix + "_xoonips_item_status";
8249        result_t ret = querySimple( "refreshItemStatus", sql );
8250        if ( ret ) return ret;
8251        return updateItemStatus();
8252    }
8253    
8254    /** selective harvesting
8255     * @param from, until  選択範囲
8256     * @param startIID     startIID<=item_idであるようなitem_idのみを得る
8257     * @param limit        返すitem_idの個数の上限
8258     * @param iids         item_idを返す配列  item_idの小さいものから配列に入る
8259     * @param iidsLen      iidsの長さ
8260     */
8261    result_t selectiveHarvesting( time_t from, time_t until, int startIID, int limit, itemid_t **iids, int *iidsLen )
8262    {
8263        result_t ret = RES_ERROR;
8264        if ( limit < 0 ) return RES_ERROR;
8265        
8266        string sql = "select item_id  "
8267          " from "      + dbprefix + "_xoonips_item_status  "
8268          " where " + unsignedIntToString(from) + " <= unix_timestamp(timestamp) "
8269            " and unix_timestamp(timestamp) <= " + unsignedIntToString(until) +
8270            " and item_id >= " + unsignedIntToString(startIID) +
8271            " limit " + unsignedIntToString(limit);
8272        sqlexec_t s( "updateItemStatus", sql, &ret );
8273        //setLastErrorString( "selectiveHarvesting..." );
8274        //setLastErrorString( sql.c_str( ) );
8275        if ( s.getSqlcode() == SQL_SUCCESS ){
8276            SQLUINTEGER iid = 0;
8277            SQLLEN cbIID = 0;
8278            SQLBindCol( s.getHstmt(), 1, SQL_C_ULONG, &iid       , 0, &cbIID       );
8279            
8280            *iids = new itemid_t[limit];
8281            for ( *iidsLen = 0; *iidsLen < limit && SQLFetch( s.getHstmt() ) == SQL_SUCCESS; (*iidsLen)++ ){
8282                (*iids)[*iidsLen] = iid;
8283            }
8284            ret = RES_OK;
8285        }
8286        return ret;
8287    }
8288    
8289    

Legend:
Removed from v.1.103  
changed lines
  Added in v.1.104

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26