//-------------------------------------------------------------------- // Microsoft OLE DB Test // // Copyright 1995-2000 Microsoft Corporation. // // @doc // // @module CTable Header Module | This module contains header information for CTable // // @normal (C) Copyright 1995-1998 Microsoft Corporation. All Rights Reserved. // // @comm // Special Notes...: (OPTIONAL NOTES FOR SPECIAL CIRCUMSTANCES) // // // Revision History: // // [00] MM-DD-YY EMAIL_NAME ACTION PERFORMED... // [01] 10-05-95 Microsoft Created // [02] 12-01-96 Microsoft Updated for release // // @head3 CTable Elements| // // @subindex CTable| // //--------------------------------------------------------------------------- #ifndef _CTable_HPP_ #define _CTable_HPP_ //----------------------------------------------------------------------------- // @comm #pragma warning (disable: 4251) - This warning is generated by having // CLists as member variables in a class that is exposed through // a dll interface. This is simply a warning. The CList member variables // are not exposed even if they are public data members. There have to be Get/Set // functions that handle these member variables. // //----------------------------------------------------------------------------- #pragma warning (disable :4251) ///////////////////////////////////////////////////////////////////// // Includes // ///////////////////////////////////////////////////////////////////// #include "CCol.hpp" #include "CTree.hpp" #include "List.h" #define READ_DBPROP_COL_AUTOINCREMENT 1 #define READ_DBPROP_COL_DEFAULT 2 #define READ_DBPROP_COL_FIXEDLENGTH 4 #define READ_DBPROP_COL_NULLABLE 8 #define READ_DBPROP_COL_UNIQUE 16 #define READ_COL_CLSID 32 const ULONG COL_NOT_COND = 0x1; const ULONG COL_COND_NULL = 0x2; const ULONG COL_COND_DEFAULT = 0x4; const ULONG COL_COND_UNIQUE = 0x8; const ULONG COL_COND_UPDATEABLE = 0x10; const ULONG COL_COND_AUTOINC = 0x20; const ULONG COL_COND_NOTNULL = COL_COND_NULL | COL_NOT_COND; const ULONG COL_COND_NOTDEFAULT = COL_COND_DEFAULT | COL_NOT_COND; const ULONG COL_COND_NOTUNIQUE = COL_COND_UNIQUE | COL_NOT_COND; const ULONG COL_COND_NOTUPDATEABLE = COL_COND_UPDATEABLE | COL_NOT_COND; const ULONG COL_COND_NOTAUTOINC = COL_COND_AUTOINC | COL_NOT_COND; //-------------------------------------------------------------------- // @class A class used to generate internation strings based on the code // page. class CLocaleInfo { public: //Convstructors CLocaleInfo(LCID lcid); virtual ~CLocaleInfo(); //String Creation Methods virtual BOOL MakeUnicodeIntlString(WCHAR* pwsz, INT len); virtual BOOL MakeUnicodeIntlData(WCHAR* pwsz, INT len); virtual BOOL MakeAnsiIntlString(CHAR* psz, INT len); virtual WCHAR MakeUnicodeChar(); virtual void MakeAnsiChar(CHAR* pcLead, CHAR* pcTrail); virtual WCHAR* MakeUnicodeInt(int val); //Localized Convervsion Methods virtual HRESULT LocalizeString(WCHAR* pwszString, BSTR* pbstrLocalizedString); virtual HRESULT LocalizeVariant(VARIANT* pVariant, VARIANT* pVarLocalized); //Interface virtual BOOL SetAnsiSeed(INT val); virtual BOOL SetUnicodeSeed(INT val); protected: LCID m_lcid; WCHAR* m_wszUnicodeChars; UCHAR* m_szAnsiChars; INT m_cchUnicode; INT m_cchAnsi; INT m_seedUnicode; INT m_seedAnsi; INT m_nCharMaxWidth; WCHAR* m_wszSurrogateChars; }; //----------------------------------------------------------------------------- // @class CTable | The class is responsible for creating, manipulating, // and deleting tables. The columns of the tables are actually CCol objects. // // // Caveat 1: Important pointers // The constructor has to have the DataSource Object and Session Object // passed to it or the class will not work. However, the IMalloc // pointer is created inside the constructor so the class can // manage its own memory. This IMalloc pointer is passed down // to the CCol class's constructor, so the CCol and CTable objects // are meant to be used together. // // // Caveat 2: SQL Statments // The BuildCommand/Execute commands and Select command have similar // functionality. But for insert/update/delete, the ExecuteCommand // cannot be used. The CreateSQLStmt/BuildCommand/ExecuteCommand // functions should be reviewed before use. Each has several uses. // // // Caveat 3: The following functions are not implemented currently: // DoesIndexExist() // SetExistingTable() // SetFromIColumnsInfoGetColumnInfo() // SetFromColumnsRowset() // SetTableColumnInfo() // // // Caveat 4:Array numbers // CCol objects are actually stored in the CTable in the MFC class of // CList,which is 0 based. // Columns in the base table are 1 based unless there is a bookmark. // Then the bookmark is the 0th element. // Rows in the base table and CTable object are 1 based. // //----------------------------------------------------------------------------- class CTable : public CSchema { // @access Private private: // @cmember Name of view over this table. WCHAR * m_pwszViewName; // @cmember Structure containing table name, used for ITableDefinition. DBID m_TableID; // IDBInfo (used Literals) ULONG m_cLiteralInfo; DBLITERALINFO* m_rgLiteralInfo; WCHAR* m_pwszLiteralInfoBuffer; // @cmember Name of index on this table. WCHAR * m_pwszIndexName; // @cmember Test case module name. WCHAR * m_pwszModuleName; // @cmember Total number of rows in CTable object. DBCOUNTITEM m_ulRows; // @cmember Next row to insert, used in Insert ONLY. DBCOUNTITEM m_ulNextRow; // @cmember Indicates what SQL Support the Provider has. LONG_PTR m_lSQLSupport; // @cmember DataSource interface IDBInitialize* m_pIDBInitialize; // @cmember Session interfaces IOpenRowset* m_pIOpenRowset; IDBCreateCommand* m_pIDBCreateCommand; // @cmember Error object used to verify OLE DB calls. CError * m_pError; // @cmember Outer Unknown (controlling unknown) for use with ITableDefinition::CreateTable IUnknown* m_pUnkOuter; // @cmember REFIID in ITableDefinition::CreateTable IID* m_riid; // @cmember Pointer to DBID returned by ITableDefinition::CreateTable DBID** m_ppTableID; // @cmember Pointer to the rowset interface returned when creating a table IUnknown** m_ppRowset; // @cmember Array of property sets used for ITableDefinition::CreateTable DBPROPSET *m_rgPropertySets; // @cmember Number of elements in the array of properties ULONG m_cPropertySets; // @cmember Array of column descriptors used for ITableDefinition::CreateTable DBCOLUMNDESC* m_rgColumnDesc; // @cmember Number of elements in the array of column descriptors DBORDINAL m_cColumnDesc; // @cmember Whether to use a NULL Table ID in ITableDefinition::CreateTable BOOL m_fInputTableID; // @cmember Whether to build a list of column desc for ITableDefinition::CreateTable BOOL m_fBuildColumnDesc; // tell what props and supl info are available on col // @cmember Column Has Default Value BOOL m_fHasAuto; // @cmember Column Has Default Value BOOL m_fHasUnique; // @cmember Column Has Default Value BOOL m_fHasCLSID; // @cmember Column Has Default Value BOOL m_fHasDefault; // @cmember Flag for available column properties (which properties of the column were got) ULONG m_fColProps; // @cmember Flag if the Provider is ReadOnly ULONG m_fProviderReadOnly; // @cmember ULONG for the Identifier Case ULONG_PTR m_ulIdentifierCase; // @cmember Cached PROVIDER_TYPES schema info CSchema * m_pSchemaCache; // @access Public public: // @cmember Command object to use in this class. ICommand * m_pICommand; // migrate to use this function instead of using public member m_pICommand virtual inline ICommand * get_ICommandPTR(void) { return m_pICommand; }; virtual inline void set_ICommandPTR( ICommand *pICommand) { m_pICommand = pICommand; }; // @cmember Constructor. There is only one. CTable( IUnknown * pSessionIUnknown, // [IN] CreateCommand pointer from client WCHAR * pwszModuleName=NULL, // [IN] Table name, optional (Default=NULL) ENULL eNull=USENULLS // [IN] Should nulls be used (Default=USENULLS) ); // @cmember Destructor. Gets rid of any memory. virtual ~CTable(void); // @cmember Builds an array used by ITableDefinition::CreateTable, // based on column info. HRESULT BuildColumnDescs(DBCOLUMNDESC** prgColumnDescs); // @cmember Builds a DBCOLUMNDESC stru used by ITableDefinition::CreateTable, // and ITableDefinition::AddColumn based on column info. HRESULT BuildColumnDesc(DBCOLUMNDESC *pColumnDesc, CCol& CurCol); // @cmember PrintTable. Prints CCol Info in debug window ONLY. void PrintCColInfo(); // @cmember Reset the pointer to IDBCreateCommand inside CTable. // This function should only be called within the same Data Source object. // The intention of this method is for CTransaction class so that when // ExecuteCommand is called, a new pIDBCreateCommand is used for the new // transacion. HRESULT ResetCreateCommand( IDBCreateCommand *pIDBCreateCommand // [IN] IDBCreateCommand pointer ); // @cmember Returns if Non null columns can be created on the database. BOOL IsNonNullColumnsAllowed(); // @cmember Returns the SQLSupport of a Provider. void ProviderSQLSupport(); // @cmember Creates table of all types found in Data Source #1. Default behavior // creates a table with an autogenerated table name. The table has no rows. The // index is on the first column. HRESULT CreateTable( DBCOUNTITEM ulRowCount, // [IN] Number of rows to generate, 1 based DBORDINAL ulIndex=1, // [IN] Column that has index, 1 based (Default=1) WCHAR * pwszTableName=NULL, // [IN] TableName,if NULL will be created internally (Default=NULL) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data to insert (Default=PRIMARY) BOOL fFirstUpdateable=FALSE // [IN] TRUE means first column will not be autoinc (Default=FALSE) ); // @cmember Creates table based on list of provider types #2. Default behavior // creates a table with an autogenerated table name. The table has no rows. The // index is on the first column. // Please note that the private library will NOT // arrange your columns. The order you pass them in is the order the table will // be created. If any column you pass in can't be created or the index can't // be created on the column specified, the table creation will fail. HRESULT CreateTable( CList & rDBTypesList, // [IN] Types of columns DBCOUNTITEM ulRowCount, // [IN] Number of rows to generate, 1 based DBORDINAL ulIndex=1, // [IN] Column that has index (Default=1) WCHAR * pwszTableName=NULL, // [IN] TableName,if NULL will be created internally (Default=NULL) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data to insert (Default=PRIMARY) BOOL fFirstUpdateable=FALSE // [IN] TRUE means first column will not be autoinc (Default=FALSE) ); // @cmember Creates table based on list of native types #3.Default behavior // creates a table with an autogenerated table name. The table has no rows. The // index is on the first column. // Please note that the private library will NOT // arrange your columns. The order you pass them in is the order the table will // be created. If any column you pass in can't be created or the index can't // be created on the column specified, the table creation will fail. HRESULT CreateTable( CList & rNativeTypesList, // [IN] Types of columns DBCOUNTITEM ulRowCount, // [IN] Number of rows to generate DBORDINAL ulIndex=1, // [IN] Column that has index (Default=1) WCHAR * pwszTableName=NULL, // [IN] TableName,if NULL will be created internally (Default=NULL) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data (Default=PRIMARY) BOOL fFirstUpdateable=FALSE // [IN] TRUE means first column will not be autoinc (Default=FALSE) ); // @cmember Creates Index on Table. Default behavior creates unique index // on column 1. // "create [unique] index index_name on table_name (column_name)" , uses // column ordinal number (m_ColNum). Index name is same as table name. Index // is unique if EINDEXTYPE is UNIQUE, else not unique. HRESULT CreateIndex( DBORDINAL ulColNum=1, // [IN] Column number,first column should be numeric (Default=1) EINDEXTYPE eIndexType=UNIQUE, // [IN] Constraint type (Default=UNIQUE) LPWSTR pwszIndexName=NULL // [IN] Index name to use, default NULL will use table name. ); // @cmember Creates Index on Table. Default behavior creates unique index // Used to create an index on one or more columns HRESULT CTable::CreateIndex( DBORDINAL* rgulOrdinals, // [IN] Array of ordinals DBORDINAL cOrdinals, // [IN] Count of ordinals EINDEXTYPE eIndexType=UNIQUE, // [IN] Type of index (Default = UNIQUE) LPWSTR pwszIndexName=NULL // [IN] Index name to use, default NULL will use table name. ); // @cmember Builds a select statement on table, executes if requested. // This function is an alternative to BuildComand and ExecuteCommand. // It would be used when you know which singular row you want returned. HRESULT Select( IUnknown* pIUnkOuter, // [IN] Aggregate DBCOUNTITEM ulRowNumber, // [IN] Row number to select REFIID riid, // [IN] Type of interface user wants back ULONG cPropSets, // [IN] Count of property sets. DBPROPSET* rgPropSets, // [IN] Array of DBPROPSET structures. DBROWCOUNT* pcRowsAffected, // [OUT] Pointer to memory in which to return the count // of rows affected by a command that updates, deletes, // or inserts rows. IUnknown ** ppIUnknown, // [OUT] Interface pointer user wants back (Default=NULL) ICommand ** ppICommand=NULL // [IN/OUT] If ppICommand == NULL, this function uses // its own command object and then frees it, caller does nothing. // // If *ppICommand is not null, this value is used as the // ICommand interface for all command operations in this function. // Caller maintains responsiblity to release this interface. // // If *ppICommand is null, this function creates a new command object // and places the ICommand interface to this object in *ppICommand. // Caller assumes responsibility to release this interface. ); // @cmember Inserts a row into the table. If commands are supported, // it builds insert SQL statement and executes if requested. // If commands are not supported, IRowsetNewRow is used to insert data, // but only if fExecute = TRUE. // Default behavior is to insert the next row. // Inserts 1 row into the table. If ulRowNumber == 0 then ulRowNumber // == m_ulNextRow. Rownumbers start at 0 in the private library, regardless // of how they are treated in the Data Source. // ppwszInsert should look like "Insert into table (col1,...) values (x, ...)". // Client must IMalloc->Free(pwszInsert) if not passed as NULL. // If pwszSelect == NULL, client doesn't want statement returned. HRESULT Insert( DBCOUNTITEM ulRowNumber=0, // [IN] Row number to insert (Default = Next row) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data (Default=PRIMARY) BOOL fExecute=TRUE, // [IN] True indicates execute statement (Default=TRUE) WCHAR ** pwszInsert=NULL,// [OUT] SQL statement generated. NULL is returned in commands aren't supported (Default=NULL) BOOL fNULL=FALSE, // [IN] TRUE indicates that NULL values will be inserted whenever possible DBCOUNTITEM cRowsToInsert = 1 ); // @cmember Inserts using IRowsetChange::InsertRow HRESULT Insert( EVALUE eValue, // [IN] Initial or second value of data DBCOUNTITEM ulRowNumber, // [IN] Row number to insert DBCOUNTITEM cRowsToInsert = 1 // [IN] number of rows to insert ); // @cmember Inserts a row into the table using commands with a literal insert statements. // the values specified by user. HRESULT InsertWithUserLiterals( DBORDINAL cCols, // [IN] number of values to insert DBORDINAL *pulColOrdinals, // [IN] array of column ordinals WCHAR **pwszLiterals // [IN] values to insert ); // @cmember Inserts a row into the table with parameters. This function will only // work when commands are supported. it builds the sql statements and executes if // requested. // pwszInsert should look like "Insert into table (col1, ...) values (?, ...); HRESULT InsertWithParams( DBCOUNTITEM ulRowNumber=0, // [IN] Row number to insert (Default = Next row) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data (Default=PRIMARY) BOOL fExecute=TRUE, // [IN] True indicates execute statement (Default=TRUE) WCHAR ** pwszInsert=NULL, // [OUT] SQL statement generated. NULL is returned in commands aren't supported (Default=NULL) DBCOUNTITEM cRowsToInsert = 1 ); // @cmember Builds an update statement on table, executes if requested. // Default behavior is to delete the last row inserted. // Client must IMalloc->Free(pwszUpdate). // Updates 1 row in table. Client must have at least one column marked // or an error will occur. eValue is the type of MakeData data you are going to // update the column to (the end result). // If pwszSelect == NULL, client doesn't want statement returned. HRESULT Update( DBCOUNTITEM ulRowNumber=0, // [IN] Row number to update (Default=last row inserted into table) EVALUE eValue=SECONDARY, // [IN] Kind of new value to set (Default=SECONDARY) BOOL fExecute=TRUE, // [IN] True indicates execute statement (Default=TRUE) WCHAR ** pwszUpdate=NULL, // [OUT] SQL statement generated (Default=NULL) BOOL fSameWhereValuesAsSet = FALSE, // [IN] Whether to look for same value in where clause which is used in // set clause and thus basically perform an update which doesn't // change anything for the given row. (Default = FALSE, meaning // the opposite of eValue will be used to generate the where clause, // and thus the updated row will show a new value.) DBCOUNTITEM ulWhereRowNumber=0 // [IN] if not 0 then update table set ulRowNumber where ulWhereRowNumber ); // @cmember Builds a delete statement on table, executes if requested. // Default behavior deletes all rows in table. // Client must IMalloc->Free(pwszSelect). // Deletes 1 row or all rows. If pstrSelect is NULL, client will not // be returned the sql text of the delete statement. eValue is the current // value of the data to be deleted. // If pwszSelect == NULL, client doesn't want statement returned. HRESULT Delete( DBCOUNTITEM ulRowNumber=ALLROWS,// [IN] Row number to update (Default=ALLROWS) EVALUE eValue=PRIMARY, // [IN] Initial or second value of data (Default=PRIMARY) BOOL fExecute=TRUE, // [IN] True indicates execute statement (Default=TRUE) WCHAR ** pwszSelect=NULL // [OUT] SQL statement generated (Default=NULL) ); // @cmember Creates a SQL statement from one of the predefined statements // and then executes that statement, Client must free any memory returned. // If the client doesn't pass in a Command pointer for this function to // work from, the private library has one it will use. // Options include: // (1)If the statement is a join that requires a second table, the second // table name must be passed in. // (2)Not executing statement, this would be interested when you want // other information returned such as the sql statement. // (3)Properties can be set and the errors associated with those properties // can be returned. // (4) The following must be IMalloc->Freed if passed in as valid addresses: // ppwszStatement,prgColumns,prgPropertyErrors,prgpRowset. // Client must release the following objects: // - If pICommand is not null user must release this // Client must free the following memory: // - If prgPropertyErrors is not null user must free this // - If pcRowset is zero then user must free prgpRowset // - ppwszStatement // - prgColumns // // This function takes a mandatory SQL statement. HRESULT ExecuteCommand( EQUERY eSQLStmt, // [IN] SQL statement to create REFIID riid, // [IN] Interface pointer to return WCHAR * pwszTableName=NULL, // [IN] Second TableName WCHAR ** ppwszStatement=NULL, // [OUT] SQL statement generated DBORDINAL * pcColumns=NULL, // [OUT] Count of columns DB_LORDINAL ** prgColumns=NULL, // [OUT] Array of column numbers EEXECUTE eExecute=EXECUTE_IFNOERROR,// [IN] TRUE = execute SQL Statement ULONG cPropSets=0, // [IN] Count of property sets. DBPROPSET rgPropSets[]=NULL, // [IN] Array of DBPROPSET structures. DBROWCOUNT * pcRowsAffected=NULL, // [OUT] Pointer to memory in which to return the count // of rows affected by a command that updates, deletes, // or inserts rows. IUnknown ** ppRowset=NULL, // [IN/OUT] Pointer to the rowset pointer. ICommand ** ppICommand=NULL // [IN/OUT] If ppICommand == NULL, this function uses // its own command object and then frees it, caller does nothing. // // If *ppICommand is not null, this value is used as the // ICommand interface for all command operations in this function. // Caller maintains responsiblity to release this interface. // // If *ppICommand is null, this function creates a new command object // and places the ICommand interface to this object in *ppICommand. // Caller assumes responsibility to release this interface. ); // @cmember Creates a Rowset HRESULT CreateRowset( EQUERY eQuery, // [IN] Query to create REFIID riid, // [IN] Interface pointer to return ULONG cPropSets=0, // [IN] Count of property sets. DBPROPSET* rgPropSets = NULL, // [IN] Array of DBPROPSET structures. IUnknown ** ppRowset = NULL, // [OUT] Pointer to the rowset pointer. DBID* pTableID = NULL, // {IN] TableID if needed (IOpenRowset) DBORDINAL * pcColumns = NULL, // [OUT] Count of columns DB_LORDINAL ** prgColumns = NULL, // [OUT] Array of column numbers ULONG cRestrictions = 0, // [IN] cRestrictions VARIANT* rgRestrictions = NULL, // [IN] rgRestrictions IOpenRowset* pIOpenRowset = NULL // [IN] pIOpenRowset ); // @cmember Sets properties on a command object and executes the sql statement // Client must release and/or free any object and/or memory returned; // If the client doesn't pass in a Command pointer for this function to // work from, the private library has one it will use. // Options include: // (1)If the statement is a join that requires a second table, the second // table name must be passed in. // (2)Not executing statement, this would be interested when you want // other information returned such as the sql statement. // (3)Properties can be set and the errors associated with those properties // can be returned. // (4) Parameters can be set. // (5) The following must be IMalloc->Freed if passed in as valid addresses: // ppwszStatement,prgPropertyErrors,prgpRowset. // Client must release the following objects: // - If pICommand is not null user must release this // Client must free the following memory: // - If prgPropertyErrors is not null user must free this // - If pcRowset is zero then user must free prgpRowset // // This function takes a mandatory SQL statement. // This function will create a command object, set any properties passed in, // set the SQL statement, and execute the statement if fExecute = TRUE; // The user has the option of setting parameters, retrieving the count of // rowsets, retrieving the array of rowsets, retrieving the interface pointer // specified in the REFIID, and retrieving the command object. HRESULT BuildCommand( LPCWSTR pwszCommand, // [IN] SQL Statement to set REFIID riid, // [IN] Interface pointer to return EEXECUTE eExecute = EXECUTE_IFNOERROR, // [IN] When to execute the SQL Statement ULONG cPropSets=0, // [IN] Count of property sets. DBPROPSET rgPropSets[]=NULL, // [IN] Array of DBPROPSET structures. DBPARAMS * pParams=NULL, // [IN] Parameters to pass to ::Execute DBROWCOUNT * pcRowsAffected=NULL, // [OUT] Pointer to memory in which to return the count // of rows affected by a command that updates, deletes, // or inserts rows. IUnknown ** ppRowset=NULL, // [IN/OUT] Pointer to the rowset pointer. ICommand ** ppICommand=NULL, // [IN/OUT] If ppICommand == NULL, this function uses // its own command object and then frees it, caller does nothing. // // If *ppICommand is not null, this value is used as the // ICommand interface for all command operations in this function. // Caller maintains responsiblity to release this interface. // // If *ppICommand is null, this function creates a new command object // and places the ICommand interface to this object in *ppICommand. // Caller assumes responsibility to release this interface. IUnknown* pIUnkOuter = NULL // @parm [IN] Aggregate ); // @cmember Creates a SQL statement from one of the predefined statements // Client must free ppwszStatement and prgColumns. // This function takes a one of the enum SQL Statements and creates the // SQL statement with the columns and the CTable. The statement is then // passed back to the user along with an array of column numbers in the // order they will come back in the result set. HRESULT CreateSQLStmt( EQUERY eSQLStmt, // [IN] SQL statement to create WCHAR * pwszTableName, // [IN] Second TableName WCHAR ** ppwszStatement, // [OUT] SQL statement generated DBORDINAL * pcColumns=NULL, // [OUT] Count of columns (Default = NULL) DB_LORDINAL ** prgColumns=NULL,// [OUT] Array of column numbers (Default = NULL) DBCOUNTITEM ulRowNumber = 1,// [IN] Row number to use CTable * pTable2 = NULL, // [IN] Second table object to use DBORDINAL iOrdinal = 0 // [IN] Col number to use, default 0 (all) ); // @cmember Creates a list from the Ctable // Client must free ppwszList, prgColumns. // This function creates a list from the CTable. The list // will be comma seperated. This function also returns an array of // column numbers. HRESULT CreateList( ELIST_TYPE eListType, // @parm [IN] Type of list to create LPWSTR * ppwszList, // @parm [OUT] List generated DBORDINAL * pcColumns = NULL, // @parm [IN/OUT] In: Maximum number of columns that can be // in the Column array. Ignored if *prgColumns==NULL. // Out: Actual number of columns in finished array. DB_LORDINAL ** pprgColumns = NULL, // @parm [IN/OUT] Array of column numbers, memory is allocated for caller // if *pprgColumns == NULL, else it is assums the array is *pcColumns // allocated by caller to hold all column numbers and the first column // is a constant column such as 'ABC'. ECOLS_IN_LIST eColsInList = ALL_COLS_IN_LIST, // @parm [IN] Type of columns in list (Default = ALL_COLS_IN_LIST) ECOLUMNORDER eColOrder = FORWARD, // @parm [IN] Column list order, default FORWARD EVALUE eValue = PRIMARY, // @parm [IN] Type of makedata (Default = PRIMARY) DBCOUNTITEM ulRowNum = 1, // @parm [IN] Row number to use for literals, default 1 LPWSTR ** pprgColumnNames = NULL, // @parm[OUT] Column names, if null are not returned, (Default = NULL) // Client must release each string and array of strings DBORDINAL * prgColumns = NULL // @parm [IN] On input specifies desired columns, // over-riding eColsInList. Default NULL. ); // @cmember Creates a column list from the Ctable // Client must free ppwszColList, prgColumns. // This function creates a column list from the CTable. The column list // will be comma seperated. This function also returns an array of // column numbers. HRESULT CreateColList( ECOLUMNORDER eColOrder, // [IN] Column list order, default FORWARD WCHAR ** ppwszColList, // [OUT] Column list generated DBORDINAL * pcColumns, // [OUT] Count of columns DB_LORDINAL ** prgColumns, // [OUT] Array of column numbers ECOLS_IN_LIST eColsInList = ALL_COLS_IN_LIST,// [IN] Indicates which columns are included in list BOOL fAddParams=FALSE, // [IN] TRUE if parameterized search criteria // is added for each searchable column BOOL fAddData=FALSE, // [IN] TRUE if data search criteria is // added for each searchable column WCHAR *** prgColumnNames=NULL,// [OUT] Column names, if null are not returned EVALUE eValue=PRIMARY, // [IN] Type of makedata (Default = PRIMARY) DBCOUNTITEM ulRowNumber = 1, // [IN] Row number to use DBORDINAL iOrdinal = 0 // [IN] Col number to use, default 0 (all) ); // @cmember Returns the columns in the query in query order and the // base table ordinal value it cooresponds to. // // Since there is at least 1 EQUERY that encapsulates 2 select // statements, there will be a need to check pXX1 and pXX2. // // Client is responsible for releasing memory.The actual strings in the array of // column names is NOT to be released. The owner of the strings is CTable, // and the CTable::DropTable() function will release that memory. BOOL CTable::GetQueryInfo ( EQUERY sqlStmt, // [in] SQL statement DBORDINAL * pcColumns1, // [out] 1.Count of columns DB_LORDINAL** prgColumns1, // [out] 1.Array of Column Ordinals WCHAR *** prgColumnNames1, // [out] 1.Column names DBORDINAL * pcColumns2, // [out] 2.Count of columns DB_LORDINAL** prgColumns2, // [out] 2.Array of Column ordinals WCHAR *** prgColumnNames2 // [out] 2.Column names ); // @cmember Sets the member variables for a pre-existing table. HRESULT SetExistingTable(WCHAR * pwszTableName = NULL); // [IN] Name of table, cannot be empty // @cmember Sets table name if table name is currently NULL, // else returns EFAIL.Can return E_OUTOFMEMORY. HRESULT SetTableName(WCHAR * pTableName); // @cmember Retrieves a correctly quoted Name // Even handles correctly quoting qualified names... HRESULT GetQuotedName(WCHAR* pwszName, WCHAR** ppwszQuoted, BOOL fFromCatalog = FALSE); HRESULT GetQualifiedName(WCHAR* pwszCatalogName, WCHAR* pwszSchemaName, WCHAR* pwszTableName, WCHAR** ppwszQualifiedName, BOOL fFromCatalog = FALSE); // @cmember Retrieves LiteralInfo for the requested LITERAL DBLITERALINFO* GetLiteralInfo(DBLITERAL dwliteral); // @cmember Sets view name if view name is currently NULL, // else returns EFAIL.Can return E_OUTOFMEMORY. HRESULT SetViewName(WCHAR * pViewName); // @cmember Sets which columns are used as search criteria // in Select,Insert,Update,and Delete. HRESULT SetColsUsed(CList & rColNumList ); // [IN] Sets ccol.m_fUseInSQL // @cmember Drops this table (which also drops index) from backend database. HRESULT DropTable(BOOL fDropAlways = FALSE); // @cmember Drops this table (which also drops index) from backend database. HRESULT DropTable(DBID*); // @cmember Drops the view on this table from backend database. HRESULT DropView(void); // @cmember Drops index on table. HRESULT DropIndex(void); // @cmember,mfunc Adds 1 to row count, should be called after insert is executed // on this table outside of class. // @@parm [IN] Number of rows to add to count (Default = 1) void AddRow(DBCOUNTITEM ulRow=1){m_ulRows += ulRow; m_ulNextRow += ulRow;}; // @cmember,mfunc Removes 1 from row count, should be called after delete // is executed on this table outside of class. // @@parm [IN] Number of rows to substract from count (Default = 1) void SubtractRow(DBCOUNTITEM ulRow=1){if(m_ulRows>0) m_ulRows -= ulRow; if(m_ulNextRow>0) m_ulNextRow -= ulRow;}; //Add a Column to the list HRESULT AddColumn(CCol& rCol); //Remove a Column from the table HRESULT DropColumn(CCol& rCol); //Remove a Column from the table; the column is given by its ordinal position HRESULT DropColumn(DBORDINAL nOrdinalPos); // @cmember Turn m_ColList.fUseInSQL to TRUE/FALSE // [IN] Sets(TRUE) or clears(FALSE) ccol.m_fUseInSQL (Default=FALSE). // TRUE means use every column in the where clause. // FALSE means do not use any columns in where clause. HRESULT AllColumnsForUse( BOOL fValue=FALSE ); // @cmember Number of rows in base table. This function executes a "select * from" and // then counts all the rows on the table. // Zero is returned if there was an error. // Counts the rows in the table by seeing how many GetRows it // goes thru. Yes, this is expensive for large databases. If table name // is not set, return E_FAIL. Alloc (pwszSQLText). DBCOUNTITEM CountRowsOnTable(IRowset *pIRowset=NULL); // @cmember Number of rows in CTable object. Returns m_ulRows. DBCOUNTITEM GetRowsOnCTable(void){return m_ulRows;}; // @cmember Number of columns in CTable. // Zero is returned if there was an error. DBORDINAL CountColumnsOnTable(void); // @cmember,mfunc Returns TableName, client should not alter pointer. WCHAR * GetTableName(void){return m_TableID.uName.pwszName;}; // @cmember,mfunc Returns ViewName, client should not alter pointer. WCHAR * GetViewName(void){return m_pwszViewName;}; // @cmember,mfunc Returns TableID DBID GetTableID(void){return m_TableID;}; // @cmember,mfunc Returns the reference of TableID DBID& GetTableIDRef(void){return m_TableID;}; // @cmember,mfunc Sets TableID void SetTableID(DBID d); // @cmember,mfunc Returns m_fHasAuto BOOL GetHasAuto(void){ return m_fHasAuto;} // @cmember,mfunc Sets m_fHasAuto void SetHasAuto(BOOL b){m_fHasAuto = b;} // @cmember,mfunc Returns m_fHasAuto BOOL GetHasUnique(void){ return m_fHasUnique;} // @cmember,mfunc Sets m_fHasAuto void SetHasUnique(BOOL b){m_fHasUnique = b;} // @cmember,mfunc Returns m_fHasAuto BOOL GetHasCLSID(void){ return m_fHasCLSID;} // @cmember,mfunc Sets m_fHasAuto void SetHasCLSID(BOOL b){m_fHasCLSID = b;} // @cmember,mfunc Returns m_fHasDefault BOOL GetHasDefault(void){ return m_fHasDefault;} // @cmember,mfunc Sets m_fHasDeffault void SetHasDefault(BOOL b){m_fHasDefault = b;} // @cmember,mfunc Returns IndexName, client should not alter pointer. WCHAR * GetIndexName(void){return m_pwszIndexName;} // @cmember,mfunc Returns Module Name, client should not alter pointer. WCHAR * GetModuleName(void); // @cmember,mfunc Returns next row number for insert statement. DBCOUNTITEM GetNextRowNumber(void){return m_ulNextRow;} // @cmember Flag telling if Commands are supported on the CTable object. BOOL GetCommandSupOnCTable(void) { return m_pIDBCreateCommand!=NULL; } // @cmember,mfunc Sets I4 for SQL support, m_lSQLSupport. // @@parmopt [IN] SQL Support (Default = 0) void SetSQLSupport(LONG_PTR lSQLSupport=0) {m_lSQLSupport=lSQLSupport;} // @cmember,mfunc Returns I4 for SQL support, m_lSQLSupport. LONG_PTR GetSQLSupport(void){return m_lSQLSupport;} // @cmember Flag telling if the Provider is ReadOnly. BOOL GetIsProviderReadOnly(void){return m_fProviderReadOnly;} // @cmember Gets the columns to be used as search criteria in // Select,Insert,Update,and Delete. Information on how to // traverse the returned structure can be found in the MFC // reference on CList. HRESULT GetColsUsed( CList & rColNumList // [OUT] Gets ccol.m_fUseInSQLs ); HRESULT SetExistingCols( CList &InColList ); // @cmember delete without using commands HRESULT DeleteRows( DBCOUNTITEM ulRowNumber=ALLROWS // @parm [IN] row # to pass (Default = ALLROWS) ); // @cmember Sets m_pUnkOuter IUnknown *SetUnkOuter(IUnknown *pUnkOuter = NULL) { return m_pUnkOuter = pUnkOuter; } // @cmember Gets m_pUnkOuter IUnknown *GetUnkOuter(void) { return m_pUnkOuter; } // @cmember Sets the reference to the required rowset reference (for ITableDefinition) IID *SetRIID(IID* riid = (struct _GUID*)&IID_IRowset) { return m_riid = riid; } // @cmember Gets the reference to the required rowset reference (for ITableDefinition) IID *GetRIID(void) { return m_riid; } // @cmember Sets the property sets DBPROPSET *SetPropertySets( DBPROPSET *rgPropertySets = NULL, ULONG cPropSets = 0 ); // @cmember Gets the property sets to be set or set by ITableDefinition::CreateTable DBPROPSET *GetPropertySets(void) { return m_rgPropertySets; } // @cmember Sets the number of property sets for ITableDefinition::CreateTable ULONG SetNoOfPropertySets(ULONG cPropertySets = 0) { return m_cPropertySets = cPropertySets; } // @cmember Gets the number of property sets ULONG GetNoOfPropertySets(void) { return m_cPropertySets; } // @cmember Sets the column description array DBCOLUMNDESC *SetColumnDesc(DBCOLUMNDESC *rgColumnDesc = NULL); // @cmember Sets the column description array DBCOLUMNDESC *SetColumnDesc(DBCOLUMNDESC *rgColumnDesc, DBORDINAL cColumnDesc); // @cmember Gets the property sets to be set or set by ITableDefinition::CreateTable DBCOLUMNDESC *GetColumnDesc(void) { return m_rgColumnDesc; } // @cmember Sets the number of column descriptors for ITableDefinition::CreateTable DBORDINAL SetNoOfColumnDesc(DBORDINAL cColumnDesc = 0) { return m_cColumnDesc = cColumnDesc; } // @cmember Use &m_TableID as input TableID in ITableDefinition::CreateTable BOOL SetInputTableID(void) { return m_fInputTableID = TRUE;} // @cmember Use NULL as input TableID in ITableDefinition::CreateTable BOOL ResetInputTableID(void) { return m_fInputTableID = FALSE;} // @cmember Get m_fInputTableID BOOL GetInputTableID(void) { return m_fInputTableID;} // @cmember SetBuildColumnDesc BOOL SetBuildColumnDesc(BOOL v) { return m_fBuildColumnDesc = v;} // @cmember GetBuildColumnDesc BOOL GetBuildColumnDesc(void) { return m_fBuildColumnDesc; } // @cmember Sets pointer to the return table DBID (in ITableDefinition::CreateTable) DBID **SetDBID(DBID **ppTableID = NULL); // @cmember Gets pointer to the return table DBID created by ITableDefinition::CreateTable DBID **GetDBID(void); // @cmember Sets pointer to the rowset interface to be created by ITableDefinition::CreateTable IUnknown **SetRowset(IUnknown **ppRowset = NULL); // @cmember Gets the pointer to the rowset interface created by ITableDefinition::CreateTable IUnknown **GetRowset(void); // @cmember Gets the column properties that could be read ULONG GetColProps(void){ return m_fColProps; } // @cmember Duplicate the column list, it's user responsability to free it CList &DuplicateColList(CList &ColList); // @cmember Set the column list CList &SetColList(CList &ColList); // @cmember Creates initial list of types,initializes m_ColList with columns of // specified types. HRESULT CreateColInfo( CList& rProviderTypesNameList, // [OUT] CList of WCHAR * of ProviderTypeNames CList& rProviderTypesList, // [OUT] CList of DBTYPE of ProviderTypes EDATATYPES eDataTypes=ALLTYPES, // [IN] Data types (Default = ALLTYPES) BOOL fFirstUpdateable = FALSE // [IN] TRUE means first column will not be autoinc (Default=FALSE) ); // @cmember Creates initial list of types,initializes m_ColList with columns of // specified types. HRESULT CreateTypeColInfo( CList& rProviderTypesNameList, // [OUT] CList of WCHAR * of ProviderTypeNames CList& rProviderTypesList, // [OUT] CList of DBTYPE of ProviderTypes EDATATYPES eDataTypes=ALLTYPES, // [IN] Data types (Default = ALLTYPES) ULONG *pulAutoIncPrec=NULL // [OUT] Precision of largest Auto Inc column (optional) ); // @cmember Checks columns for Updatability. Used in the createtable functions. HRESULT MayWrite( BOOL * fMayWrite=NULL // [OUT] Is Column Writeable (Default=NULL). ); // @cmember Returns first numeric (4 byte or larger) column HRESULT GetFirstNumericCol(CCol * pCCol); // @cmember returns list of not nullable columns HRESULT CTable::GetNullableCols (WCHAR **prgColName); // @cmember Builds a variant which can represent the default value of a type BOOL BuildDefaultValue(CCol& col, DBCOUNTITEM cRow, VARIANT *vDefault = NULL); // @cmember Sets the default value of a column BOOL SetDefaultValue(CCol& col, DBCOUNTITEM cRow); // @cmember Sets the has default value of a column BOOL SetHasDefaultValue(CCol& col, BOOL fHasDefaultValue); // @cmember Gets a column that satisfies several criteria BOOL GetColWithAttr(ULONG cCond, ULONG *rgCond, DBORDINAL *pcSelectedColumn); BOOL GetColWithAttr(ULONG ulCond, DBORDINAL *pcSelectedColumn) { return GetColWithAttr(1, &ulCond, pcSelectedColumn); } // @cmember get the order by column HRESULT GetOrderByCol( CCol * pCCol // @parm [in/out] Pointer to CCol object to copy ); // @access Private private: // @cmember All functionality common to 3 CreateTable functions. // Called from one of the overloaded CreateTable functions.Passing zero // for ulIndex means do not but an Index on this table. eValue means // to create table with eValue kind of data. // // 1) Get Table Name // 2) Get Datatypes from Datasource // 3) Determine if we'll use command with SQL or ITableDefinition // 4) If using command, build sql/execute string for creating table // 5) Create Table // 4) Create Index, if requested // 5) Fill table with rows, if requested // // create table SQL statement looks like: // "create table (col1 type,col2 type)" HRESULT QCreateTable( DBCOUNTITEM ulRowCount, // [IN] # of Rows to insert into table, 1 based DBORDINAL ulIndex, // [IN] Column Number of index, 1 based EVALUE eValue // [IN] Type of data to insert ); // @cmember Returns System Time. Used to create table name. // Client must IMalloc->Free returned string. WCHAR * GetTime(void); public: // @cmember Checks if Table currently exists based on a tablename search. // Make sure table is in Data Source, E_FAIL if table name is empty. // If table is found set fExists to true. If function runs correctly // but doesn't find the table name, function will return NOERROR, but fExists // will be FALSE. HRESULT DoesTableExist( WCHAR * pwszTableName=NULL, // [IN] Table name to check for (Default=NULL) BOOL * fExists=NULL // [OUT] TRUE if table is found (Default=NULL) ); // @cmember Checks if Table currently exists based on a tablename search. // Make sure table is in Data Source, E_FAIL if table name is empty. // If table is found set fExists to true. If function runs correctly // but doesn't find the table name, function will return NOERROR, but fExists // will be FALSE. HRESULT DoesTableExist( DBID * pTableID=NULL, // [IN] Pointer to Table DBID to check for (Default=NULL) BOOL * fExists=NULL // [OUT] TRUE if table is found (Default=NULL) ); public: // @cmember Checks if Index currently exists based on indexname search. // If this index is on this table return true and fill in // strIndexName and udwIndex, set fExists to true. If function runs correctly // but doesn't find the table name, function will return NOERROR, but fExists // will be FALSE. If strIndexName is empty, returns E_FAIL. Assumes table // will have only 1 index. HRESULT DoesIndexExist( BOOL * fExists=NULL // [OUT] TRUE if index exists (Default=NULL) ); // @cmember Used in Select to get literal prefix, makedata, and literal suffix // Client must IMalloc->Free((*ppwszData)). HRESULT GetLiteralAndValue( CCol & col, // [IN] Col to grab prefix and suffix from WCHAR ** ppwszData=NULL, // [OUT] Prefix, data, suffix like 'zbc' or #222 (Default=NULL) DBCOUNTITEM ulRow=1, // [IN] Row number to pass to MakeData (Default=1) DBORDINAL ulColNum=1, // [IN] Column number to pass to MakeData (Default=1) EVALUE eValue=PRIMARY, // [IN] PRIMARY or SECONDARY data (Default=PRIMARY) BOOL fColData=FALSE // [IN] Whether to use col to make the data (Default = FALSE) ); // @cmember FormatVariantLiteral // Formats a variant literal using ODBC canonical convert functions HRESULT CTable::FormatVariantLiteral ( DBTYPE wVariantType, // [IN] variant sub type WCHAR * pwszData, // [IN] input data WCHAR ** ppwszData // [OUT] formatted data ); // @cmember Generates Table Name // Looks like "MODULENAME_DATE_RANDOMNUMBER" example "persist_950101_9563". HRESULT MakeTableName(WCHAR* pwszTableName); // @cmember Fill m_ColList with information about current table HRESULT SetTableColumnInfo( WCHAR * pwszTableName = NULL, // [IN] Table Name IUnknown *pIRowset=NULL // [IN] Rowset from command ); // @cmember Fill m_ColList with information about current table HRESULT GetTableColumnInfo( DBID * pTableID, // [IN] Table ID IUnknown *pIRowset=NULL // [IN] Rowset from command ); // @cmember Builds m_ColList from information in rgColumnDesc BOOL ColumnDesc2ColList( DBCOLUMNDESC *rgColumnDesc, // [IN] An array of ColumnDesc build from m_ColList DBORDINAL cColumnDesc // [IN] the number of elements in the array ); // @cmember Fill m_ColList with information about current table BOOL ColList2ColumnDesc( DBCOLUMNDESC **rgColumnDesc, // [OUT] An array of ColumnDesc build from m_ColList DBORDINAL *cColumnDesc = NULL // [OUT] the number of elements in the array ); // @cmember Puts the elements of CCol in m_ColList. HRESULT GetFromColumnsRowset( IColumnsRowset * pIColumnsRowset, // [IN] IColumnsRowset pointer DBORDINAL * cColsFound=NULL // [OUT] Total number of columns found (Default=NULL) ); // @cmember Updates elements in m_ColList based on values read from column schema rowset HRESULT AddInfoFromColumnsSchemaRowset( IUnknown *pIUnknown, // [IN] session interface WCHAR *pwszTableName = NULL, // [IN] table name (if null go for current table) DBCOUNTITEM *cColsFound = NULL // [OUT] Total number of columns found (Default=NULL) ); private: // @cmember Puts the elements of CCol in m_ColList. HRESULT SetFromIDBSCHEMATypes( DBORDINAL * cColsFound=NULL // [OUT] Total number of columns found (Default=NULL) ); // @cmember Puts the elements of CCol in m_ColList. HRESULT SetFromIDBSCHEMAColumns( DBORDINAL * cColsFound=NULL // [OUT] Total number of columns found (Default=NULL) ); // @cmember Setups up cache for LiteralInfo HRESULT SetupLiteralInfo(); // @cmember Sets the corresponding member function. HRESULT SetModuleName( WCHAR * pwszModuleName=NULL // [IN] Test Case Module Name (Default=NULL) ); // @cmember Sets the column description array BOOL IsCompatibleType( DBCOUNTITEM cBindings, DBBINDING* rgBindings, void* pData, CCol & rCol // @parm [IN] Element from the CCol List ); // @cmember Creates DBPARAMBINDINFO and rgParamOrdinal array given desired // bindings, column ordinals. User must free pParamOrdinals, pParamBindInfo. HRESULT GetDBPARAMBINDINFO( DBCOUNTITEM cBindings, DBBINDING* rgBindings, DB_LORDINAL * rgColOrds, DB_UPARAMS ** ppParamOrdinals, DBPARAMBINDINFO ** ppParamBindInfo ); }; #endif // _CTable_