dbtable.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,992 行 · 第 1/5 页

CPP
1,992
字号
    if (hstmtDefault)
        DeleteCursor(hstmtDefault);

    if (hstmtCount)
        DeleteCursor(hstmtCount);

    if (m_hstmtGridQuery)
        DeleteCursor(m_hstmtGridQuery);

}  // wxDbTable::cleanup()


/***************************** PRIVATE FUNCTIONS *****************************/


void wxDbTable::setCbValueForColumn(int columnIndex)
{
    switch(colDefs[columnIndex].DbDataType)
    {
        case DB_DATA_TYPE_VARCHAR:
            if (colDefs[columnIndex].Null)
                colDefs[columnIndex].CbValue = SQL_NULL_DATA;
            else
                colDefs[columnIndex].CbValue = SQL_NTS;
            break;
        case DB_DATA_TYPE_INTEGER:
            if (colDefs[columnIndex].Null)
                colDefs[columnIndex].CbValue = SQL_NULL_DATA;
            else
                colDefs[columnIndex].CbValue = 0;
            break;
        case DB_DATA_TYPE_FLOAT:
            if (colDefs[columnIndex].Null)
                colDefs[columnIndex].CbValue = SQL_NULL_DATA;
            else
                colDefs[columnIndex].CbValue = 0;
            break;
        case DB_DATA_TYPE_DATE:
            if (colDefs[columnIndex].Null)
                colDefs[columnIndex].CbValue = SQL_NULL_DATA;
            else
                colDefs[columnIndex].CbValue = 0;
            break;
        case DB_DATA_TYPE_BLOB:
            if (colDefs[columnIndex].Null)
                colDefs[columnIndex].CbValue = SQL_NULL_DATA;
            else
                if (colDefs[columnIndex].SqlCtype == SQL_C_WXCHAR)
                    colDefs[columnIndex].CbValue = SQL_NTS;
                else
                    colDefs[columnIndex].CbValue = SQL_LEN_DATA_AT_EXEC(colDefs[columnIndex].SzDataObj);
            break;
    }
}

/********** wxDbTable::bindParams() **********/
bool wxDbTable::bindParams(bool forUpdate)
{
    wxASSERT(!queryOnly);
    if (queryOnly)
        return false;

    SWORD   fSqlType    = 0;
    SDWORD  precision   = 0;
    SWORD   scale       = 0;

    // Bind each column of the table that should be bound
    // to a parameter marker
    int i;
    UWORD colNumber;

    for (i=0, colNumber=1; i < m_numCols; i++)
    {
        if (forUpdate)
        {
            if (!colDefs[i].Updateable)
                continue;
        }
        else
        {
            if (!colDefs[i].InsertAllowed)
                continue;
        }

        switch(colDefs[i].DbDataType)
        {
            case DB_DATA_TYPE_VARCHAR:
                fSqlType = pDb->GetTypeInfVarchar().FsqlType;
                precision = colDefs[i].SzDataObj;
                scale = 0;
                break;
            case DB_DATA_TYPE_INTEGER:
                fSqlType = pDb->GetTypeInfInteger().FsqlType;
                precision = pDb->GetTypeInfInteger().Precision;
                scale = 0;
                break;
            case DB_DATA_TYPE_FLOAT:
                fSqlType = pDb->GetTypeInfFloat().FsqlType;
                precision = pDb->GetTypeInfFloat().Precision;
                scale = pDb->GetTypeInfFloat().MaximumScale;
                // SQL Sybase Anywhere v5.5 returned a negative number for the
                // MaxScale.  This caused ODBC to kick out an error on ibscale.
                // I check for this here and set the scale = precision.
                //if (scale < 0)
                // scale = (short) precision;
                break;
            case DB_DATA_TYPE_DATE:
                fSqlType = pDb->GetTypeInfDate().FsqlType;
                precision = pDb->GetTypeInfDate().Precision;
                scale = 0;
                break;
            case DB_DATA_TYPE_BLOB:
                fSqlType = pDb->GetTypeInfBlob().FsqlType;
                precision = colDefs[i].SzDataObj;
                scale = 0;
                break;
        }

        setCbValueForColumn(i);

        if (forUpdate)
        {
            if (SQLBindParameter(hstmtUpdate, colNumber++, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
                                 fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj,
                                 precision+1, &colDefs[i].CbValue) != SQL_SUCCESS)
            {
                return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
            }
        }
        else
        {
            if (SQLBindParameter(hstmtInsert, colNumber++, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
                                 fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj,
                                 precision+1, &colDefs[i].CbValue) != SQL_SUCCESS)
            {
                return(pDb->DispAllErrors(henv, hdbc, hstmtInsert));
            }
        }
    }

    // Completed successfully
    return true;

}  // wxDbTable::bindParams()


/********** wxDbTable::bindInsertParams() **********/
bool wxDbTable::bindInsertParams(void)
{
    return bindParams(false);
}  // wxDbTable::bindInsertParams()


/********** wxDbTable::bindUpdateParams() **********/
bool wxDbTable::bindUpdateParams(void)
{
    return bindParams(true);
}  // wxDbTable::bindUpdateParams()


/********** wxDbTable::bindCols() **********/
bool wxDbTable::bindCols(HSTMT cursor)
{
    static SQLLEN cb;

    // Bind each column of the table to a memory address for fetching data
    UWORD i;
    for (i = 0; i < m_numCols; i++)
    {
        cb = colDefs[i].CbValue;
        if (SQLBindCol(cursor, (UWORD)(i+1), colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
                       colDefs[i].SzDataObj, &cb ) != SQL_SUCCESS)
          return (pDb->DispAllErrors(henv, hdbc, cursor));
    }

    // Completed successfully
    return true;

}  // wxDbTable::bindCols()


/********** wxDbTable::getRec() **********/
bool wxDbTable::getRec(UWORD fetchType)
{
    RETCODE retcode;

    if (!pDb->FwdOnlyCursors())
    {
        // Fetch the NEXT, PREV, FIRST or LAST record, depending on fetchType
        SQLULEN cRowsFetched;
        UWORD   rowStatus;

        retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus);
        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
        {
            if (retcode == SQL_NO_DATA_FOUND)
                return false;
            else
                return(pDb->DispAllErrors(henv, hdbc, hstmt));
        }
        else
        {
            // Set the Null member variable to indicate the Null state
            // of each column just read in.
            int i;
            for (i = 0; i < m_numCols; i++)
                colDefs[i].Null = (colDefs[i].CbValue == SQL_NULL_DATA);
        }
    }
    else
    {
        // Fetch the next record from the record set
        retcode = SQLFetch(hstmt);
        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
        {
            if (retcode == SQL_NO_DATA_FOUND)
                return false;
            else
                return(pDb->DispAllErrors(henv, hdbc, hstmt));
        }
        else
        {
            // Set the Null member variable to indicate the Null state
            // of each column just read in.
            int i;
            for (i = 0; i < m_numCols; i++)
                colDefs[i].Null = (colDefs[i].CbValue == SQL_NULL_DATA);
        }
    }

    // Completed successfully
    return true;

}  // wxDbTable::getRec()


/********** wxDbTable::execDelete() **********/
bool wxDbTable::execDelete(const wxString &pSqlStmt)
{
    RETCODE retcode;

    // Execute the DELETE statement
    retcode = SQLExecDirect(hstmtDelete, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);

    if (retcode == SQL_SUCCESS ||
        retcode == SQL_NO_DATA_FOUND ||
        retcode == SQL_SUCCESS_WITH_INFO)
    {
        // Record deleted successfully
        return true;
    }

    // Problem deleting record
    return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));

}  // wxDbTable::execDelete()


/********** wxDbTable::execUpdate() **********/
bool wxDbTable::execUpdate(const wxString &pSqlStmt)
{
    RETCODE retcode;

    // Execute the UPDATE statement
    retcode = SQLExecDirect(hstmtUpdate, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);

    if (retcode == SQL_SUCCESS ||
        retcode == SQL_NO_DATA_FOUND ||
        retcode == SQL_SUCCESS_WITH_INFO)
    {
        // Record updated successfully
        return true;
    }
    else if (retcode == SQL_NEED_DATA)
    {
        PTR pParmID;
        retcode = SQLParamData(hstmtUpdate, &pParmID);
        while (retcode == SQL_NEED_DATA)
        {
            // Find the parameter
            int i;
            for (i=0; i < m_numCols; i++)
            {
                if (colDefs[i].PtrDataObj == pParmID)
                {
                    // We found it.  Store the parameter.
                    retcode = SQLPutData(hstmtUpdate, pParmID, colDefs[i].SzDataObj);
                    if (retcode != SQL_SUCCESS)
                    {
                        pDb->DispNextError();
                        return pDb->DispAllErrors(henv, hdbc, hstmtUpdate);
                    }
                    break;
                }
            }
            retcode = SQLParamData(hstmtUpdate, &pParmID);
        }
        if (retcode == SQL_SUCCESS ||
            retcode == SQL_NO_DATA_FOUND ||
            retcode == SQL_SUCCESS_WITH_INFO)
        {
            // Record updated successfully
            return true;
        }
    }

    // Problem updating record
    return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));

}  // wxDbTable::execUpdate()


/********** wxDbTable::query() **********/
bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxString &pSqlStmt)
{
    wxString sqlStmt;

    if (forUpdate)
        // The user may wish to select for update, but the DBMS may not be capable
        selectForUpdate = CanSelectForUpdate();
    else
        selectForUpdate = false;

    // Set the SQL SELECT string
    if (queryType != DB_SELECT_STATEMENT)               // A select statement was not passed in,
    {                                                   // so generate a select statement.
        BuildSelectStmt(sqlStmt, queryType, distinct);
        pDb->WriteSqlLog(sqlStmt);
    }

    // Make sure the cursor is closed first
    if (!CloseCursor(hstmt))
        return false;

    // Execute the SQL SELECT statement
    int retcode;
    retcode = SQLExecDirect(hstmt, (SQLTCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt.c_str() : sqlStmt.c_str()), SQL_NTS);
    if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
        return(pDb->DispAllErrors(henv, hdbc, hstmt));

    // Completed successfully
    return true;

}  // wxDbTable::query()


/***************************** PUBLIC FUNCTIONS *****************************/


/********** wxDbTable::Open() **********/
bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists)
{
    if (!pDb)
        return false;

    int i;
    wxString sqlStmt;
    wxString s;

    // Calculate the maximum size of the concatenated
    // keys for use with wxDbGrid
    m_keysize = 0;
    for (i=0; i < m_numCols; i++)
    {
        if (colDefs[i].KeyField)
        {
            m_keysize += colDefs[i].SzDataObj;
        }
    }

    s.Empty();

    bool exists = true;
    if (checkTableExists)
    {
        if (pDb->Dbms() == dbmsPOSTGRES)
            exists = pDb->TableExists(tableName, NULL, tablePath);
        else
            exists = pDb->TableExists(tableName, pDb->GetUsername(), tablePath);
    }

    // Verify that the table exists in the database
    if (!exists)
    {
        s = wxT("Table/view does not exist in the database");
        if ( *(pDb->dbInf.accessibleTables) == wxT('Y'))
            s += wxT(", or you have no permissions.\n");
        else
            s += wxT(".\n");
    }
    else if (checkPrivileges)
    {
        // Verify the user has rights to access the table.
        bool hasPrivs wxDUMMY_INITIALIZE(true);

        if (pDb->Dbms() == dbmsPOSTGRES)
            hasPrivs = pDb->TablePrivileges(tableName, wxT("SELECT"), pDb->GetUsername(), NULL, tablePath);
        else
            hasPrivs = pDb->TablePrivileges(tableName, wxT("SELECT"), pDb->GetUsername(), pDb->GetUsername(), tablePath);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?