// Мирошниченко Кирилл aka spock
// #163860836
// e-mail: spock@km.ru
//
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __oledb_h__
#include <oledb.h>
#endif // __oledb_h__

#ifndef _MSADERR_H_
#include <oledberr.h>
#endif // _MSADERR_H_

#include "..\\ODBC\\MetaNameParser.h"
#include "..\\SQL\\MetaDataWork.h"
#include "..\\GUID.h"
#include "sp_oledb.h"
#include "sp_oledbparam.h"

#ifndef __sp_oledbptr_h__
#include "sp_oledbptr.h"
#endif // __sp_oledbptr_h__

#ifndef __sp_convhlpr_h__
#include "sp_ConvHlpr.h"
#endif // __sp_convhlpr_h__

#include "ValueTo.h"

#define NUMROWS_CHUNK 50
#define BLOCK_SIZE 1024

enum ExtTp1C {eToOther, eToDoc, eToSb};

//_____________________________________________________________________________
//
struct COLEDBFldsInf
{
public:
	COLEDBFldsInf();

	ULONG	 m_Index;
	CString	 m_strName; 
	CType	 m_nType1C;
	DBTYPE	 m_wType;
	bool	 m_bIsType1C;
	ExtTp1C	 m_eExtType1C;
	bool	 m_bIsLong;
};

typedef CComPtr<ICommandWithParameters> ICommandWithParameters_;
typedef CComPtr<IAccessor> IAccessor_;
typedef CComPtr<IRowset> IRowset_;

typedef COLEDBMemPtr<DBPARAMBINDINFO> DBPARAMBINDINFO_;
typedef COLEDBMemPtr<COLEDBFldsInf> COLEDBFldsInf_;
typedef COLEDBMemPtr<DBBINDSTATUS> DBBINDSTATUS_;
typedef COLEDBMemPtr<DBBINDING> DBBINDING_;
typedef COLEDBMemPtr<DBOBJECT> DBOBJECT_;
typedef COLEDBMemPtr<ULONG> ULONG_;
typedef COLEDBMemPtr<BYTE> BYTE_;

//_____________________________________________________________________________
//
class COLEDBCommand : public CMyContextBase
{
	friend class COLEDBData;
	
	DECLARE_DYNCREATE(COLEDBCommand);
	COLEDBCommand() {}; // запрещено использовать !!

public:
	// конструктор по-умолчанию не используем!
	// только с параметром, в конструкторе член (m_bCreated) инициализируется
	//
	COLEDBCommand(CComPtr<IDBCreateCommand> pIDBCreateCommand);
	virtual ~COLEDBCommand();

	BOOL funcExecuteStatement(CValue& RetVal, CValue** ppValue);
	BOOL defsExecuteStatement(int nParam, CValue* param) const;

	BOOL funcExecute(CValue& RetVal, CValue** ppValue);
	BOOL defsExecute(int nParam, CValue* param) const;

	BOOL procPutObjectList(CValue** ppValue);
	BOOL defsPutObjectList(int nParam, CValue* param) const;

	BOOL procClose(CValue** ppValue);
	BOOL procDebug(CValue** ppValue);
	BOOL procSetTextParam(CValue** ppValue);
	BOOL procSetTempTablesDir(CValue** ppValue);
	BOOL procSetExecTimeOut(CValue** ppValue);
	BOOL procAddParam(CValue** ppValue);
	BOOL procSetParam(CValue** ppValue);
	BOOL procDeleteParam(CValue** ppValue);
	BOOL procDeleteParams(CValue** ppValue);
	
	void DeleteParams();

	BOOL procPrepare(CValue** ppValue);
	BOOL procUnprepare(CValue** ppValue);
	BOOL funcParamCnt(CValue& RetVal, CValue** ppValue);

private:
	//trad
	void SetIBProp(CMetaDataCont *pMDC, CIBSet *pIBSet) {m_MetaNameParser.SetIBProp(pMDC, pIBSet);};
	CBLPtr<COLEDBData> m_pOLEDBData;
	//

	long GetTypeSize(WORD nType);
	void GetErrorDescription(CString& strError) const;
	bool Binding(IRowset_& pIRowset, ULONG* pnCols, DBBINDING_& pDBBindings, COLEDBFldsInf_& pColInfo1C, ULONG* pcMaxRowSize, bool& HasKindField) const;
	CType GetType1C(COLEDBFldsInf* fInfo) const;
	bool ParseQuery(CString& strQuery);
	bool Execute(const CString& strSQL, DBPARAMS* pParams, long* pnRowsAffected, IUnknown** pIRowset, bool bQuiet = false, bool bPrepared = false) const;
	bool CreateAccessor(DBACCESSORFLAGS eDBACCFLAGS, ULONG cbRowSize, IAccessor_& pIAccessor, IUnknown* pIUnknown, HACCESSOR* hAccessor, ULONG& cCntItems, DBBINDING_& pDBBindings) const;
	bool PutObjectsList(CValue** ppValue);
	bool PutAggregateObjects(CValue* pValue, const CString* pszTableName, const CString* RefName);
	void RemoveTmpTable(CString& strTmpTblName);
	void RemoveAllTmpTables(void);
	ULONG FindKindCol(const COLEDBFldsInf* pColumnsInfo, const ULONG& cMaxCols, const CString& strColName) const;

	LPOLESTR wGetTypeByStr(const WORD) const;

	bool Prepare(const CString& strSQL, CString& strErr) const;
	bool Unprepare(CString& strErr) const;
	bool BindWithParams(CString& strErr, const int& nParamCnt, ICommandWithParameters_& pICmdParams, DBPARAMBINDINFO_& pParamBindInfo, DBBINDING_& pDBBinding, ULONG_& pParamOrdinals);
	bool GetParamsDataBuf(BYTE_& pBuffer);

	CMetaNameParser m_MetaNameParser;
	CComPtr<ICommandText> m_pICommandText;
	CList<CString, CString&> m_TmpTblsList;
	CList<COLEDBParam*, COLEDBParam*> m_ParamList;

	bool	 m_bCreated;
	bool	 m_IsDebugMode;
	bool	 m_bPrepared;
	long	 m_ExecTimeout;
	GUID	 m_GUID;
	CString	 m_szTempTablesDir;

	DECLARE_MY_CONTEXT()
};