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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: lds_files.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:46:03  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: lds_files.cpp,v 1000.1 2004/06/01 19:46:03 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:  LDS Files implementation.
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbifile.hpp>
  41. #include <corelib/ncbitime.hpp>
  42. #include <util/checksum.hpp>
  43. #include <util/format_guess.hpp>
  44. #include <bdb/bdb_cursor.hpp>
  45. #include <objtools/lds/admin/lds_files.hpp>
  46. #include <objtools/lds/lds_set.hpp>
  47. #include <objtools/lds/lds_util.hpp>
  48. #include <objtools/lds/lds_query.hpp>
  49. BEGIN_NCBI_SCOPE
  50. BEGIN_SCOPE(objects)
  51. void CLDS_File::SyncWithDir(const string& path, 
  52.                             CLDS_Set*     deleted, 
  53.                             CLDS_Set*     updated, 
  54.                             bool          recurse_subdirs,
  55.                             bool          compute_check_sum)
  56. {
  57.     CDir dir(path);
  58.     if (!dir.Exists()) {
  59.         string err("Directory is not found or access denied:");
  60.         err.append(path);
  61.         LDS_THROW(eFileNotFound, err);
  62.     }
  63.     CLDS_Query lds_query(m_db);
  64.     CChecksum checksum(CChecksum::eCRC32);
  65.     set<string> files;
  66.     // Scan the directory, compare it against File table
  67.     
  68.     x_SyncWithDir(path, 
  69.                   deleted, 
  70.                   updated,
  71.                   &files,
  72.                   recurse_subdirs,
  73.                   compute_check_sum);
  74.     // Scan the database, find deleted files
  75.     CBDB_FileCursor cur(m_FileDB);
  76.     cur.SetCondition(CBDB_FileCursor::eFirst);
  77.     while (cur.Fetch() == eBDB_Ok) {
  78.         string fname(m_FileDB.file_name);
  79.         set<string>::const_iterator fit = files.find(fname);
  80.         if (fit == files.end()) { // not found
  81.             deleted->insert(m_FileDB.file_id);
  82.             LOG_POST(Info << "LDS: File removed: " << fname);
  83.         }
  84.     } // while
  85.     Delete(*deleted);
  86. }
  87. void CLDS_File::x_SyncWithDir(const string& path, 
  88.                               CLDS_Set*     deleted, 
  89.                               CLDS_Set*     updated,
  90.                               set<string>*  scanned_files,
  91.                               bool          recurse_subdirs,
  92.                               bool          compute_check_sum)
  93. {
  94.     CDir dir(path);
  95.     if (!dir.Exists()) {
  96.         LOG_POST(Info << "LDS: Directory is not found or access denied:" << path);
  97.         return;
  98.     } else {
  99.         LOG_POST(Info << "LDS: scanning " << path);
  100.     }
  101.     CLDS_Query lds_query(m_db);
  102.     CChecksum checksum(CChecksum::eCRC32);
  103.     // Scan the directory, compare it against File table
  104.     // Here I intentionally take only files, skipping sub-directories,
  105.     // Second pass scans for sub-dirs and implements recursion
  106.     {{
  107.     CDir::TEntries  content(dir.GetEntries());
  108.     ITERATE(CDir::TEntries, i, content) {
  109.         if (!(*i)->IsFile()) {
  110.             continue;
  111.         }
  112.         CTime modification;
  113.         string entry = (*i)->GetPath();
  114.         string name = (*i)->GetName();
  115.         string ext = (*i)->GetExt();
  116.         (*i)->GetTime(&modification);
  117.         time_t tm = modification.GetTimeT();
  118.         CFile aFile(entry);
  119.         size_t file_size = aFile.GetLength();
  120.         if (ext == ".db") {
  121.             continue; // Berkeley DB file, no need to index it.
  122.         }
  123.         bool found = lds_query.FindFile(entry);
  124.         scanned_files->insert(entry);
  125.         if (!found) {  // new file arrived
  126.             CFormatGuess fg;
  127.             Uint4 crc = 0;
  128.             if (compute_check_sum) {
  129.                 checksum.Reset();
  130.                 ComputeFileChecksum(entry, checksum);
  131.                 crc = checksum.GetChecksum();
  132.             }
  133.             CFormatGuess::EFormat format = fg.Format(entry);
  134.             FindMaxRecId();
  135.             ++m_MaxRecId;
  136.             m_FileDB.file_id = m_MaxRecId;
  137.             m_FileDB.file_name = entry.c_str();
  138.             m_FileDB.format = format;
  139.             m_FileDB.time_stamp = tm;
  140.             m_FileDB.CRC = crc;
  141.             m_FileDB.file_size = file_size;
  142.             m_FileDB.Insert();
  143.             updated->insert(m_MaxRecId);
  144.             LOG_POST(Info << "New LDS file found: " << entry);
  145.             continue;
  146.         }
  147.         if (tm != m_FileDB.time_stamp || file_size != m_FileDB.file_size) {
  148.             updated->insert(m_FileDB.file_id);
  149.             UpdateEntry(m_FileDB.file_id, 
  150.                         entry, 
  151.                         0, 
  152.                         tm, 
  153.                         file_size, 
  154.                         compute_check_sum);
  155.         } else {
  156.             Uint4 crc = 0;
  157.             if (compute_check_sum) {
  158.                 checksum.Reset();
  159.                 ComputeFileChecksum(entry, checksum);
  160.                 crc = checksum.GetChecksum();
  161.                 if (crc != m_FileDB.CRC) {
  162.                     updated->insert(m_FileDB.file_id);
  163.                     UpdateEntry(m_FileDB.file_id, 
  164.                                 entry, 
  165.                                 crc, 
  166.                                 tm, 
  167.                                 file_size,
  168.                                 compute_check_sum);
  169.                 }
  170.             }
  171.         }
  172.     } // ITERATE
  173.     }}
  174.     if (!recurse_subdirs)
  175.         return;
  176.     // Scan sub-directories
  177.     {{
  178.     CDir::TEntries  content(dir.GetEntries());
  179.     ITERATE(CDir::TEntries, i, content) {
  180.         if ((*i)->IsDir()) {
  181.             string name = (*i)->GetName();
  182.             if (name == "LDS" || name == "." || name == "..") {
  183.                 continue;
  184.             }
  185.             string entry = (*i)->GetPath();
  186.             
  187.             x_SyncWithDir(entry, 
  188.                           deleted, 
  189.                           updated, 
  190.                           scanned_files, 
  191.                           recurse_subdirs,
  192.                           compute_check_sum);
  193.             
  194.         }
  195.     } // ITERATE
  196.     }}
  197. }
  198. void CLDS_File::Delete(const CLDS_Set& record_set)
  199. {
  200.     ITERATE(CLDS_Set, it, record_set) {
  201.         m_FileDB.file_id = *it;
  202.         m_FileDB.Delete();
  203.     }
  204. }
  205. void CLDS_File::UpdateEntry(int    file_id, 
  206.                             const  string& file_name,
  207.                             Uint4  crc,
  208.                             int    time_stamp,
  209.                             size_t file_size,
  210.                             bool   compute_check_sum)
  211. {
  212.     if (!crc && compute_check_sum) {
  213.         crc = ComputeFileCRC32(file_name);
  214.     }
  215.     m_FileDB.file_id = file_id;
  216.     if (m_FileDB.Fetch() != eBDB_Ok) {
  217.         LDS_THROW(eRecordNotFound, "Files record not found");
  218.     }
  219.     // Re-evalute the file format
  220.     CFormatGuess fg;
  221.     CFormatGuess::EFormat format = fg.Format(file_name);
  222.     m_FileDB.format = format;
  223.     m_FileDB.time_stamp = time_stamp;
  224.     m_FileDB.CRC = crc;
  225.     m_FileDB.file_size = file_size;
  226.     EBDB_ErrCode err = m_FileDB.UpdateInsert();
  227.     BDB_CHECK(err, "LDS::File");
  228.     LOG_POST(Info << "LDS: file update: " << file_name);
  229. }
  230. int CLDS_File::FindMaxRecId()
  231. {
  232.     if (m_MaxRecId) {
  233.         return m_MaxRecId;
  234.     }
  235.     LDS_GETMAXID(m_MaxRecId, m_FileDB, file_id);
  236.     return m_MaxRecId;
  237. }
  238. END_SCOPE(objects)
  239. END_NCBI_SCOPE
  240. /*
  241.  * ===========================================================================
  242.  * $Log: lds_files.cpp,v $
  243.  * Revision 1000.1  2004/06/01 19:46:03  gouriano
  244.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  245.  *
  246.  * Revision 1.8  2004/05/21 21:42:55  gorelenk
  247.  * Added PCH ncbi_pch.hpp
  248.  *
  249.  * Revision 1.7  2004/04/20 14:52:25  rsmith
  250.  * Name fl -> aFile since fl is a macro (?!) on Macs.
  251.  *
  252.  * Revision 1.6  2003/10/06 20:16:20  kuznets
  253.  * Added support for sub directories and option to disable CRC32 for files
  254.  *
  255.  * Revision 1.5  2003/08/11 20:02:43  kuznets
  256.  * Reworked CRC32 calculation in order to get better performance
  257.  *
  258.  * Revision 1.4  2003/07/02 12:07:42  dicuccio
  259.  * Fix for implicit conversion/assignment in gcc
  260.  *
  261.  * Revision 1.3  2003/06/16 16:24:43  kuznets
  262.  * Fixed #include paths (lds <-> lds_admin separation)
  263.  *
  264.  * Revision 1.2  2003/06/16 14:55:00  kuznets
  265.  * lds splitted into "lds" and "lds_admin"
  266.  *
  267.  * Revision 1.1  2003/06/03 14:13:25  kuznets
  268.  * Initial revision
  269.  *
  270.  *
  271.  * ===========================================================================
  272.  */