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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: demo3.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:37:48  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: demo3.cpp,v 1000.1 2004/06/01 18:37:48 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: Demo3 application for NCBI Berkeley DB library (BDB).
  37.  *                   Shows how to create additional BTree index file to 
  38.  *                   improve search performance.
  39.  *
  40.  */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbiapp.hpp>
  43. #include <corelib/ncbiargs.hpp>
  44. #include <bdb/bdb_cursor.hpp>
  45. #include <assert.h>
  46. #include <list>
  47. USING_NCBI_SCOPE;
  48. //////////////////////////////////////////////////////////////////
  49. // 
  50. // Structure implements database table record in "phone book" 
  51. // database table.
  52. //
  53. //
  54. struct SPhoneBookDB : public CBDB_File
  55. {
  56.     CBDB_FieldInt4      person_id;
  57.     CBDB_FieldString    first_name;
  58.     CBDB_FieldString    last_name;
  59.     CBDB_FieldInt4      zip_code;
  60.     CBDB_FieldString    phone;
  61.     // Constructor binds field variables.
  62.     SPhoneBookDB()
  63.     {
  64.         // Bind int primary key. Cannot be NULL.
  65.         BindKey("PersonId", &person_id);
  66.         //  Bind non-PK data fields
  67.         BindData("FirstName", &first_name, 64, eNotNullable);
  68.         BindData("LastName",  &last_name, 64, eNotNullable);
  69.         BindData("Zip",       &zip_code);  // NULLable by default
  70.         BindData("Phone",     &phone, 32); // NULLable by default
  71.     }
  72. };
  73. const char* s_PhoneBookDBFileName = "phone.db";
  74. //////////////////////////////////////////////////////////////////
  75. // 
  76. // Structure implements index record for "phone book" 
  77. // database table. BTree index stores Zip code and correspondent 
  78. // primary key in the main table.
  79. //
  80. struct SPhoneBookZipIDX : public CBDB_File
  81. {
  82.     CBDB_FieldInt4      zip_code;
  83.     CBDB_FieldInt4      person_id;
  84.     SPhoneBookZipIDX()
  85.     {
  86.         BindKey("Zip", &zip_code);
  87.         BindKey("PersonId", &person_id);
  88.     }
  89. };
  90. const char* s_PhoneBookZipIDXFileName = "phone_zip.idx";
  91. void LoadPhoneBook()
  92. {
  93.     SPhoneBookDB  dbf;
  94.     dbf.Open(s_PhoneBookDBFileName, CBDB_File::eCreate);
  95.     
  96.     dbf.person_id = 1;
  97.     dbf.first_name = "John";
  98.     dbf.last_name = "Doe";
  99.     dbf.zip_code = 10785;
  100.     dbf.phone = "+1(240)123456";  
  101.     
  102.     EBDB_ErrCode ret = dbf.Insert();
  103.     // Check Insert result, it can be 'eBDB_KeyDup'
  104.     // if primary key already exists
  105.     if (ret != eBDB_Ok) {
  106.         cout << "Insert failed!" << endl;
  107.         exit(1);
  108.     }
  109.     
  110.     dbf.person_id = 2;
  111.     dbf.first_name = "Antony";
  112.     dbf.last_name = "Smith";
  113.     dbf.zip_code = 10785;
  114.     dbf.phone = "(240)234567";
  115.     ret = dbf.Insert();
  116.     if (ret != eBDB_Ok) {
  117.         cout << "Insert failed!" << endl;
  118.         exit(1);
  119.     }
  120.     dbf.person_id = 3;
  121.     dbf.first_name = "John";
  122.     dbf.last_name = "Public";
  123.     dbf.zip_code = 40000;
  124.       
  125.     ret = dbf.Insert();
  126.     if (ret != eBDB_Ok) {
  127.         cout << "Insert failed!" << endl;
  128.         exit(1);
  129.     }
  130. }
  131. //
  132. // Function builds Zip code index.
  133. // Indexing procedure creates a cursor on the main data file, fetches all data
  134. // and adds corresponding entries to the index. From the technical standpoint
  135. // both data and index are both BTree Berkeley DB files.
  136. //
  137. void BuildZipIndex(SPhoneBookDB& dbf)
  138. {
  139.     SPhoneBookZipIDX idx;
  140.     idx.Open(s_PhoneBookZipIDXFileName, CBDB_File::eCreate);
  141.     CBDB_FileCursor cur(dbf);
  142.     cur.SetCondition(CBDB_FileCursor::eFirst);
  143.     while (cur.Fetch() == eBDB_Ok) {
  144.         if (dbf.zip_code.IsNull())  // NULL values are dropped
  145.             continue;
  146.         
  147.         idx.zip_code = dbf.zip_code;
  148.         idx.person_id = dbf.person_id;
  149.         EBDB_ErrCode ret = idx.Insert();
  150.         if (ret != eBDB_Ok) {
  151.             cout << "Insert failed!" << endl;
  152.             exit(1);
  153.         }
  154.     }
  155. }
  156. // Function prints the database record.
  157. void PrintRecord(const SPhoneBookDB& rec)
  158. {
  159.     cout << rec.person_id.GetName() << ": " << rec.person_id.Get() << endl;
  160.     cout << rec.first_name.GetName()<< ": ";
  161.     if (rec.first_name.IsNull()) {
  162.         cout << "NULL" << endl;
  163.     } else {
  164.         cout << (const char*) rec.first_name << endl;
  165.     }
  166.     cout << rec.last_name.GetName()<< ": ";
  167.     if (rec.last_name.IsNull()) {
  168.         cout << "NULL" << endl;
  169.     } else {
  170.         cout << (const char*) rec.last_name << endl;
  171.     }
  172.     cout << rec.zip_code.GetName()<< ": ";
  173.     if (rec.zip_code.IsNull()) {
  174.         cout << "NULL" << endl;
  175.     } else {
  176.         cout << (Int4) rec.zip_code << endl;
  177.     }
  178.     cout << rec.phone.GetName()<< ": ";
  179.     if (rec.phone.IsNull()) {
  180.         cout << "NULL" << endl;
  181.     } else {
  182.         cout << (const char*) rec.phone << endl;
  183.     }
  184. }
  185. //
  186. // Search function uses Zip code index for fast data retrieval.
  187. // Actual data seach is two phase process.
  188. // First we seach the index values and collect the parent table primary key.
  189. // Then we go and get the primary data table records.
  190. //
  191. void SearchPhoneBook(SPhoneBookDB& dbf, SPhoneBookZipIDX& idx, int zip_code)
  192. {
  193.     list<int>  person_id;
  194.     // Index search. Here we store seach values in the list.
  195.     {{
  196.         CBDB_FileCursor cur(idx);
  197.         cur.SetCondition(CBDB_FileCursor::eEQ);
  198.         cur.From << zip_code;
  199.         while (cur.Fetch() == eBDB_Ok) {
  200.             person_id.push_back(idx.person_id.Get());
  201.         }
  202.     }}
  203.     if (person_id.empty()) {
  204.         cout << "No records found." << endl;
  205.         return;
  206.     }
  207.     // Data retrieval using index seach values.
  208.     for (list<int>::const_iterator it = person_id.begin();
  209.          it != person_id.end(); ++it) {
  210.         dbf.person_id = *it;
  211.         EBDB_ErrCode ret = dbf.Fetch();
  212.         assert(ret == eBDB_Ok);
  213.         cout << "====================================" << endl;
  214.         PrintRecord(dbf);
  215.     }
  216. }
  217. ////////////////////////////////
  218. // Demo3 application
  219. //
  220. class CBDB_PhoneBookDemo3 : public CNcbiApplication
  221. {
  222. public:
  223.     void Init(void);
  224.     int Run(void);
  225. };
  226. void CBDB_PhoneBookDemo3::Init(void)
  227. {
  228.     SetDiagPostLevel(eDiag_Warning);
  229.     SetDiagPostFlag(eDPF_File);
  230.     SetDiagPostFlag(eDPF_Line);
  231.     auto_ptr<CArgDescriptions> d(new CArgDescriptions);
  232.     d->SetUsageContext("bdb demo3",
  233.                        "Demo3 application for BDB library");
  234.     SetupArgDescriptions(d.release());
  235. }
  236. int CBDB_PhoneBookDemo3::Run(void)
  237. {
  238.     try
  239.     {
  240.         LoadPhoneBook();
  241.         SPhoneBookDB dbf;
  242.         dbf.Open(s_PhoneBookDBFileName, CBDB_File::eReadOnly);
  243.         BuildZipIndex(dbf);
  244.         SPhoneBookZipIDX idx;
  245.         idx.Open(s_PhoneBookZipIDXFileName, CBDB_File::eReadOnly);
  246.         SearchPhoneBook(dbf, idx, 10785);
  247.     }
  248.     catch (CBDB_ErrnoException& ex)
  249.     {
  250.         cout << "Error! DBD errno exception:" << ex.what();
  251.         return 1;
  252.     }
  253.     catch (CBDB_LibException& ex)
  254.     {
  255.         cout << "Error! DBD library exception:" << ex.what();
  256.         return 1;
  257.     }
  258.     return 0;
  259. }
  260. int main(int argc, const char* argv[])
  261. {
  262.     return CBDB_PhoneBookDemo3().AppMain(argc, argv, 0, eDS_Default, 0);
  263. }
  264. /*
  265.  * ===========================================================================
  266.  * $Log: demo3.cpp,v $
  267.  * Revision 1000.1  2004/06/01 18:37:48  gouriano
  268.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  269.  *
  270.  * Revision 1.3  2004/05/17 20:55:18  gorelenk
  271.  * Added include of PCH ncbi_pch.hpp
  272.  *
  273.  * Revision 1.2  2003/05/02 16:23:14  kuznets
  274.  * Cosmetic fixes
  275.  *
  276.  * Revision 1.1  2003/05/01 13:44:57  kuznets
  277.  * Initial revision
  278.  *
  279.  * ===========================================================================
  280.  */