Beginnings of BLOB support - Do not use BLOBs yet though, as they do not work, but these changes will not affect behavor of anything unless you try to create a BLOB column 0 which will fail right now.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9362 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -150,8 +150,6 @@ wxDbConnectInf::wxDbConnectInf(HENV henv, const wxString &dsn, const wxString &u
|
|||||||
const wxString &password, const wxString &defaultDir,
|
const wxString &password, const wxString &defaultDir,
|
||||||
const wxString &fileType, const wxString &description)
|
const wxString &fileType, const wxString &description)
|
||||||
{
|
{
|
||||||
wxASSERT(dsn.Length());
|
|
||||||
|
|
||||||
Henv = 0;
|
Henv = 0;
|
||||||
freeHenvOnDestroy = FALSE;
|
freeHenvOnDestroy = FALSE;
|
||||||
|
|
||||||
@@ -322,6 +320,8 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType,
|
|||||||
i_dbDataType = DB_DATA_TYPE_VARCHAR;
|
i_dbDataType = DB_DATA_TYPE_VARCHAR;
|
||||||
if (i_sqlDataType == SQL_REAL)
|
if (i_sqlDataType == SQL_REAL)
|
||||||
i_dbDataType = DB_DATA_TYPE_FLOAT;
|
i_dbDataType = DB_DATA_TYPE_FLOAT;
|
||||||
|
if (i_sqlDataType == SQL_C_BINARY)
|
||||||
|
i_dbDataType = DB_DATA_TYPE_BLOB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i_dbDataType == DB_DATA_TYPE_INTEGER) && (i_sqlDataType == SQL_C_DOUBLE))
|
if ((i_dbDataType == DB_DATA_TYPE_INTEGER) && (i_sqlDataType == SQL_C_DOUBLE))
|
||||||
@@ -366,6 +366,9 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType,
|
|||||||
s_Field = wxT("%02d/%02d/%04d %02d:%02d:%02d.%03d");
|
s_Field = wxT("%02d/%02d/%04d %02d:%02d:%02d.%03d");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB:
|
||||||
|
s_Field.Printf(wxT("Unable to format(%d)-SQL(%d)"),dbDataType,sqlDataType); //
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
s_Field.Printf(wxT("Unknown Format(%d)-SQL(%d)"),dbDataType,sqlDataType); //
|
s_Field.Printf(wxT("Unknown Format(%d)-SQL(%d)"),dbDataType,sqlDataType); //
|
||||||
break;
|
break;
|
||||||
@@ -529,6 +532,12 @@ void wxDb::initialize()
|
|||||||
typeInfDate.CaseSensitive = 0;
|
typeInfDate.CaseSensitive = 0;
|
||||||
typeInfDate.MaximumScale = 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
|
// Error reporting is turned OFF by default
|
||||||
silent = TRUE;
|
silent = TRUE;
|
||||||
|
|
||||||
@@ -643,7 +652,7 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt
|
|||||||
// Query the data source regarding data type information
|
// Query the data source regarding data type information
|
||||||
|
|
||||||
//
|
//
|
||||||
// The way I determined which SQL data types to use was by calling SQLGetInfo
|
// 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
|
// 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()
|
// 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
|
// fails with SQL_NO_DATA_FOUND. This is ugly because I'm sure the three SQL data
|
||||||
@@ -692,7 +701,6 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt
|
|||||||
|
|
||||||
// Float
|
// Float
|
||||||
if (!getDataTypeInfo(SQL_DOUBLE,typeInfFloat))
|
if (!getDataTypeInfo(SQL_DOUBLE,typeInfFloat))
|
||||||
|
|
||||||
if (!getDataTypeInfo(SQL_REAL,typeInfFloat))
|
if (!getDataTypeInfo(SQL_REAL,typeInfFloat))
|
||||||
if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat))
|
if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat))
|
||||||
if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat))
|
if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat))
|
||||||
@@ -738,11 +746,24 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt
|
|||||||
typeInfDate.FsqlType = SQL_DATE;
|
typeInfDate.FsqlType = SQL_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!getDataTypeInfo(SQL_LONGVARBINARY, typeInfBlob))
|
||||||
|
{
|
||||||
|
if (!getDataTypeInfo(SQL_VARBINARY,typeInfBlob))
|
||||||
|
return(FALSE);
|
||||||
|
else
|
||||||
|
typeInfInteger.FsqlType = SQL_VARBINARY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
typeInfInteger.FsqlType = SQL_LONGVARBINARY;
|
||||||
|
|
||||||
|
//typeInfBlob.TypeName = "BLOB";
|
||||||
|
|
||||||
#ifdef DBDEBUG_CONSOLE
|
#ifdef DBDEBUG_CONSOLE
|
||||||
cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl;
|
cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl;
|
||||||
cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl;
|
cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl;
|
||||||
cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl;
|
cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl;
|
||||||
cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl;
|
cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl;
|
||||||
|
cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -870,11 +891,19 @@ bool wxDb::Open(wxDb *copyDb)
|
|||||||
typeInfDate.CaseSensitive = copyDb->typeInfDate.CaseSensitive;
|
typeInfDate.CaseSensitive = copyDb->typeInfDate.CaseSensitive;
|
||||||
typeInfDate.MaximumScale = copyDb->typeInfDate.MaximumScale;
|
typeInfDate.MaximumScale = copyDb->typeInfDate.MaximumScale;
|
||||||
|
|
||||||
|
// Blob
|
||||||
|
typeInfBlob.FsqlType = copyDb->typeInfBlob.FsqlType;
|
||||||
|
typeInfBlob.TypeName = copyDb->typeInfBlob.TypeName;
|
||||||
|
typeInfBlob.Precision = copyDb->typeInfBlob.Precision;
|
||||||
|
typeInfBlob.CaseSensitive = copyDb->typeInfBlob.CaseSensitive;
|
||||||
|
typeInfBlob.MaximumScale = copyDb->typeInfBlob.MaximumScale;
|
||||||
|
|
||||||
#ifdef DBDEBUG_CONSOLE
|
#ifdef DBDEBUG_CONSOLE
|
||||||
cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl;
|
cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl;
|
||||||
cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl;
|
cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl;
|
||||||
cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl;
|
cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl;
|
||||||
cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl;
|
cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl;
|
||||||
|
cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2186,13 +2215,14 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID)
|
|||||||
#endif
|
#endif
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR;
|
||||||
}
|
}
|
||||||
else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfInteger.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER;
|
||||||
else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfFloat.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT;
|
||||||
else if (!wxStricmp(typeInfDate.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfDate.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
||||||
|
else if (!wxStricmp(typeInfBlob.TypeName, colInf[colNo].typeName))
|
||||||
|
colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB;
|
||||||
colNo++;
|
colNo++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2343,7 +2373,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh
|
|||||||
|
|
||||||
// Determine the wxDb data type that is used to represent the native data type of this data source
|
// Determine the wxDb data type that is used to represent the native data type of this data source
|
||||||
colInf[colNo].dbDataType = 0;
|
colInf[colNo].dbDataType = 0;
|
||||||
if (!wxStricmp(typeInfVarchar.TypeName,colInf[colNo].typeName))
|
if (!wxStricmp(typeInfVarchar.TypeName, colInf[colNo].typeName))
|
||||||
{
|
{
|
||||||
#ifdef _IODBC_
|
#ifdef _IODBC_
|
||||||
// IODBC does not return a correct columnSize, so we set
|
// IODBC does not return a correct columnSize, so we set
|
||||||
@@ -2357,12 +2387,14 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh
|
|||||||
|
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR;
|
||||||
}
|
}
|
||||||
else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfInteger.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER;
|
||||||
else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfFloat.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT;
|
||||||
else if (!wxStricmp(typeInfDate.TypeName,colInf[colNo].typeName))
|
else if (!wxStricmp(typeInfDate.TypeName, colInf[colNo].typeName))
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
||||||
|
else if (!wxStricmp(typeInfBlob.TypeName, colInf[colNo].typeName))
|
||||||
|
colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB;
|
||||||
|
|
||||||
colNo++;
|
colNo++;
|
||||||
}
|
}
|
||||||
@@ -2620,6 +2652,9 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh
|
|||||||
case SQL_DATE:
|
case SQL_DATE:
|
||||||
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
colInf[colNo].dbDataType = DB_DATA_TYPE_DATE;
|
||||||
break;
|
break;
|
||||||
|
case SQL_BINARY:
|
||||||
|
colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB;
|
||||||
|
break;
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
default:
|
default:
|
||||||
wxString errMsg;
|
wxString errMsg;
|
||||||
@@ -3435,6 +3470,9 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName,
|
|||||||
case DB_DATA_TYPE_DATE :
|
case DB_DATA_TYPE_DATE :
|
||||||
dataTypeName = typeInfDate.TypeName;
|
dataTypeName = typeInfDate.TypeName;
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB :
|
||||||
|
dataTypeName = typeInfBlob.TypeName;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@@ -487,6 +487,15 @@ bool wxDbTable::bindParams(bool forUpdate)
|
|||||||
else
|
else
|
||||||
colDefs[i].CbValue = 0;
|
colDefs[i].CbValue = 0;
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB:
|
||||||
|
fSqlType = pDb->GetTypeInfBlob().FsqlType;
|
||||||
|
precision = 50000;
|
||||||
|
scale = 0;
|
||||||
|
if (colDefs[i].Null)
|
||||||
|
colDefs[i].CbValue = SQL_NULL_DATA;
|
||||||
|
else
|
||||||
|
colDefs[i].CbValue = SQL_LEN_DATA_AT_EXEC(colDefs[i].SzDataObj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (forUpdate)
|
if (forUpdate)
|
||||||
{
|
{
|
||||||
@@ -1315,6 +1324,9 @@ bool wxDbTable::CreateTable(bool attemptDrop)
|
|||||||
case DB_DATA_TYPE_DATE:
|
case DB_DATA_TYPE_DATE:
|
||||||
cout << pDb->typeInfDate.TypeName;
|
cout << pDb->typeInfDate.TypeName;
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB:
|
||||||
|
cout << pDb->typeInfBlob.TypeName;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
@@ -1350,9 +1362,13 @@ bool wxDbTable::CreateTable(bool attemptDrop)
|
|||||||
case DB_DATA_TYPE_DATE:
|
case DB_DATA_TYPE_DATE:
|
||||||
sqlStmt += pDb->GetTypeInfDate().TypeName;
|
sqlStmt += pDb->GetTypeInfDate().TypeName;
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB:
|
||||||
|
sqlStmt += pDb->GetTypeInfBlob().TypeName;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// For varchars, append the size of the string
|
// For varchars, append the size of the string
|
||||||
if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)
|
if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)// ||
|
||||||
|
// colDefs[i].DbDataType == DB_DATA_TYPE_BLOB)
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
s.Printf(wxT("(%d)"), colDefs[i].SzDataObj);
|
s.Printf(wxT("(%d)"), colDefs[i].SzDataObj);
|
||||||
@@ -2119,8 +2135,26 @@ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols)
|
|||||||
pColDataPtrs[index].SzDataObj = sizeof(TIMESTAMP_STRUCT);
|
pColDataPtrs[index].SzDataObj = sizeof(TIMESTAMP_STRUCT);
|
||||||
pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP;
|
pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP;
|
||||||
break;
|
break;
|
||||||
|
case DB_DATA_TYPE_BLOB:
|
||||||
|
int notSupportedYet = 0;
|
||||||
|
wxASSERT_MSG(notSupportedYet, wxT("This form of ::SetColDefs() cannot be used with BLOB columns"));
|
||||||
|
pColDataPtrs[index].PtrDataObj = /*BLOB ADDITION NEEDED*/NULL;
|
||||||
|
pColDataPtrs[index].SzDataObj = /*BLOB ADDITION NEEDED*/sizeof(void *);
|
||||||
|
pColDataPtrs[index].SqlCtype = SQL_VARBINARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pColDataPtrs[index].PtrDataObj != NULL)
|
||||||
|
SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unable to build all the column definitions, as either one of
|
||||||
|
// the calls to "new" failed above, or there was a BLOB field
|
||||||
|
// to have a column definition for. If BLOBs are to be used,
|
||||||
|
// the other form of ::SetColDefs() must be used, as it is impossible
|
||||||
|
// to know the maximum size to create the PtrDataObj to be.
|
||||||
|
delete [] pColDataPtrs;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user