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 + -
显示快捷键?