bool 
   PersistentGreyList::AddObject(shared_ptr<GreyListTriplet> pTriplet)
   //---------------------------------------------------------------------------()
   // DESCRIPTION:
   // Adds a new greylist triple into the database.
   //---------------------------------------------------------------------------()
   {
      String sSenderAddress = pTriplet->GetSenderAddress().Left(200);
      String sRecipientAddress = pTriplet->GetRecipientAddress().Left(200);
   
      // Update the triplet
      SQLStatement oStatement;

      IPAddressSQLHelper helper;

      oStatement.SetTable("hm_greylisting_triplets");
      oStatement.AddColumn("glcreatetime", pTriplet->GetCreateTime());
      oStatement.AddColumn("glblockendtime", pTriplet->GetBlockEndTime());
      oStatement.AddColumn("gldeletetime", pTriplet->GetDeleteTime());
      
      helper.AppendStatement(oStatement, pTriplet->GetIPAddress(), "glipaddress1", "glipaddress2");

      oStatement.AddColumn("glsenderaddress", sSenderAddress);
      oStatement.AddColumn("glrecipientaddress", sRecipientAddress);
      oStatement.AddColumn("glpassedcount", "0");
      oStatement.AddColumn("glblockedcount", "0");

      oStatement.SetStatementType(SQLStatement::STInsert);
      oStatement.SetIdentityColumn("glid");

      bool bResult = Application::Instance()->GetDBManager()->Execute(oStatement, 0, DALConnection::DALErrorInSQL);

      return bResult;
   }
   bool
   PersistentSecurityRange::SaveObject(shared_ptr<SecurityRange> pSR, String &result)
   {
      if (!Validate(pSR, result))
         return false;

      DateTime rangeExpiresTime = pSR->GetExpiresTime();
      if (rangeExpiresTime.GetStatus() != DateTime::valid)
         rangeExpiresTime.SetDateTime(2001,01,01,0,0,0);

      String name = pSR->GetName();
      if (name.GetLength() > 100)
         name = name.Mid(0, 100);

      IPAddressSQLHelper helper;

      SQLStatement oStatement;
      oStatement.SetTable("hm_securityranges");

      oStatement.AddColumn("rangename", name);
      oStatement.AddColumn("rangepriorityid", pSR->GetPriority());

      helper.AppendStatement(oStatement, pSR->GetLowerIP(), "rangelowerip1", "rangelowerip2");
      helper.AppendStatement(oStatement, pSR->GetUpperIP(), "rangeupperip1", "rangeupperip2");

      oStatement.AddColumn("rangeoptions", pSR->GetOptions());
      oStatement.AddColumn("rangeexpires", pSR->GetExpires());
      oStatement.AddColumn("rangeexpirestime", Time::GetTimeStampFromDateTime(rangeExpiresTime));

      if (pSR->GetID() == 0)
      {
         oStatement.SetStatementType(SQLStatement::STInsert);
         oStatement.SetIdentityColumn("rangeid");
      }
      else
      {
         oStatement.SetStatementType(SQLStatement::STUpdate);

         String sWhere;
         sWhere.Format(_T("rangeid = %I64d"), pSR->GetID());
         oStatement.SetWhereClause(sWhere);
      }


      bool bNewObject = pSR->GetID() == 0;

      // Save and fetch ID
      __int64 iDBID = 0;
      bool bRetVal = Application::Instance()->GetDBManager()->Execute(oStatement, bNewObject ? &iDBID : 0);
      if (bRetVal && bNewObject)
         pSR->SetID((int) iDBID);

      if (!bRetVal)
         result = "Failed to save. Please see the hMailServer error log for details.";

      return bRetVal;
   }
   bool 
   PersistentTCPIPPort::SaveObject(shared_ptr<TCPIPPort> pObject)
   {
      SQLStatement oStatement;
      oStatement.SetTable("hm_tcpipports");
      
      if (pObject->GetID() == 0)
      {
         oStatement.SetStatementType(SQLStatement::STInsert);
         oStatement.SetIdentityColumn("portid");
      }
      else
      {
         oStatement.SetStatementType(SQLStatement::STUpdate);
         String sWhere;
         sWhere.Format(_T("portid = %I64d"), pObject->GetID());
         oStatement.SetWhereClause(sWhere);
         
      }

      __int64 iAddress = 0;

      IPAddressSQLHelper helper;
      

      oStatement.AddColumn("portprotocol", pObject->GetProtocol());
      oStatement.AddColumn("portnumber", pObject->GetPortNumber());
      oStatement.AddColumnInt64("portsslcertificateid", pObject->GetSSLCertificateID());
      helper.AppendStatement(oStatement, pObject->GetAddress(), "portaddress1", "portaddress2");
      //JDR: Added to store the the UseSTARTLS setting.
      if (pObject->GetUseSSL() == true)
      {
         oStatement.AddColumn("portusessl", 1);
      }
      else if ( pObject->GetUseSTARTTLS() == true)
      {
         oStatement.AddColumn("portusessl", 2);
      }
      else
      {
         oStatement.AddColumn("portusessl", 0);
      }
     //JDR: end edit

      bool bNewObject = pObject->GetID() == 0;

      // Save and fetch ID
      __int64 iDBID = 0;
      bool bRetVal = Application::Instance()->GetDBManager()->Execute(oStatement, bNewObject ? &iDBID : 0);
      if (bRetVal && bNewObject)
         pObject->SetID((int) iDBID);


      return true;
   }
   bool 
   PersistentTCPIPPort::SaveObject(std::shared_ptr<TCPIPPort> pObject, String &errorMessage, PersistenceMode mode)
   {
      if (mode == PersistenceModeNormal)
      {
         if (pObject->GetSSLCertificateID() == 0 &&
             (pObject->GetConnectionSecurity() == CSSSL || pObject->GetConnectionSecurity() == CSSTARTTLSOptional || pObject->GetConnectionSecurity() == CSSTARTTLSRequired))
         {
            errorMessage = "Certificate must be specified.";
            return false;
         }
      }

      SQLStatement oStatement;
      oStatement.SetTable("hm_tcpipports");

      if (pObject->GetID() == 0)
      {
         oStatement.SetStatementType(SQLStatement::STInsert);
         oStatement.SetIdentityColumn("portid");
      }
      else
      {
         oStatement.SetStatementType(SQLStatement::STUpdate);
         String sWhere;
         sWhere.Format(_T("portid = %I64d"), pObject->GetID());
         oStatement.SetWhereClause(sWhere);
         
      }

      __int64 iAddress = 0;

      IPAddressSQLHelper helper;
      

      oStatement.AddColumn("portprotocol", pObject->GetProtocol());
      oStatement.AddColumn("portnumber", pObject->GetPortNumber());
      oStatement.AddColumnInt64("portsslcertificateid", pObject->GetSSLCertificateID());
      helper.AppendStatement(oStatement, pObject->GetAddress(), "portaddress1", "portaddress2");
      oStatement.AddColumn("portconnectionsecurity", pObject->GetConnectionSecurity());
      
      bool bNewObject = pObject->GetID() == 0;

      // Save and fetch ID
      __int64 iDBID = 0;
      bool bRetVal = Application::Instance()->GetDBManager()->Execute(oStatement, bNewObject ? &iDBID : 0);
      if (bRetVal && bNewObject)
         pObject->SetID((int) iDBID);


      return true;
   }
   bool 
   PersistentLogonFailure::AddFailure(const IPAddress &ipaddress)
   {
      SQLStatement statement;

      IPAddressSQLHelper helper;
      helper.AppendStatement(statement, ipaddress, "ipaddress1", "ipaddress2");

      statement.AddColumnCommand("failuretime", SQLStatement::GetCurrentTimestamp());
      statement.SetStatementType(SQLStatement::STInsert);
      statement.SetTable("hm_logon_failures");

      return Application::Instance()->GetDBManager()->Execute(statement);
   }
   bool
   PersistentIncomingRelay::SaveObject(boost::shared_ptr<IncomingRelay> pSR)
   {
      SQLStatement oStatement;
      oStatement.SetTable("hm_incoming_relays");

      oStatement.AddColumn("relayname", pSR->GetName());

      IPAddressSQLHelper helper;

      helper.AppendStatement(oStatement, pSR->GetLowerIP(), "relaylowerip1", "relaylowerip2");
      helper.AppendStatement(oStatement, pSR->GetUpperIP(), "relayupperip1", "relayupperip2");

      if (pSR->GetID() == 0)
      {
         oStatement.SetStatementType(SQLStatement::STInsert);
         oStatement.SetIdentityColumn("relayid");
      }
      else
      {
         oStatement.SetStatementType(SQLStatement::STUpdate);

         String sWhere;
         sWhere.Format(_T("relayid = %d"), (unsigned int) pSR->GetID());
         oStatement.SetWhereClause(sWhere);
      }

      bool bNewObject = pSR->GetID() == 0;

      // Save and fetch ID
      __int64 iDBID = 0;
      bool bRetVal = Application::Instance()->GetDBManager()->Execute(oStatement, bNewObject ? &iDBID : 0);
      if (bRetVal && bNewObject)
         pSR->SetID((int) iDBID);
      return bRetVal;
   }