// CRecordset.h: interface for the CConnection class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CONNECTION_H__FF5ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_) #define AFX_CONNECTION_H__FF5ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CServerConnection; namespace scdriver { // forward declaration class CRecordset; class CCommand; /************************************** * * enum: D A T A _ T Y P E * ************************************** * * Functional description * * data types of the field **************************************/ enum DATA_TYPE { DB_TINYINT = 2, DB_SMALLINT = 2, DB_INT = 3, DB_BIGINT = 32769, DB_UNIQUEIDENTIFIER = 32768, DB_DOUBLE = 5, DB_FLOAT = 4, DB_DATETIME = 7, DB_CHAR = 8, DB_VARCHAR = 8, DB_TEXT = 32770, DB_NCHAR = 25, DB_NVARCHAR = 25, DB_NTEXT = 32772, DB_BLOB = 32771, DB_GUID = 72, DB_NULL = 1, DB_DECIMAL = 2048, // decimal data type DB_BIT = 102, }; #ifdef DELPHI class CAbstractFieldStream { public: virtual int __stdcall GetFieldSize() const = 0; virtual bool __stdcall IsNull() const = 0; virtual bool __stdcall ReadField(void *data, int *size) = 0; }; #endif /************************************** * * class: C F i e l d S t r e a m * ************************************** * * Functional description * * Interface for reading column's value **************************************/ #ifdef DELPHI class CFieldStream : public CAbstractFieldStream #else class __declspec( dllexport ) CFieldStream #endif { public: CFieldStream(); virtual ~CFieldStream(); /************************************** * * function: G e t F i e l d S i z e * ************************************** * * Functional description * * return number of bytes of the content of the column's data * NOTE: for the BLOB type columns it will return bigger size * of the BLOB than actual. * The function is especially usefull to read BLOB's data in a single * ReadField() call. **************************************/ #ifdef DELPHI int __stdcall GetFieldSize() const; #else int GetFieldSize()const; #endif /************************************** * * function: I s N u l l * ************************************** * * Functional description * * return TRUE if column is null, otherwise - FALSE **************************************/ #ifdef DELPHI bool __stdcall IsNull() const; #else bool IsNull(); #endif /************************************** * * function: R e a d F i e l d * ************************************** * * Functional description * * fill ouput buffer with the data column's data * parameters: * [in] data - buffer to write column's content * [in,out] size - [in] max buffer's size, [out] - number of bytes readed * return: * false - more data to read left * true - all content of the column has been read **************************************/ #ifdef DELPHI bool __stdcall ReadField(void *data, int *size); #else bool ReadField(void *data, int *size); #endif protected: friend class CRecordset; void SetField(const int &_type, void *data); private: CConnection *m_conn; DATA_TYPE m_type; byte *m_data; byte *m_blob; long m_ichunk; long m_chunks; int m_isize; int m_size; }; /************************************** * * struct: F I E L D _ I N F O * ************************************** * * Functional description * * detailed information of the column int the output row **************************************/ struct FIELD_INFO { char name[128]; int id; DATA_TYPE type; unsigned char m_prec; // DECIMAL precision unsigned char m_scale; // DECIMAL fraction byte vtype; // visibility mask. Used to gennerate SQL for update/delete/insert when modifyning recordset in DB grid // 0 - normal column (show always), // 4 - RID (columns belong to row ID or primary key), show always // 6 - RID column, hide from output unsigned __int64 table_id; // unique table_id the column belongs to: select table_id from system.systables CFieldStream data; bool operator() (const char *f1,const char *f2) const { return stricmp(f1,f2) < 0; }; }; #ifdef DELPHI class CAbstractRecordset { public: virtual void __stdcall Open(CConnection *conn, const char *cmd) = 0; virtual void __stdcall Next() = 0; virtual int __stdcall GetFieldCount() const = 0; virtual FIELD_INFO* __stdcall GetFieldInfoByIndex(const int iCol) = 0; virtual FIELD_INFO* __stdcall GetFieldInfoByName(const char *name) = 0; virtual CFieldStream* __stdcall GetFieldStreamByIndex(const int iCol) = 0; virtual CFieldStream* __stdcall GetFieldStreamByName(const char *name) = 0; virtual bool __stdcall IsEOF() const = 0; virtual void __stdcall Free() = 0; }; extern "C" CAbstractRecordset* __stdcall NewRecordset(); #endif /************************************** * * class: C R e c o r d s e t * ************************************** * * Functional description * * manage recordsets. single threaded **************************************/ #ifdef DELPHI class CRecordset : public CAbstractRecordset #else class __declspec( dllexport ) CRecordset #endif { public: CRecordset(); virtual ~CRecordset(); /************************************** * * function: g e t _ c a l l _ s i z e * ************************************** * * Functional description * * return the size of the class **************************************/ static int get_class_size(); /************************************** * * function: O p e n * ************************************** * * Functional description * * execute SQL/DQL statement and receive status * (has output, columns schema & rows) **************************************/ #ifdef DELPHI void __stdcall Open(CConnection *conn, const char *cmd); #else void Open(CConnection *conn, const char *cmd); #endif /************************************** * * function: N e x t * ************************************** * * Functional description * Move to the next row in the recordset **************************************/ #ifdef DELPHI void __stdcall Next(); #else void Next(); #endif /************************************** * * function: G e t F i e l d C o u n t * ************************************** * * Functional description * Return number of columns in the output row(s) **************************************/ #ifdef DELPHI int __stdcall GetFieldCount() const; #else int GetFieldCount(); #endif /************************************** * * function: G e t V i s i b l e F i e l d C o u n t * ************************************** * * Functional description * Return number of visible columns **************************************/ int GetVisibleFieldCount(); /************************************** * * function: G e t F i e l d I n f o * ************************************** * * Functional description * Get field's info structure by the its * position in the row [0,nFields[ **************************************/ #ifdef DELPHI FIELD_INFO* __stdcall GetFieldInfoByIndex(const int iCol); CFieldStream* __stdcall GetFieldStreamByIndex(const int iCol); #else FIELD_INFO *GetFieldInfo(const int iCol); #endif /************************************** * * function: G e t F i e l d I n f o * ************************************** * * Functional description * Get field's info structure by the its * name **************************************/ #ifdef DELPHI FIELD_INFO* __stdcall GetFieldInfoByName(const char *name); CFieldStream* __stdcall GetFieldStreamByName(const char *name); #else FIELD_INFO *GetFieldInfo(const char *name); #endif /************************************** * * function: E O F * ************************************** * * Functional description * * return TRUE if end of recordset reached **************************************/ #ifdef DELPHI bool __stdcall IsEOF(); #else bool IsEOF(); #endif #ifdef DELPHI void __stdcall Free(); #endif /************************************** * * function: O p e n * ************************************** * * Functional description * * execute SQL/DQL inside server (for UDI procedures) **************************************/ void Open(CServerConnection *conn, const char *cmd); /************************************** * * function: G e t S c h e m a I n f o * ************************************** * * Functional description * * set the number of rows affected by insert/update/delete * and if select statement can update rows **************************************/ void GetSchemaInfo(int *_recodset, unsigned __int64 *_affected_row, bool *_allow_add, bool *_allow_edit,bool *_allow_delete) { *_recodset = m_recordset; *_affected_row = m_affected_row; *_allow_add = m_allow_add; *_allow_edit = m_allow_edit; *_allow_delete = m_allow_delete; }; protected: /************************************** * * function: r e a d _ s c h e m a * ************************************** * * Functional description * called then query has completed to read * column's definition in output recordset **************************************/ static void __stdcall read_schema(CConnection *conn, void *recordset); /************************************** * * function: a l l o c _ f i e l d s * ************************************** * * Functional description * * reallocate fields buffer if it is too * small **************************************/ void alloc_fields(const unsigned int &iallocate); private: /************************************** * * function: f e t c h _ p r o j e c t * ************************************** * * Functional description * read columns info **************************************/ void fetch_project(); /************************************** * * function: f e t c h _ r o w s e t * ************************************** * * Functional description * read rows **************************************/ void fetch_rowset(); private: short m_eof; // end of recordset int m_index; // current row position in the precached rows chunk buffer CConnection *m_conn; // connection instance CServerConnection *m_server_conn; // server side connection instance. used by UDI applications int m_nfields; // number of the fields/columns in the output row FIELD_INFO *m_fields; // columns type info void *m_fmap; // for fast access to the field by its name byte *m_rows; // rows fitting to the single IO page bool m_first; // true - if first package from db received int m_ifields; // number of preallocated fields int m_recordset; bool m_allow_add; bool m_allow_edit; bool m_allow_delete; unsigned __int64 m_affected_row; // number of rows affected by insert/update/delete friend class CCommand; }; } #endif // !defined(AFX_CONNECTION_H__FF5ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_)