lds_query.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:13k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: lds_query.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:45:50  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: lds_query.cpp,v 1000.2 2004/06/01 19:45:50 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author: Anatoliy Kuznetsov
  35.  *
  36.  * File Description:  Different query functions to LDS database.
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistr.hpp>
  41. #include <bdb/bdb_cursor.hpp>
  42. #include <bdb/bdb_util.hpp>
  43. #include <bdb/bdb_query.hpp>
  44. #include <bdb/bdb_query_parser.hpp>
  45. #include <objects/seqloc/Seq_id.hpp>
  46. #include <objects/general/Object_id.hpp>
  47. #include <objtools/lds/lds_query.hpp>
  48. #include <objtools/lds/lds_set.hpp>
  49. #include <objtools/lds/lds_expt.hpp>
  50. #include <vector>
  51. BEGIN_NCBI_SCOPE
  52. BEGIN_SCOPE(objects)
  53. /// Base class for sequence search functors.
  54. ///
  55. /// @internal
  56. class CLDS_FindSeqIdBase
  57. {
  58. public:
  59.     CLDS_FindSeqIdBase(const vector<string>&  seqids,
  60.                        CLDS_Set*              obj_ids)
  61.     :
  62.       m_SeqIds(seqids),
  63.       m_ResultSet(obj_ids)
  64.     {
  65.         _ASSERT(obj_ids);
  66.     }
  67.     bool MatchSeqId(const CSeq_id& seq_id_db, const string& candidate_str)
  68.     {
  69.         CSeq_id seq_id(candidate_str);
  70.         if (seq_id.Which() == CSeq_id::e_not_set) {
  71.             seq_id.SetLocal().SetStr(candidate_str);
  72.             if (seq_id.Which() == CSeq_id::e_not_set) {
  73.                 return false;
  74.             }
  75.         }
  76.         if (seq_id.Match(seq_id_db)) {
  77.             return true;
  78.         }
  79.         // Sequence does not match, lets try "force it local" strategy
  80.         //
  81.         if (seq_id.Which() != CSeq_id::e_Local) {
  82.             if (candidate_str.find('|') == NPOS) {
  83.                 seq_id.SetLocal().SetStr(candidate_str);
  84.                 if (seq_id.Which() != CSeq_id::e_Local) {
  85.                     return false;
  86.                 }
  87.                 if (seq_id.Match(seq_id_db)) {
  88.                     return true;
  89.                 }
  90.             }
  91.         }
  92.         return false;
  93.     }
  94. private:
  95.     CLDS_FindSeqIdBase(const CLDS_FindSeqIdBase&);
  96.     CLDS_FindSeqIdBase& operator=(const CLDS_FindSeqIdBase&);
  97. protected:
  98.     const vector<string>&   m_SeqIds;    // Search criteria
  99.     CLDS_Set*               m_ResultSet; // Search result 
  100. };
  101. /// Functor used for scanning the Berkeley DB database.
  102. /// This functor is driven by the BDB_iterate_file algorithm,
  103. /// checks every object record to determine if it contains 
  104. /// objects(molecules) satisfying the the given set of ids.
  105. ///
  106. /// @internal
  107. class CLDS_FindSeqIdFunctor : public CLDS_FindSeqIdBase
  108. {
  109. public:
  110.     CLDS_FindSeqIdFunctor(SLDS_TablesCollection& db,
  111.                           const vector<string>&  seqids,
  112.                           CLDS_Set*              obj_ids)
  113.     : CLDS_FindSeqIdBase(seqids, obj_ids),
  114.       m_db(db)
  115.     {
  116.     }
  117.     void operator()(SLDS_ObjectDB& dbf)
  118.     {
  119.         if (dbf.primary_seqid.IsEmpty())
  120.             return;
  121.         int object_id = dbf.object_id;
  122.         int tse_id = dbf.TSE_object_id;
  123.         string seq_id_str(dbf.primary_seqid);
  124.         if (seq_id_str.empty())
  125.             return;
  126.         CSeq_id seq_id_db(seq_id_str);
  127.         if (seq_id_db.Which() == CSeq_id::e_not_set) {
  128.             seq_id_db.SetLocal().SetStr(seq_id_str);
  129.             if (seq_id_db.Which() == CSeq_id::e_not_set) {
  130.                 return;
  131.             }
  132.         }
  133.         // Check the seqids vector against the primary seq id
  134.         //
  135.         ITERATE (vector<string>, it, m_SeqIds) {
  136.             if (MatchSeqId(seq_id_db, *it)) {
  137.                 m_ResultSet->insert(tse_id ? tse_id : object_id);
  138.                 return;
  139.             }
  140.         }
  141.         // Primary seq id gave no hit. Scanning the supplemental list (attributes)
  142.         //
  143. /*
  144.         m_db.object_attr_db.object_attr_id = object_id;
  145.         if (m_db.object_attr_db.Fetch() != eBDB_Ok) {
  146.             return;
  147.         }
  148. */
  149.         if (dbf.seq_ids.IsNull() || 
  150.             dbf.seq_ids.IsEmpty()) {
  151.             return;
  152.         }
  153.         string attr_seq_ids(dbf.seq_ids);
  154.         vector<string> seq_id_arr;
  155.         
  156.         NStr::Tokenize(attr_seq_ids, " ", seq_id_arr, NStr::eMergeDelims);
  157.         ITERATE (vector<string>, it, seq_id_arr) {
  158.             CSeq_id seq_id_db(*it);
  159.             if (seq_id_db.Which() == CSeq_id::e_not_set) {
  160.                 seq_id_db.SetLocal().SetStr(*it);
  161.                 if (seq_id_db.Which() == CSeq_id::e_not_set) {
  162.                     continue;
  163.                 }
  164.             }
  165.             ITERATE (vector<string>, it2, m_SeqIds) {
  166.                 if (MatchSeqId(seq_id_db, *it2)) {
  167.                     m_ResultSet->insert(tse_id ? tse_id : object_id);
  168.                     return;
  169.                 }
  170.             }
  171.         }
  172.     }
  173. private:
  174.     CLDS_FindSeqIdFunctor(const CLDS_FindSeqIdFunctor&);
  175.     CLDS_FindSeqIdFunctor& operator=(const CLDS_FindSeqIdFunctor&);
  176. private:
  177.     SLDS_TablesCollection&  m_db;        // The LDS database
  178. };
  179. ///
  180. /// Functor used for scanning the SLDS_SeqId_List database.
  181. ///
  182. /// @internal
  183. class CLDS_FindSeqIdListFunctor : public CLDS_FindSeqIdBase
  184. {
  185. public:
  186.     CLDS_FindSeqIdListFunctor(const vector<string>&  seqids,
  187.                               CLDS_Set*  obj_ids)
  188.     : CLDS_FindSeqIdBase(seqids, obj_ids)
  189.     {
  190.     }
  191.     void operator()(SLDS_SeqId_List& dbf)
  192.     {
  193.         if (dbf.seq_id.IsEmpty())
  194.             return;
  195.         const char* str_id = dbf.seq_id;
  196.         
  197.         CSeq_id seq_id_db(str_id);
  198.         if (seq_id_db.Which() == CSeq_id::e_not_set) {
  199.             seq_id_db.SetLocal().SetStr((const char*)dbf.seq_id);
  200.             if (seq_id_db.Which() == CSeq_id::e_not_set) {
  201.                 return;
  202.             }
  203.         }
  204.         int object_id = dbf.object_id;
  205.         ITERATE (vector<string>, it, m_SeqIds) {
  206.             if (MatchSeqId(seq_id_db, *it)) {
  207.                 m_ResultSet->insert(object_id);
  208.                 return;
  209.             }
  210.         }
  211.     }
  212. };
  213. inline 
  214. string LDS_TypeMapSearch(const map<string, int>& type_map, int type)
  215. {
  216.     typedef map<string, int> TName2Id;
  217.     ITERATE (TName2Id, it, type_map) {
  218.         if (it->second == type) {
  219.             return it->first;
  220.         }
  221.     }
  222.     return kEmptyStr;
  223. }
  224. /// Query scanner functor for objects
  225. ///
  226. /// @internal
  227. class CLDS_IdTableScanner : public CBDB_FileScanner
  228. {
  229. public:
  230.     CLDS_IdTableScanner(CBDB_File& dbf, CLDS_Set* rec_ids)
  231.     : CBDB_FileScanner(dbf),
  232.       m_ResultSet(*rec_ids)
  233.     {}
  234.     virtual EScanAction OnRecordFound()
  235.     {
  236.         int rowid = BDB_get_rowid(m_File);
  237.         if (rowid) {
  238.             m_ResultSet.insert(rowid);
  239.         }
  240.         return eContinue;
  241.     }
  242. protected:
  243.     CLDS_Set&   m_ResultSet;
  244. };
  245. //////////////////////////////////////////////////////////////////
  246. //
  247. // CLDS_Query
  248. bool CLDS_Query::FindFile(const string& path)
  249. {
  250.     CBDB_FileCursor cur(m_db.file_db);
  251.     cur.SetCondition(CBDB_FileCursor::eFirst);
  252.     while (cur.Fetch() == eBDB_Ok) {
  253.         string fname(m_db.file_db.file_name);
  254.         if (fname == path) {
  255.             return true;
  256.         }
  257.     }
  258.     return false;
  259. }
  260. void CLDS_Query::FindSequences(const vector<string>& seqids, 
  261.                                CLDS_Set* obj_ids)
  262. {
  263.     CLDS_FindSeqIdFunctor search_func(m_db, seqids, obj_ids);
  264.     BDB_iterate_file(m_db.object_db, search_func);
  265. }
  266. void CLDS_Query::FindSeqIdList(const vector<string>& seqids, CLDS_Set* obj_ids)
  267. {
  268.     CLDS_FindSeqIdListFunctor search_func(seqids, obj_ids);
  269.     BDB_iterate_file(m_db.seq_id_list, search_func);
  270. }
  271. void CLDS_Query::FindSequences(const string& query_str, CLDS_Set* obj_ids)
  272. {
  273.     _ASSERT(obj_ids);
  274.     CLDS_IdTableScanner scanner(m_db.object_db, obj_ids);
  275.     CBDB_Query    query;
  276.     try {
  277.         BDB_ParseQuery(query_str.c_str(), &query);
  278.     } catch (CBDB_LibException&) {
  279.         return; // ignore errors
  280.     }
  281.     scanner.Scan(query); 
  282. }
  283. CLDS_Query::SObjectDescr 
  284. CLDS_Query::GetObjectDescr(const map<string, int>& type_map, 
  285.                            int id,
  286.                            bool trace_to_top)
  287. {
  288.     SObjectDescr descr;
  289.     // Check objects
  290.     //
  291.     m_db.object_db.object_id = id;
  292.     if (m_db.object_db.Fetch() == eBDB_Ok) {
  293.         int tse_id = m_db.object_db.TSE_object_id;
  294.         
  295.         if (tse_id && trace_to_top) {
  296.             // If non-top level entry, call recursively redirected to
  297.             // the top level object
  298.             return GetObjectDescr(type_map, tse_id, trace_to_top);
  299.         }
  300.         descr.id = id;
  301.         descr.is_object = true;
  302.         int object_type = m_db.object_db.object_type;
  303.         descr.type_str = LDS_TypeMapSearch(type_map, object_type);
  304.         int file_id = m_db.object_db.file_id;
  305.         m_db.file_db.file_id = file_id;
  306.         if (m_db.file_db.Fetch() != eBDB_Ok) {
  307.             LDS_THROW(eRecordNotFound, "File record not found.");
  308.         }
  309.         descr.format = (CFormatGuess::EFormat)(int)m_db.file_db.format;
  310.         descr.file_name = m_db.file_db.file_name;
  311.         descr.offset = m_db.object_db.file_offset;
  312.         descr.title = m_db.object_db.object_title;
  313. /*
  314.         m_db.object_attr_db.object_attr_id = id;
  315.         if (m_db.object_attr_db.Fetch() == eBDB_Ok) {
  316.             descr.title = m_db.object_attr_db.object_title;
  317.         }
  318. */
  319.         return descr;
  320.     }
  321.     // Check annotations
  322.     //
  323.     m_db.annot_db.annot_id = id;
  324.     if (m_db.annot_db.Fetch() == eBDB_Ok) {
  325.         int top_level_id = m_db.annot_db.top_level_id;
  326.         
  327.         if (top_level_id && trace_to_top) {
  328.             // If non-top level entry, call recursively redirected to
  329.             // the top level object
  330.             return GetObjectDescr(type_map, top_level_id, trace_to_top);
  331.         }
  332.         descr.id = id;
  333.         descr.is_object = false;
  334.         int object_type = m_db.annot_db.annot_type;
  335.         descr.type_str = LDS_TypeMapSearch(type_map, object_type);
  336.         int file_id = m_db.annot_db.file_id;
  337.         m_db.file_db.file_id = file_id;
  338.         if (m_db.file_db.Fetch() != eBDB_Ok) {
  339.             LDS_THROW(eRecordNotFound, "File record not found.");
  340.         }
  341.         descr.format = (CFormatGuess::EFormat)(int)m_db.file_db.format;
  342.         descr.file_name = m_db.file_db.file_name;
  343.         descr.offset = m_db.annot_db.file_offset;
  344.         return descr;
  345.     }
  346.     descr.id = 0; // not found
  347.     return descr;
  348. }
  349. END_SCOPE(objects)
  350. END_NCBI_SCOPE
  351. /*
  352.  * ===========================================================================
  353.  * $Log: lds_query.cpp,v $
  354.  * Revision 1000.2  2004/06/01 19:45:50  gouriano
  355.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  356.  *
  357.  * Revision 1.12  2004/05/21 21:42:55  gorelenk
  358.  * Added PCH ncbi_pch.hpp
  359.  *
  360.  * Revision 1.11  2004/03/11 18:43:41  kuznets
  361.  * + FindSequences
  362.  *
  363.  * Revision 1.10  2004/03/09 17:16:59  kuznets
  364.  * Merge object attributes with objects
  365.  *
  366.  * Revision 1.9  2003/08/06 20:49:13  kuznets
  367.  * SObjectDescr::title handled in CLDS_Query::GetObjectDescr
  368.  *
  369.  * Revision 1.8  2003/07/14 19:48:04  kuznets
  370.  * Minor changes to improve debugging
  371.  *
  372.  * Revision 1.7  2003/07/10 20:09:53  kuznets
  373.  * Implemented GetObjectDescr query. Searches both objects and annotations.
  374.  *
  375.  * Revision 1.6  2003/07/09 19:32:10  kuznets
  376.  * Added query scanning sequence id list.
  377.  *
  378.  * Revision 1.5  2003/06/27 14:36:45  kuznets
  379.  * Fixed compilation problem with GCC
  380.  *
  381.  * Revision 1.4  2003/06/24 18:32:39  kuznets
  382.  * Code clean up. Improved sequence id comparison.
  383.  *
  384.  * Revision 1.3  2003/06/24 15:40:30  kuznets
  385.  * Working on sequence id scan search. Improved recognition of local sequences.
  386.  *
  387.  * Revision 1.2  2003/06/20 19:56:41  kuznets
  388.  * Implemented new function "FindSequences"
  389.  *
  390.  * Revision 1.1  2003/06/16 14:55:00  kuznets
  391.  * lds splitted into "lds" and "lds_admin"
  392.  *
  393.  *
  394.  * ===========================================================================
  395.  */