示例#1
0
bool wxOdbcDatabase::Open( )
{
   ResetErrorCodes();

   if ( !m_strDSN.IsEmpty() )
   {
#ifdef wxUSE_UNICODE
     wxCharBuffer dsnCharBuffer = ConvertToUnicodeStream(m_strDSN);
     wxCharBuffer userCharBuffer = ConvertToUnicodeStream(m_strUser);
     wxCharBuffer passwordCharBuffer = ConvertToUnicodeStream(m_strPassword);
#else
     void* dsnCharBuffer = (void*)m_strDSN.c_str();
     void* userCharBuffer = (void*)m_strUser.c_str();
     void* passwordCharBuffer = (void*)m_strPassword.c_str();
#endif

     SQLRETURN nRet;
     nRet = m_pInterface->GetSQLConnect()((SQLHDBC)m_sqlHDBC, (SQLTCHAR FAR*)(const char*)dsnCharBuffer,
                SQL_NTS, (SQLTCHAR FAR*)(const char*)userCharBuffer, SQL_NTS,
                (SQLTCHAR FAR*)(const char*)passwordCharBuffer, SQL_NTS);
     if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
     {
       InterpretErrorCodes( nRet );
       ThrowDatabaseException();
     }
   }
   else if ( !m_strConnection.IsEmpty() )
   {
     SQLTCHAR buff[8192];
     SQLSMALLINT iLen;

     memset(buff, 0, 8192*sizeof(SQLTCHAR));
     
     wxCharBuffer connectionCharBuffer = ConvertToUnicodeStream(m_strConnection); //AML
     //AMLvoid* connectionCharBuffer = (void*)m_strConnection.c_str();
#if wxUSE_GUI
     SQLRETURN nRet = m_pInterface->GetSQLDriverConnect()((SQLHDBC)m_sqlHDBC, m_pParent ? (SQLHWND)m_pParent->GetHandle() : NULL, (SQLTCHAR*)(const char*)connectionCharBuffer,
         (SQLSMALLINT)m_strConnection.Length(), (SQLTCHAR*)buff, 8192, &iLen, m_bPrompt ? SQL_DRIVER_PROMPT : SQL_DRIVER_NOPROMPT);
#else
     SQLRETURN nRet = m_pInterface->GetSQLDriverConnect()((SQLHDBC)m_sqlHDBC, NULL, (SQLTCHAR*)(const char*)connectionCharBuffer,
         (SQLSMALLINT)m_strConnection.Length(), (SQLTCHAR*)buff, 8192, &iLen, SQL_DRIVER_NOPROMPT);
#endif

     if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
     {
       InterpretErrorCodes( nRet );
       ThrowDatabaseException();
     }
   }
   else
   {
     return false;
   }

   m_bIsConnected = true;    
        
   return true;
}
示例#2
0
wxArrayString wxOdbcDatabase::GetPKColumns(const wxString& table)
{
  wxArrayString returnArray;
  // Use SQLColumns
  SQLHSTMT pStatement = allocStmth();
  wxCharBuffer tableBuffer = ConvertToUnicodeStream(table);
  int tableBufferLength = GetEncodedStreamLength(table);
  SQLRETURN nRet = m_pInterface->GetSQLPKColumns()(pStatement,
      NULL, 0,
      NULL, 0,
      (SQLTCHAR*)(const char*)tableBuffer, tableBufferLength,
      NULL, 0);

  if (nRet != SQL_SUCCESS)
  {
    InterpretErrorCodes( nRet );
    m_pInterface->GetSQLFreeStmt()(pStatement, SQL_CLOSE);
    ThrowDatabaseException();
    return returnArray;
  }

  nRet = m_pInterface->GetSQLFetch()(pStatement);
  while (nRet == SQL_SUCCESS || nRet == SQL_SUCCESS_WITH_INFO)
  {
    SQLPOINTER buff[8192];

    memset(buff, 0, 8192*sizeof(SQLTCHAR));

    SQLINTEGER  col_size         = 8192;
    SQLLEN  real_size        = 0;
    int nField = 4;

    SQLRETURN nGetDataReturn = m_pInterface->GetSQLGetData()( pStatement, nField, SQL_C_CHAR, buff,
      col_size, &real_size );
    if ( nGetDataReturn != SQL_SUCCESS && nGetDataReturn != SQL_SUCCESS_WITH_INFO )
    {
      InterpretErrorCodes(nRet);
      m_pInterface->GetSQLFreeStmt()(pStatement, SQL_CLOSE);
      ThrowDatabaseException();
      return returnArray;
    }
    wxString strColumn = ConvertFromUnicodeStream((const char*)buff);
    returnArray.Add(strColumn);
    nRet = m_pInterface->GetSQLFetch()(pStatement);
  }

  m_pInterface->GetSQLFreeStmt()(pStatement, SQL_CLOSE);

  return returnArray;
}
示例#3
0
// ctor()
wxOdbcDatabase::wxOdbcDatabase(): wxDatabase()
{
   m_bIsConnected = false;
   ResetErrorCodes();

   m_pInterface = new wxOdbcInterface();
   if (!m_pInterface->Init())
   {
     SetErrorCode(wxDATABASE_ERROR_LOADING_LIBRARY);
     SetErrorMessage(wxT("Error loading ODBC library"));
     ThrowDatabaseException();
     return;
   }

   SQLHENV sqlEnvHandle = (SQLHENV)m_sqlEnvHandle;
   SQLRETURN nRet = m_pInterface->GetSQLAllocHandle()(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlEnvHandle);
   m_sqlEnvHandle = sqlEnvHandle;
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }

   nRet = m_pInterface->GetSQLSetEnvAttr()((SQLHENV)m_sqlEnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }

   SQLHDBC sqlHDBC = (SQLHDBC)m_sqlHDBC;
   nRet = m_pInterface->GetSQLAllocHandle()(SQL_HANDLE_DBC, (SQLHENV)m_sqlEnvHandle, &sqlHDBC);
   m_sqlHDBC = sqlHDBC;
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }

   m_strDSN = wxEmptyString;
   m_strUser = wxEmptyString;
   m_strPassword = wxEmptyString;
   m_strConnection = wxEmptyString;
#if wxUSE_GUI
   m_bPrompt = false;
   m_pParent = NULL;
#endif
}
// close database  
bool FirebirdDatabaseLayer::Close()
{
  CloseResultSets();
  CloseStatements();

  if (m_pDatabase)
  {
    if (m_pTransaction)
    {
      isc_tr_handle pTransaction = (isc_tr_handle)m_pTransaction;
      m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pTransaction);
      m_pTransaction = NULL;
    }

    isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
    int nReturn = m_pInterface->GetIscDetachDatabase()(*(ISC_STATUS_ARRAY*)m_pStatus, &pDatabase);
    m_pDatabase = NULL;
    if (nReturn != 0)
    {
      InterpretErrorCodes();
      ThrowDatabaseException();
      return false;
    }
  }

  return true;
}
示例#5
0
bool wxOdbcResultSet::Next()
{
    m_RetrievedValues.clear();
    m_NullValues.clear();

    m_BlobMap.clear();

    if (m_pOdbcStatement == NULL)
        m_pOdbcStatement = m_pStatement->GetLastStatement();

    long nReturn = m_pInterface->GetSQLFetch()( m_pOdbcStatement );
     
    if ( nReturn != SQL_SUCCESS && nReturn != SQL_SUCCESS_WITH_INFO )
    {
        if ( nReturn == SQL_NO_DATA )
            return false;

        InterpretErrorCodes(nReturn, m_pOdbcStatement);
        ThrowDatabaseException();
        return false;
    }

    m_fieldValues.Clear();
    for ( int i=0; i<(int)m_FieldLookupMap.size(); i++ )
        m_fieldValues.push_back( wxVariant() );
      
    return true;
}
示例#6
0
bool wxOdbcDatabase::ViewExists(const wxString& view)
{
  bool bReturn = false;
  // Use SQLTables
  SQLHSTMT pStatement = allocStmth();
  wxCharBuffer viewBuffer = ConvertToUnicodeStream(view);
  wxString tableType = _("VIEW");
  wxCharBuffer tableTypeBuffer = ConvertToUnicodeStream(tableType);
  int tableTypeBufferLength = GetEncodedStreamLength(tableType);
  SQLRETURN nRet = m_pInterface->GetSQLTables()(pStatement,
      NULL, 0,
      NULL, 0,
      (SQLTCHAR*)(const char*)viewBuffer, SQL_NTS,
      (SQLTCHAR*)(const char*)tableTypeBuffer, tableTypeBufferLength);

  if (nRet != SQL_SUCCESS)
  {
    InterpretErrorCodes( nRet );
    m_pInterface->GetSQLFreeStmt()(pStatement, SQL_CLOSE);
    ThrowDatabaseException();
    return false;
  }

  nRet = m_pInterface->GetSQLFetch()(pStatement);
  if (nRet == SQL_SUCCESS || nRet == SQL_SUCCESS_WITH_INFO)
    bReturn = true;

  m_pInterface->GetSQLFreeStmt()(pStatement, SQL_CLOSE);
  
  return bReturn;
}
示例#7
0
wxOdbcResultSet::wxOdbcResultSet(wxOdbcInterface* pInterface, wxOdbcPreparedStatement* pStatement, bool bManageStatement, int nCol)
 : wxDatabaseResultSet()
{
    m_pInterface = pInterface;
    m_pStatement = pStatement;
    m_pOdbcStatement = m_pStatement->GetLastStatement();
    m_bManageStatement = bManageStatement;

    // Populate field lookup map
    SQLTCHAR field_name[ODBC_FIELD_NAME_LEN];
    SQLSMALLINT colnamelen;
   
    for (int i=0; i<nCol; i++)
    {
        UWORD col = i+1;
        long nReturn = m_pInterface->GetSQLColAttributes()(m_pOdbcStatement, col, SQL_COLUMN_NAME,
	                      field_name,
                          ODBC_FIELD_NAME_LEN, &colnamelen, 0);
        if ( nReturn != SQL_SUCCESS && nReturn != SQL_SUCCESS_WITH_INFO )
        {
            InterpretErrorCodes(nReturn, m_pOdbcStatement);
            ThrowDatabaseException();
            return;
        }
        
#if wxUSE_UNICODE
		wxString strField = ConvertFromUnicodeStream((const char*)(wxChar*)field_name);
#else
		wxString strField((wxChar*)field_name);
#endif
        m_FieldLookupMap[strField.Upper()] = i;
    }
}
示例#8
0
void wxOdbcDatabase::RollBack()
{
   ResetErrorCodes();

   SQLRETURN nRet = m_pInterface->GetSQLEndTran()(SQL_HANDLE_DBC, (SQLHDBC)m_sqlHDBC, SQL_ROLLBACK);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }
   
   nRet = m_pInterface->GetSQLSetConnectAttr()((SQLHDBC)m_sqlHDBC, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }
}
示例#9
0
void wxOdbcDatabase::BeginTransaction()
{
   ResetErrorCodes();

   SQLRETURN nRet = m_pInterface->GetSQLSetConnectAttr()((SQLHDBC)m_sqlHDBC, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }
}
示例#10
0
wxOdbcDatabase::~wxOdbcDatabase()
{
   Close();

   SQLRETURN nRet = m_pInterface->GetSQLFreeHandle()(SQL_HANDLE_DBC, (SQLHDBC)m_sqlHDBC);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }

   nRet = m_pInterface->GetSQLFreeHandle()(SQL_HANDLE_ENV, (SQLHENV)m_sqlEnvHandle);
   if ( nRet != SQL_SUCCESS )
   {
     InterpretErrorCodes( nRet );
     ThrowDatabaseException();
   }

   wxDELETE(m_pInterface);
}
示例#11
0
void* wxOdbcDatabase::allocStmth()
{
    ResetErrorCodes();

    SQLHANDLE handle = NULL;
        
    SQLRETURN nRet = m_pInterface->GetSQLAllocHandle()(SQL_HANDLE_STMT, (SQLHDBC)m_sqlHDBC, &handle);
    if ( nRet != SQL_SUCCESS )
    {
        InterpretErrorCodes( nRet );
        ThrowDatabaseException();
    }
    return handle;
}
// transaction support
void FirebirdDatabaseLayer::BeginTransaction()
{
  ResetErrorCodes();

  //wxLogDebug(_("Beginning transaction"));
  if (m_pDatabase)
  {
    m_pTransaction = 0L;
    isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
    isc_tr_handle pTransaction = (isc_tr_handle)m_pTransaction;
    int nReturn = m_pInterface->GetIscStartTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pTransaction, 1, &pDatabase, 0 /*tpb_length*/, NULL/*tpb*/);
    m_pDatabase = pDatabase;
    m_pTransaction = pTransaction;
    if (nReturn != 0)
    {
      InterpretErrorCodes();
      ThrowDatabaseException();
    }
  }
}
示例#13
0
bool wxOdbcDatabase::Close()
{
   ResetErrorCodes();

   CloseResultSets();
   CloseStatements();

   if (m_bIsConnected) 
   {
      SQLRETURN nRet = m_pInterface->GetSQLDisconnect()((SQLHDBC)m_sqlHDBC);
      if ( nRet != SQL_SUCCESS )
      {
        InterpretErrorCodes( nRet );
        ThrowDatabaseException();
      }

      m_bIsConnected=false;
   }

   return true;
}
示例#14
0
wxPreparedStatement* wxOdbcDatabase::PrepareStatement( const wxString& strQuery, bool bParseQuery )
{
    ResetErrorCodes();

    wxArrayString QueryArray;
    if (bParseQuery)
      QueryArray = ParseQueries(strQuery);
    else
      QueryArray.push_back(strQuery);

    wxOdbcPreparedStatement* pReturnStatement = new wxOdbcPreparedStatement(m_pInterface, (SQLHENV)m_sqlEnvHandle, (SQLHDBC)m_sqlHDBC);

    if (pReturnStatement)
        pReturnStatement->SetEncoding(GetEncoding());

    for (unsigned int i=0; i<(QueryArray.size()); i++)
    {
//#if wxUSE_UNICODE
//        void* sqlBuffer = (void*)(QueryArray[i].c_str());
//#else
        wxCharBuffer sqlBuffer = ConvertToUnicodeStream(QueryArray[i]);
//#endif
        //wxPrintf(_("Preparing statement: '%s'\n"), sqlBuffer);

        SQLHSTMT pSqlStatement = allocStmth();
        SQLRETURN nRet = m_pInterface->GetSQLPrepare()(pSqlStatement, (SQLTCHAR*)(const char*)sqlBuffer, SQL_NTS);
        if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
        {
            InterpretErrorCodes( nRet );
            m_pInterface->GetSQLFreeStmt()(pSqlStatement, SQL_CLOSE);
            ThrowDatabaseException();
            return NULL;
        }

        if ( pSqlStatement )
            pReturnStatement->AddPreparedStatement( pSqlStatement );
    }

    return pReturnStatement;
}
void FirebirdDatabaseLayer::RollBack()
{
  ResetErrorCodes();

  //wxLogDebug(_("Rolling back transaction"));
  if (m_pDatabase && m_pTransaction)
  {
    isc_tr_handle pTransaction = (isc_tr_handle)m_pTransaction;
    int nReturn = m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pTransaction);
    m_pTransaction = pTransaction;
    if (nReturn != 0)
    {
      InterpretErrorCodes();
      ThrowDatabaseException();
    }
    else
    {
      // We're done with the transaction, so set it to NULL so that we know that a new transaction must be started if we run any queries
      m_pTransaction = NULL;
    }
  }
}
bool FirebirdDatabaseLayer::Open()
{
  ResetErrorCodes();

  // Set up the connection parameter string
  //int nParameterStringLength;
  //char szParameterString[512];
  //char* pParameterString = szParameterString;

  // Firebird accepts all the other ISO_8859 encoding names but ISO-8859-1 needs a little tweaking to be recognized
  //wxString encodingName = wxLocale::GetSystemEncodingName();
  
  //wxCharBuffer systemEncoding;
  //if (encodingName == wxT("ISO-8859-1"))
  // systemEncoding = "ISO8859_1";
  //else
  // systemEncoding = encodingName.mb_str(*wxConvCurrent);
  wxCharBuffer systemEncoding = "UTF-8";

  wxCSConv conv(_("UTF-8"));
  SetEncoding(&conv);
  
  //char* pDpb = new char(512);
  char* pDpb;
  short nDpbLength = 0;
  wxCharBuffer userCharBuffer = ConvertToUnicodeStream(m_strUser);
  wxCharBuffer passwordCharBuffer = ConvertToUnicodeStream(m_strPassword);
  wxCharBuffer roleCharBuffer = ConvertToUnicodeStream(m_strRole);
  
  pDpb = (char*)0;
  
  if (m_strRole == wxEmptyString)
  {
#ifdef wxUSE_UNICODE
    m_pInterface->GetIscExpandDpb()(&pDpb, &nDpbLength, isc_dpb_user_name, (const char*)userCharBuffer,
        isc_dpb_password, (const char*)passwordCharBuffer, isc_dpb_lc_ctype, (const char*)systemEncoding, NULL);
#else
    m_pInterface->GetIscExpandDpb()(&pDpb, &nDpbLength, isc_dpb_user_name, (const char*)userCharBuffer,
        isc_dpb_password, (const char*)m_strPassword.c_str(), isc_dpb_lc_ctype, (const char*)systemEncoding, NULL);
#endif
  }
  else
  {
#ifdef wxUSE_UNICODE
    m_pInterface->GetIscExpandDpb()(&pDpb, &nDpbLength, isc_dpb_user_name, (const char*)userCharBuffer,
        isc_dpb_password, (const char*)passwordCharBuffer, isc_dpb_lc_ctype, (const char*)systemEncoding,
        isc_dpb_sql_role_name, (const char*)roleCharBuffer, NULL);
#else
    m_pInterface->GetIscExpandDpb()(&pDpb, &nDpbLength, isc_dpb_user_name, (const char*)userCharBuffer,
        isc_dpb_password, (const char*)m_strPassword.c_str(), isc_dpb_lc_ctype, (const char*)systemEncoding,
        isc_dpb_sql_role_name, (const char*)roleCharBuffer, NULL);
#endif
  }
    
  // Combine the server and databsae path strings to pass into the isc_attach_databse function
  wxString strDatabaseUrl;
  if (m_strServer.IsEmpty())
    strDatabaseUrl = m_strDatabase; // Embedded database, just supply the file name
  else
    strDatabaseUrl = m_strServer + _(":") + m_strDatabase;
 
  m_pDatabase = NULL;
  m_pTransaction = NULL;

  wxCharBuffer urlBuffer = ConvertToUnicodeStream(strDatabaseUrl);
  isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
  //int nReturn = m_pInterface->GetIscAttachDatabase()(*(ISC_STATUS_ARRAY*)m_pStatus, 0, urlBuffer, &((isc_db_handle)m_pDatabase), nParameterStringLength, szParameterString);
  int nReturn = m_pInterface->GetIscAttachDatabase()(*(ISC_STATUS_ARRAY*)m_pStatus, 0, (char*)(const char*)urlBuffer, &pDatabase, nDpbLength, pDpb);
  m_pDatabase = pDatabase;
  if (nReturn != 0)
  {
    InterpretErrorCodes();
    ThrowDatabaseException();

    return false;
  }
  return true;
}
// query database
int FirebirdDatabaseLayer::RunQuery(const wxString& strQuery, bool bParseQuery)
{
  ResetErrorCodes();
  if (m_pDatabase != NULL)
  {
    wxCharBuffer sqlDebugBuffer = ConvertToUnicodeStream(strQuery);
    //wxLogDebug(_("Running query: \"%s\"\n"), (const char*)sqlDebugBuffer);

    wxArrayString QueryArray;
    if (bParseQuery)
      QueryArray = ParseQueries(strQuery);
    else
      QueryArray.push_back(strQuery);

    wxArrayString::iterator start = QueryArray.begin();
    wxArrayString::iterator stop = QueryArray.end();

    int nRows = 1;
    if (QueryArray.size() > 0)
    {
      bool bQuickieTransaction = false;
    
      if (m_pTransaction == NULL)
      {
        // If there's no transaction is progress, run this as a quick one-timer transaction
        bQuickieTransaction = true;
      }

      if (bQuickieTransaction)
      {
        BeginTransaction();
        if (GetErrorCode() != DATABASE_LAYER_OK)
        {
          wxLogError(_("Unable to start transaction"));
          ThrowDatabaseException();
          return DATABASE_LAYER_QUERY_RESULT_ERROR;
        }
      }

      while (start != stop)
      {
        wxCharBuffer sqlBuffer = ConvertToUnicodeStream(*start);
        isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
        isc_tr_handle pTransaction = (isc_tr_handle)m_pTransaction;
        //int nReturn = m_pInterface->GetIscDsqlExecuteImmediate()(*(ISC_STATUS_ARRAY*)m_pStatus, &pDatabase, &pTransaction, 0, (char*)(const char*)sqlBuffer, SQL_DIALECT_CURRENT, NULL);
        int nReturn = m_pInterface->GetIscDsqlExecuteImmediate()(*(ISC_STATUS_ARRAY*)m_pStatus, &pDatabase, &pTransaction, GetEncodedStreamLength(*start), (char*)(const char*)sqlBuffer, SQL_DIALECT_CURRENT, NULL);
        m_pDatabase = pDatabase;
        m_pTransaction = pTransaction;
        if (nReturn != 0)
        {
          InterpretErrorCodes();
          // Manually try to rollback the transaction rather than calling the member RollBack function
          //  so that we can ignore the error messages
          isc_tr_handle pTransaction = (isc_tr_handle)m_pTransaction;
          m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pTransaction);
          m_pTransaction = NULL;

          ThrowDatabaseException();
          return DATABASE_LAYER_QUERY_RESULT_ERROR;
        }
        start++;
      }

      if (bQuickieTransaction)
      {
        Commit();
        if (GetErrorCode() != DATABASE_LAYER_OK)
        {
          ThrowDatabaseException();
          return DATABASE_LAYER_QUERY_RESULT_ERROR;
        }
      }
    }

    return nRows;
  }
  else
  {
    wxLogError(_("Database handle is NULL"));
    return DATABASE_LAYER_QUERY_RESULT_ERROR;
  }
}
DatabaseResultSet* FirebirdDatabaseLayer::RunQueryWithResults(const wxString& strQuery)
{
  ResetErrorCodes();
  if (m_pDatabase != NULL)
  {
    wxCharBuffer sqlDebugBuffer = ConvertToUnicodeStream(strQuery);
    //wxLogDebug(_("Running query: \"%s\""), (const char*)sqlDebugBuffer);
    
    wxArrayString QueryArray = ParseQueries(strQuery);

    if (QueryArray.size() > 0)
    {
      bool bQuickieTransaction = false;
    
      if (m_pTransaction == NULL)
      {
        // If there's no transaction is progress, run this as a quick one-timer transaction
        bQuickieTransaction = true;
      }

      if (QueryArray.size() > 1)
      {
        if (bQuickieTransaction)
        {
          BeginTransaction();
          if (GetErrorCode() != DATABASE_LAYER_OK)
          {
            wxLogError(_("Unable to start transaction"));
            ThrowDatabaseException();
            return NULL;
          }
        }
      
        // Assume that only the last statement in the array returns the result set
        for (unsigned int i=0; i<QueryArray.size()-1; i++)
        {
          RunQuery(QueryArray[i], false);
          if (GetErrorCode() != DATABASE_LAYER_OK)
          {
            ThrowDatabaseException();
            return NULL;
          }
        }
      
        // Now commit all the previous queries before calling the query that returns a result set
        if (bQuickieTransaction)
        {
          Commit();
          if (GetErrorCode() != DATABASE_LAYER_OK)
          {
            ThrowDatabaseException();
            return NULL;
          }
        }
      } // End check if there are more than one query in the array
      
      isc_tr_handle pQueryTransaction = NULL;
      bool bManageTransaction = false;
      if (bQuickieTransaction)
      {
        bManageTransaction = true;
        isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
        int nReturn = m_pInterface->GetIscStartTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, 1, &pDatabase, 0 /*tpb_length*/, NULL/*tpb*/);
        m_pDatabase = pDatabase;
        if (nReturn != 0)
        {
          InterpretErrorCodes();
          ThrowDatabaseException();
        }
      }
      else
      {
        pQueryTransaction = m_pTransaction;
      }
      
      isc_stmt_handle pStatement = NULL;
      isc_db_handle pDatabase = (isc_db_handle)m_pDatabase;
      int nReturn = m_pInterface->GetIscDsqlAllocateStatement()(*(ISC_STATUS_ARRAY*)m_pStatus, &pDatabase, &pStatement);
      m_pDatabase = pDatabase;
      if (nReturn != 0)
      {
        InterpretErrorCodes();

        // Manually try to rollback the transaction rather than calling the member RollBack function
        //  so that we can ignore the error messages
        m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

        ThrowDatabaseException();
        return NULL;
      }
      
      wxCharBuffer sqlBuffer = ConvertToUnicodeStream(QueryArray[QueryArray.size()-1]);
      nReturn = m_pInterface->GetIscDsqlPrepare()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, &pStatement, 0, (char*)(const char*)sqlBuffer, SQL_DIALECT_CURRENT, NULL);
      if (nReturn != 0)
      {
        InterpretErrorCodes();

        // Manually try to rollback the transaction rather than calling the member RollBack function
        //  so that we can ignore the error messages
        m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

        ThrowDatabaseException();
        return NULL;
      }

//--------------------------------------------------------------

      XSQLDA* pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(1));
      pOutputSqlda->sqln = 1;
      pOutputSqlda->version = SQLDA_VERSION1;

      // Make sure that we have enough space allocated for the result set
      nReturn = m_pInterface->GetIscDsqlDescribe()(*(ISC_STATUS_ARRAY*)m_pStatus, &pStatement, SQL_DIALECT_CURRENT, pOutputSqlda);
      if (nReturn != 0)
      {
        free(pOutputSqlda);
        InterpretErrorCodes();

        // Manually try to rollback the transaction rather than calling the member RollBack function
        //  so that we can ignore the error messages
        m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

        ThrowDatabaseException();
        return NULL;
      }

      if (pOutputSqlda->sqld > pOutputSqlda->sqln)
      {
        int nColumns = pOutputSqlda->sqld;
        free(pOutputSqlda);
        pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(nColumns));
        pOutputSqlda->sqln = nColumns;
        pOutputSqlda->version = SQLDA_VERSION1;
        nReturn = m_pInterface->GetIscDsqlDescribe()(*(ISC_STATUS_ARRAY*)m_pStatus, &pStatement, SQL_DIALECT_CURRENT, pOutputSqlda);
        if (nReturn != 0)
        {
          free(pOutputSqlda);
          InterpretErrorCodes();

          // Manually try to rollback the transaction rather than calling the member RollBack function
          //  so that we can ignore the error messages
          m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

          ThrowDatabaseException();
          return NULL;
        }
      }

      // Create the result set object
      FirebirdResultSet* pResultSet = new FirebirdResultSet(m_pInterface, m_pDatabase, pQueryTransaction, pStatement, pOutputSqlda, true, bManageTransaction);
      pResultSet->SetEncoding(GetEncoding());
      if (pResultSet->GetErrorCode() != DATABASE_LAYER_OK)
      {
        SetErrorCode(pResultSet->GetErrorCode());
        SetErrorMessage(pResultSet->GetErrorMessage());
    
        // Manually try to rollback the transaction rather than calling the member RollBack function
        //  so that we can ignore the error messages
        m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

        // Wrap the result set deletion in try/catch block if using exceptions.
        //We want to make sure the original error gets to the user
#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
        try
        {
#endif
        delete pResultSet;
#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
        }
        catch (DatabaseLayerException& e)
        {
        }
#endif

        ThrowDatabaseException();
      }
  
      // Now execute the SQL
      nReturn = m_pInterface->GetIscDsqlExecute()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, &pStatement, SQL_DIALECT_CURRENT, NULL);
      if (nReturn != 0)
      {
        InterpretErrorCodes();

        // Manually try to rollback the transaction rather than calling the member RollBack function
        //  so that we can ignore the error messages
        m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction);

        // Wrap the result set deletion in try/catch block if using exceptions.
        //  We want to make sure the isc_dsql_execute error gets to the user
#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
        try
        {
#endif
        delete pResultSet;
#ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
        }
        catch (DatabaseLayerException& e)
        {
        }
#endif
    
        ThrowDatabaseException();
        return NULL;
      }
      
//--------------------------------------------------------------

      LogResultSetForCleanup(pResultSet);
      return pResultSet;
    }
    else
      return NULL;
  }
  else
  {
    wxLogError(_("Database handle is NULL"));
    return NULL;
  }
}
示例#19
0
void wxOdbcResultSet::RetrieveFieldData(int nField)
{
    if (nField != -1)
    {
      SQLRETURN rc;
      SQLSMALLINT buflen;
      unsigned long int colType;
      rc = m_pInterface->GetSQLColAttribute()(m_pOdbcStatement, nField, SQL_DESC_TYPE, NULL, 0,
        &buflen, &colType);

      if (SQL_FLOAT == colType || SQL_DOUBLE == colType)
      {
        SQLFLOAT ret;
        SQLINTEGER sqlPtr;
        rc = m_pInterface->GetSQLGetData()(m_pOdbcStatement, nField, SQL_C_DOUBLE, &ret, 0, &sqlPtr);
        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        {
          InterpretErrorCodes(rc, m_pOdbcStatement);
          ThrowDatabaseException();
          return;
        }
        // Mark this field as retrieved
        m_RetrievedValues.insert(nField);
        // Record whether this field is NULL
        if (sqlPtr == SQL_NULL_DATA)
        {
          m_NullValues.insert(nField);
          ret = 0;
          m_fieldValues[nField-1] = ret;
        }
        else
        {
          m_fieldValues[nField-1] = ret;
        }
      }
      else if (SQL_DATETIME == colType)
      {
        TIMESTAMP_STRUCT ret;
        SQLINTEGER sqlPtr;
        rc = m_pInterface->GetSQLGetData()(m_pOdbcStatement, nField, SQL_C_TIMESTAMP, &ret, sizeof(ret),
          &sqlPtr);

        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        {
          InterpretErrorCodes(rc, m_pOdbcStatement);
          ThrowDatabaseException();
          return;
        }
        // Mark this field as retrieved
        m_RetrievedValues.insert(nField);
        // Record whether this field is NULL
        if (sqlPtr == SQL_NULL_DATA)
        {
          m_NullValues.insert(nField);
          //m_fieldValues[nField-1] = wxInvalidDateTime;
        }
        else
        {
          /*
          wxPrintf(_T("day = %d, month = %d, year = %d, hour = %d, minute = %d, second = %d, fraction = %d\n"), 
            ret.day, ret.month, ret.year, ret.hour, ret.minute, ret.second, ret.fraction);*/
          wxDateTime dt(ret.day, wxDateTime::Month(ret.month-1), ret.year, ret.hour,
            ret.minute, ret.second, ret.fraction);
          m_fieldValues[nField-1] = dt;
        }
      }
      else
      {
        wxString strValue;
        SQLPOINTER buff[8192];

        memset(buff, 0, 8192*sizeof(SQLTCHAR));

        SQLINTEGER  col_size         = 8192;
        SQLINTEGER  real_size        = 0;

        if (m_pOdbcStatement == NULL)
            m_pOdbcStatement = m_pStatement->GetLastStatement();

		SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff, col_size, &real_size ); // should SQL_C_CHAR be SQL_C_TCHAR?
        if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
        {
            InterpretErrorCodes(nRet, m_pOdbcStatement);
            ThrowDatabaseException();
            return;
        }
        strValue += ConvertFromUnicodeStream((const wxChar*)/*(const char*)*/buff);
        // Mark this field as retrieved
        m_RetrievedValues.insert(nField);
        // Record whether this field is NULL
        if (real_size == SQL_NULL_DATA)
          m_NullValues.insert(nField);

        if ( real_size > col_size )
        {
            while ( nRet != SQL_NO_DATA )
            {
                nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff, col_size, &real_size ); // should SQL_C_CHAR be SQL_C_TCHAR?
                if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO && nRet != SQL_NO_DATA )
                {
                    InterpretErrorCodes(nRet, m_pOdbcStatement);
                    ThrowDatabaseException();
                    return;
                }
                strValue += ConvertFromUnicodeStream((const wxChar*)/*(const char*)*/buff);
            }
        }

        m_fieldValues[nField-1] = strValue;//.Trim();
      }
    }
}
示例#20
0
void* wxOdbcResultSet::GetResultBlob(int nField, wxMemoryBuffer& Buffer)
{
    if (m_BlobMap.find(nField) == m_BlobMap.end())
    {
      if (m_pOdbcStatement == NULL)
          m_pOdbcStatement = m_pStatement->GetLastStatement();

      if (m_NullValues.find(nField) != m_NullValues.end())
        return NULL;

      SQLINTEGER iLength = 8192;
      SQLINTEGER iSize = 0;
      unsigned char buff[8193];

      memset(buff, 0, 8193*sizeof(unsigned char));

      long nReturn = m_pInterface->GetSQLBindParameter()(m_pOdbcStatement, nField, SQL_PARAM_OUTPUT,
                      SQL_C_BINARY, SQL_BINARY, iLength, 0, &buff, iLength, &iSize);

      // Mark this field as retrieved
      m_RetrievedValues.insert(nField);
      // Record whether this field is NULL
      if (iSize == SQL_NULL_DATA)
      {
        m_NullValues.insert(nField);
        return NULL;
      }

      nReturn = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_BINARY, &buff, iLength, &iSize );
      if ( nReturn != SQL_SUCCESS && nReturn != SQL_SUCCESS_WITH_INFO )
      {
          wxLogError(_T("Error with RunQueryWithResults - 1\n"));
          InterpretErrorCodes(nReturn, m_pOdbcStatement);
          ThrowDatabaseException();
      }

      // NULL data
      if (iSize < 0)
      {
        wxMemoryBuffer tempBuffer(0);
        tempBuffer.SetDataLen(0);
        tempBuffer.SetBufSize(0);
        Buffer = tempBuffer;

        // Add null blobs to the map as well
        m_BlobMap[nField] = tempBuffer;
        return NULL;
      }

      size_t dataLength = (iLength < iSize) ? iLength : iSize;
      size_t bufferSize = dataLength;
      wxMemoryBuffer tempBuffer(dataLength);

      tempBuffer.AppendData( buff, dataLength );

      while ( iSize > iLength )
      {
          nReturn = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_BINARY, &buff, iLength, &iSize );
          if ( nReturn != SQL_SUCCESS && nReturn != SQL_SUCCESS_WITH_INFO )
          {
              wxLogError(_T("Error with RunQueryWithResults - 2\n"));
              InterpretErrorCodes(nReturn, m_pOdbcStatement);
              ThrowDatabaseException();
          }

          dataLength = (iLength < iSize) ? iLength : iSize;
          tempBuffer.AppendData( buff, dataLength );
          bufferSize += dataLength;
      }

      wxMemoryBuffer tempBufferExactSize(bufferSize);
      void* pData = tempBufferExactSize.GetWriteBuf(bufferSize);
      memcpy(pData, tempBuffer.GetData(), bufferSize);
      tempBufferExactSize.UngetWriteBuf(bufferSize);
      tempBufferExactSize.SetDataLen(bufferSize);
      tempBufferExactSize.SetBufSize(bufferSize);
      Buffer = tempBufferExactSize;
 
      wxMemoryBuffer localCopy(Buffer);
      m_BlobMap[nField] = localCopy;

      return Buffer.GetData();
    }
    else
    {
      BlobMap::iterator it = m_BlobMap.find(nField);
      if (it == m_BlobMap.end())
      {
        wxMemoryBuffer tempBuffer(0);
        tempBuffer.SetDataLen(0);
        tempBuffer.SetBufSize(0);
        Buffer = tempBuffer;
        return NULL;
      }
      else
      {
        Buffer = it->second;
        return Buffer.GetData();
      }
    }
}