releasing package apt version 1.0.9.1
[ntk/apt.git] / ftparchive / cachedb.cc
index f63aa88..0901492 100644 (file)
 #include <apti18n.h>
                                                                        /*}}}*/
 
+CacheDB::CacheDB(std::string const &DB) 
+   : Dbp(0), Fd(NULL), DebFile(0)
+{
+   TmpKey[0]='\0';
+   ReadyDB(DB);
+};
+
+CacheDB::~CacheDB()
+{
+   ReadyDB();
+   delete DebFile;
+};
+
 // CacheDB::ReadyDB - Ready the DB2                                    /*{{{*/
 // ---------------------------------------------------------------------
 /* This opens the DB2 file for caching package information */
@@ -86,7 +99,7 @@ bool CacheDB::ReadyDB(std::string const &DB)
           return _error->Error(_("Unable to open DB file %s: %s"),DB.c_str(), db_strerror(err));
       }
    }
-   
+
    DBFile = DB;
    DBLoaded = true;
    return true;
@@ -97,13 +110,8 @@ bool CacheDB::ReadyDB(std::string const &DB)
 /* */
 bool CacheDB::OpenFile()
 {
-   // its open already
-   if(Fd && Fd->Name() == this->FileName)
-      return true;
-
-   // a different file is open, close it first
-   if(Fd && Fd->Name() != this->FileName)
-      CloseFile();
+   // always close existing file first
+   CloseFile();
 
    // open a new file
    Fd = new FileFd(FileName,FileFd::ReadOnly);
@@ -128,13 +136,8 @@ void CacheDB::CloseFile()
 // CacheDB::OpenDebFile - Open a debfile                               /*{{{*/
 bool CacheDB::OpenDebFile()
 {
-   // debfile is already open
-   if(DebFile && &DebFile->GetFile() == Fd)
-      return true;
-
-   // a different debfile is open, close it first
-   if(DebFile && &DebFile->GetFile() != Fd)
-      CloseDebFile();
+   // always close existing file first
+   CloseDebFile();
 
    // first open the fd, then pass it to the debDebFile
    if(OpenFile() == false)
@@ -182,6 +185,45 @@ bool CacheDB::GetFileStat(bool const &doStat)
    CurStat.mtime = htonl(St.st_mtime);
    CurStat.Flags |= FlSize;
    
+   return true;
+}
+                                                                       /*}}}*/
+// CacheDB::GetCurStatCompatOldFormat                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* Read the old (32bit FileSize) StateStore format from disk */
+bool CacheDB::GetCurStatCompatOldFormat()
+{
+   InitQueryStats();
+   Data.data = &CurStatOldFormat;
+   Data.flags = DB_DBT_USERMEM;
+   Data.ulen = sizeof(CurStatOldFormat);
+   if (Get() == false)
+   {
+      CurStat.Flags = 0;
+   } else {
+      CurStat.Flags = CurStatOldFormat.Flags;
+      CurStat.mtime = CurStatOldFormat.mtime;
+      CurStat.FileSize = CurStatOldFormat.FileSize;
+      memcpy(CurStat.MD5, CurStatOldFormat.MD5, sizeof(CurStat.MD5));
+      memcpy(CurStat.SHA1, CurStatOldFormat.SHA1, sizeof(CurStat.SHA1));
+      memcpy(CurStat.SHA256, CurStatOldFormat.SHA256, sizeof(CurStat.SHA256));
+   }
+   return true;
+}
+                                                                       /*}}}*/
+// CacheDB::GetCurStatCompatOldFormat                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* Read the new (64bit FileSize) StateStore format from disk */
+bool CacheDB::GetCurStatCompatNewFormat()
+{
+   InitQueryStats();
+   Data.data = &CurStat;
+   Data.flags = DB_DBT_USERMEM;
+   Data.ulen = sizeof(CurStat);
+   if (Get() == false)
+   {
+      CurStat.Flags = 0;
+   }
    return true;
 }
                                                                        /*}}}*/
@@ -195,19 +237,29 @@ bool CacheDB::GetCurStat()
    
    if (DBLoaded)
    {
-      /* First see if there is anything about it
-         in the database */
-      
-      /* Get the flags (and mtime) */
-      InitQuery("st");
-      // Ensure alignment of the returned structure
+      // do a first query to just get the size of the data on disk
+      InitQueryStats();
       Data.data = &CurStat;
-      Data.ulen = sizeof(CurStat);
       Data.flags = DB_DBT_USERMEM;
-      if (Get() == false)
+      Data.ulen = 0;
+      Get();
+
+      if (Data.size == 0)
+      {
+         // nothing needs to be done, we just have not data for this deb
+      }
+      // check if the record is written in the old format (32bit filesize)
+      else if(Data.size == sizeof(CurStatOldFormat))
+      {
+         GetCurStatCompatOldFormat();
+      }
+      else if(Data.size == sizeof(CurStat))
       {
-        CurStat.Flags = 0;
-      }      
+         GetCurStatCompatNewFormat();
+      } else {
+         return _error->Error("Cache record size mismatch (%ul)", Data.size);
+      }
+
       CurStat.Flags = ntohl(CurStat.Flags);
       CurStat.FileSize = ntohl(CurStat.FileSize);
    }      
@@ -262,7 +314,7 @@ bool CacheDB::LoadSource()
    if ((CurStat.Flags & FlSource) == FlSource)
    {
       // Lookup the control information
-      InitQuery("cs");
+      InitQuerySource();
       if (Get() == true && Dsc.TakeDsc(Data.data, Data.size) == true)
       {
            return true;
@@ -280,7 +332,7 @@ bool CacheDB::LoadSource()
       return _error->Error(_("Failed to read .dsc"));
    
    // Write back the control information
-   InitQuery("cs");
+   InitQuerySource();
    if (Put(Dsc.Data, Dsc.Length) == true)
       CurStat.Flags |= FlSource;
 
@@ -296,7 +348,7 @@ bool CacheDB::LoadControl()
    if ((CurStat.Flags & FlControl) == FlControl)
    {
       // Lookup the control information
-      InitQuery("cl");
+      InitQueryControl();
       if (Get() == true && Control.TakeControl(Data.data,Data.size) == true)
            return true;
       CurStat.Flags &= ~FlControl;
@@ -313,7 +365,7 @@ bool CacheDB::LoadControl()
       return _error->Error(_("Archive has no control record"));
    
    // Write back the control information
-   InitQuery("cl");
+   InitQueryControl();
    if (Put(Control.Control,Control.Length) == true)
       CurStat.Flags |= FlControl;
    return true;
@@ -331,7 +383,7 @@ bool CacheDB::LoadContents(bool const &GenOnly)
         return true;
       
       // Lookup the contents information
-      InitQuery("cn");
+      InitQueryContent();
       if (Get() == true)
       {
         if (Contents.TakeContents(Data.data,Data.size) == true)
@@ -349,7 +401,7 @@ bool CacheDB::LoadContents(bool const &GenOnly)
       return false;        
    
    // Write back the control information
-   InitQuery("cn");
+   InitQueryContent();
    if (Put(Contents.Data,Contents.CurSize) == true)
       CurStat.Flags |= FlContents;
    return true;
@@ -515,11 +567,11 @@ bool CacheDB::Finish()
    if (CurStat.Flags == OldStat.Flags &&
        CurStat.mtime == OldStat.mtime)
       return true;
-   
+
    // Write the stat information
    CurStat.Flags = htonl(CurStat.Flags);
    CurStat.FileSize = htonl(CurStat.FileSize);
-   InitQuery("st");
+   InitQueryStats();
    Put(&CurStat,sizeof(CurStat));
    CurStat.Flags = ntohl(CurStat.Flags);
    CurStat.FileSize = ntohl(CurStat.FileSize);