db.cpp

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

CPP
1,858
字号
wxDbColInf::~wxDbColInf()
{
    if (pColFor)
        delete pColFor;
    pColFor = NULL;
}  // wxDbColInf::~wxDbColInf()


bool wxDbColInf::Initialize()
{
    catalog[0]      = 0;
    schema[0]       = 0;
    tableName[0]    = 0;
    colName[0]      = 0;
    sqlDataType     = 0;
    typeName[0]     = 0;
    columnLength    = 0;
    bufferSize      = 0;
    decimalDigits   = 0;
    numPrecRadix    = 0;
    nullable        = 0;
    remarks[0]      = 0;
    dbDataType      = 0;
    PkCol           = 0;
    PkTableName[0]  = 0;
    FkCol           = 0;
    FkTableName[0]  = 0;
    pColFor         = NULL;

    return true;
}  // wxDbColInf::Initialize()


/********** wxDbTableInf Constructor ********/
wxDbTableInf::wxDbTableInf()
{
    Initialize();
}  // wxDbTableInf::wxDbTableInf()


/********** wxDbTableInf Constructor ********/
wxDbTableInf::~wxDbTableInf()
{
    if (pColInf)
        delete [] pColInf;
    pColInf = NULL;
}  // wxDbTableInf::~wxDbTableInf()


bool wxDbTableInf::Initialize()
{
    tableName[0]    = 0;
    tableType[0]    = 0;
    tableRemarks[0] = 0;
    numCols         = 0;
    pColInf         = NULL;

    return true;
}  // wxDbTableInf::Initialize()


/********** wxDbInf Constructor *************/
wxDbInf::wxDbInf()
{
    Initialize();
}  // wxDbInf::wxDbInf()


/********** wxDbInf Destructor *************/
wxDbInf::~wxDbInf()
{
  if (pTableInf)
    delete [] pTableInf;
  pTableInf = NULL;
}  // wxDbInf::~wxDbInf()


/********** wxDbInf::Initialize() *************/
bool wxDbInf::Initialize()
{
    catalog[0]      = 0;
    schema[0]       = 0;
    numTables       = 0;
    pTableInf       = NULL;

    return true;
}  // wxDbInf::Initialize()


/********** wxDb Constructor **********/
wxDb::wxDb(const HENV &aHenv, bool FwdOnlyCursors)
{
    // Copy the HENV into the db class
    henv = aHenv;
    fwdOnlyCursors = FwdOnlyCursors;

    initialize();
} // wxDb::wxDb()


/********** wxDb Destructor **********/
wxDb::~wxDb()
{
    wxASSERT_MSG(!IsCached(),wxT("Cached connections must not be manually deleted, use\nwxDbFreeConnection() or wxDbCloseConnections()."));

    if (IsOpen())
    {
        Close();
    }
}  // wxDb destructor



/********** PRIVATE! wxDb::initialize PRIVATE! **********/
/********** wxDb::initialize() **********/
void wxDb::initialize()
/*
 * Private member function that sets all wxDb member variables to
 * known values at creation of the wxDb
 */
{
    int i;

    fpSqlLog      = 0;            // Sql Log file pointer
    sqlLogState   = sqlLogOFF;    // By default, logging is turned off
    nTables       = 0;
    dbmsType      = dbmsUNIDENTIFIED;

    wxStrcpy(sqlState,wxEmptyString);
    wxStrcpy(errorMsg,wxEmptyString);
    nativeError = cbErrorMsg = 0;
    for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
        wxStrcpy(errorList[i], wxEmptyString);

    // Init typeInf structures
    typeInfVarchar.TypeName.Empty();
    typeInfVarchar.FsqlType      = 0;
    typeInfVarchar.Precision     = 0;
    typeInfVarchar.CaseSensitive = 0;
    typeInfVarchar.MaximumScale  = 0;

    typeInfInteger.TypeName.Empty();
    typeInfInteger.FsqlType      = 0;
    typeInfInteger.Precision     = 0;
    typeInfInteger.CaseSensitive = 0;
    typeInfInteger.MaximumScale  = 0;

    typeInfFloat.TypeName.Empty();
    typeInfFloat.FsqlType      = 0;
    typeInfFloat.Precision     = 0;
    typeInfFloat.CaseSensitive = 0;
    typeInfFloat.MaximumScale  = 0;

    typeInfDate.TypeName.Empty();
    typeInfDate.FsqlType      = 0;
    typeInfDate.Precision     = 0;
    typeInfDate.CaseSensitive = 0;
    typeInfDate.MaximumScale  = 0;

    typeInfBlob.TypeName.Empty();
    typeInfBlob.FsqlType      = 0;
    typeInfBlob.Precision     = 0;
    typeInfBlob.CaseSensitive = 0;
    typeInfBlob.MaximumScale  = 0;

    // Error reporting is turned OFF by default
    silent = true;

    // Allocate a data source connection handle
    if (SQLAllocConnect(henv, &hdbc) != SQL_SUCCESS)
        DispAllErrors(henv);

    // Initialize the db status flag
    DB_STATUS = 0;

    // Mark database as not open as of yet
    dbIsOpen = false;
    dbIsCached = false;
    dbOpenedWithConnectionString = false;
}  // wxDb::initialize()


/********** PRIVATE! wxDb::convertUserID PRIVATE! **********/
//
// NOTE: Return value from this function MUST be copied
//       immediately, as the value is not good after
//       this function has left scope.
//
const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID)
{
    if (userID)
    {
        if (!wxStrlen(userID))
            UserID = uid;
        else
            UserID = userID;
    }
    else
        UserID.Empty();

    // dBase does not use user names, and some drivers fail if you try to pass one
    if ( Dbms() == dbmsDBASE
         || Dbms() == dbmsXBASE_SEQUITER )
        UserID.Empty();

    // Some databases require user names to be specified in uppercase,
    // so force the name to uppercase
    if ((Dbms() == dbmsORACLE) ||
        (Dbms() == dbmsMAXDB))
        UserID = UserID.Upper();

    return UserID.c_str();
}  // wxDb::convertUserID()


bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported)
{
    size_t iIndex;

    // These are the possible SQL types we check for use against the datasource we are connected
    // to for the purpose of determining which data type to use for the basic character strings
    // column types
    //
    // NOTE: The first type in this enumeration that is determined to be supported by the
    //       datasource/driver is the one that will be used.
    SWORD PossibleSqlCharTypes[] = {
#if wxUSE_UNICODE && defined(SQL_WVARCHAR)
        SQL_WVARCHAR,
#endif
        SQL_VARCHAR,
#if wxUSE_UNICODE && defined(SQL_WVARCHAR)
        SQL_WCHAR,
#endif
        SQL_CHAR
    };

    // These are the possible SQL types we check for use against the datasource we are connected
    // to for the purpose of determining which data type to use for the basic non-floating point
    // column types
    //
    // NOTE: The first type in this enumeration that is determined to be supported by the
    //       datasource/driver is the one that will be used.
    SWORD PossibleSqlIntegerTypes[] = {
        SQL_INTEGER
    };

    // These are the possible SQL types we check for use against the datasource we are connected
    // to for the purpose of determining which data type to use for the basic floating point number
    // column types
    //
    // NOTE: The first type in this enumeration that is determined to be supported by the
    //       datasource/driver is the one that will be used.
    SWORD PossibleSqlFloatTypes[] = {
        SQL_DOUBLE,
        SQL_REAL,
        SQL_FLOAT,
        SQL_DECIMAL,
        SQL_NUMERIC
    };

    // These are the possible SQL types we check for use agains the datasource we are connected
    // to for the purpose of determining which data type to use for the date/time column types
    //
    // NOTE: The first type in this enumeration that is determined to be supported by the
    //       datasource/driver is the one that will be used.
    SWORD PossibleSqlDateTypes[] = {
        SQL_TIMESTAMP,
        SQL_DATE,
#ifdef SQL_DATETIME
        SQL_DATETIME
#endif
    };

    // These are the possible SQL types we check for use agains the datasource we are connected
    // to for the purpose of determining which data type to use for the BLOB column types.
    //
    // NOTE: The first type in this enumeration that is determined to be supported by the
    //       datasource/driver is the one that will be used.
    SWORD PossibleSqlBlobTypes[] = {
        SQL_LONGVARBINARY,
        SQL_VARBINARY
    };


    // Query the data source regarding data type information

    //
    // The way it was determined which SQL data types to use was by calling SQLGetInfo
    // for all of the possible SQL data types to see which ones were supported.  If
    // a type is not supported, the SQLFetch() that's called from getDataTypeInfo()
    // fails with SQL_NO_DATA_FOUND.  This is ugly because I'm sure the three SQL data
    // types I've selected below will not always be what we want.  These are just
    // what happened to work against an Oracle 7/Intersolv combination.  The following is
    // a complete list of the results I got back against the Oracle 7 database:
    //
    // SQL_BIGINT             SQL_NO_DATA_FOUND
    // SQL_BINARY             SQL_NO_DATA_FOUND
    // SQL_BIT                SQL_NO_DATA_FOUND
    // SQL_CHAR               type name = 'CHAR', Precision = 255
    // SQL_DATE               SQL_NO_DATA_FOUND
    // SQL_DECIMAL            type name = 'NUMBER', Precision = 38
    // SQL_DOUBLE             type name = 'NUMBER', Precision = 15
    // SQL_FLOAT              SQL_NO_DATA_FOUND
    // SQL_INTEGER            SQL_NO_DATA_FOUND
    // SQL_LONGVARBINARY      type name = 'LONG RAW', Precision = 2 billion
    // SQL_LONGVARCHAR        type name = 'LONG', Precision = 2 billion
    // SQL_NUMERIC            SQL_NO_DATA_FOUND
    // SQL_REAL               SQL_NO_DATA_FOUND
    // SQL_SMALLINT           SQL_NO_DATA_FOUND
    // SQL_TIME               SQL_NO_DATA_FOUND
    // SQL_TIMESTAMP          type name = 'DATE', Precision = 19
    // SQL_VARBINARY          type name = 'RAW', Precision = 255
    // SQL_VARCHAR            type name = 'VARCHAR2', Precision = 2000
    // =====================================================================
    // Results from a Microsoft Access 7.0 db, using a driver from Microsoft
    //
    // SQL_VARCHAR            type name = 'TEXT', Precision = 255
    // SQL_TIMESTAMP          type name = 'DATETIME'
    // SQL_DECIMAL            SQL_NO_DATA_FOUND
    // SQL_NUMERIC            type name = 'CURRENCY', Precision = 19
    // SQL_FLOAT              SQL_NO_DATA_FOUND
    // SQL_REAL               type name = 'SINGLE', Precision = 7
    // SQL_DOUBLE             type name = 'DOUBLE', Precision = 15
    // SQL_INTEGER            type name = 'LONG', Precision = 10

    // Query the data source for info about itself
    if (!getDbInfo(failOnDataTypeUnsupported))
        return false;

    // --------------- Varchar - (Variable length character string) ---------------
    for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlCharTypes) &&
                     !getDataTypeInfo(PossibleSqlCharTypes[iIndex], typeInfVarchar); ++iIndex)
    {}

    if (iIndex < WXSIZEOF(PossibleSqlCharTypes))
        typeInfVarchar.FsqlType = PossibleSqlCharTypes[iIndex];
    else if (failOnDataTypeUnsupported)
        return false;

    // --------------- Float ---------------
    for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlFloatTypes) &&
                     !getDataTypeInfo(PossibleSqlFloatTypes[iIndex], typeInfFloat); ++iIndex)
    {}

    if (iIndex < WXSIZEOF(PossibleSqlFloatTypes))
        typeInfFloat.FsqlType = PossibleSqlFloatTypes[iIndex];
    else if (failOnDataTypeUnsupported)
        return false;

    // --------------- Integer -------------
    for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlIntegerTypes) &&
                     !getDataTypeInfo(PossibleSqlIntegerTypes[iIndex], typeInfInteger); ++iIndex)
    {}

    if (iIndex < WXSIZEOF(PossibleSqlIntegerTypes))
        typeInfInteger.FsqlType = PossibleSqlIntegerTypes[iIndex];
    else if (failOnDataTypeUnsupported)
    {
        // If no non-floating point data types are supported, we'll
        // use the type assigned for floats to store integers as well
        if (!getDataTypeInfo(typeInfFloat.FsqlType, typeInfInteger))
        {
            if (failOnDataTypeUnsupported)
                return false;
        }
        else
            typeInfInteger.FsqlType = typeInfFloat.FsqlType;
    }

    // --------------- Date/Time ---------------
    for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlDateTypes) &&
                     !getDataTypeInfo(PossibleSqlDateTypes[iIndex], typeInfDate); ++iIndex)

⌨️ 快捷键说明

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