dataprovider.h at tip Вы: nobody
Вход

File sqlite1c/SQL_DBF/dataprovider.h from the latest check-in


// dataprovider.h
#pragma once
//#define OPTIMIZE_FIELDS_CHANGE
#include "1cpp/V7DataProvider.h"
#include "database.h"
#include "resultloader.h"

class SQLiteDataProvider;

class SQLiteDataRow : public CDataRow, public CV7DataRow
{
public:
    //CDataRow
    virtual int GetFieldCount();
    virtual int GetFieldIndexOf(LPCSTR szFieldName);
    virtual LPCSTR GetFieldName(int nIndex);
    virtual DataType GetFieldType(int nIndex);
    virtual void FormatField(int nIndex, CString& strValue);
    virtual UINT GetRowIndex();

    //CV7DataRow
    virtual const CValue& GetValue(int nIndex) const;
protected:
	friend SQLiteDataProvider;
	friend class DataProviderResultLoader;
	SQLiteDataRow(SQLiteDataProvider* pParent);
	SQLiteDataRow(DWORD fc);
	~SQLiteDataRow();
	SQLiteDataProvider* m_pParent;
	CValue* m_pValues;
	DWORD m_fCount;
};
typedef CTypedPtrArray<CPtrArray, SQLiteDataRow*> RowsArray;


class SQLiteDataProvider : public CContextImpl<SQLiteDataProvider>
	, public CDataProvider, public CV7DataProvider
{
    //CDataProvider
public:
    virtual void QueryRows(CDataRow* pRowFrom, int nRowsCount, int nPageSizeHint);
    virtual CDataRow* Fetch();
    virtual BOOL RefreshRow(CDataRow* pRowFrom);
    virtual BOOL CompareRows(CDataRow* pRow1, CDataRow* pRow2) const;
    virtual BOOL GetRowCount(UINT* pCount);

    virtual void QueryField(LPCSTR szFieldName);
    virtual void ReleaseField(LPCSTR szFieldName);

    virtual DataType GetQuickSearchType(LPCSTR szFieldName);
    virtual void QuickSearch(stQuickSearchPattern& QSPattern);
protected:
    virtual void OnAttach();
    //CV7DataProvider
public:
    virtual CV7DataRow* GetV7DataRow(CDataRow* pDataRow) const;
    virtual void GetRowValue(CDataRow* pDataRow, CValue& value) const;
    virtual CDataRow* BuildRowByValue(const CValue& value);

	//  SQLiteDataRow
	int findField(LPCSTR strFieldName) const
	{
		field_info* pFI;
		if(m_fieldByName.Lookup(strFieldName, pFI))
			return pFI->posInQuery;
		return -1;
	}
	int fieldsCount() const				{ return m_countOfColumns; }
	LPCSTR fieldName(int iIndex)const	{ return m_queryFieldsNames[iIndex]; }

	SQLiteDataProvider();
	~SQLiteDataProvider()
	{
		clearAll();
	}

	BL_BEGIN_CONTEXT("SQLiteDataProvider", "SQLiteDataProvider");

	BL_PROC_WITH_DEFVAL(SetDataBase, "", 1);
	BL_DEFVAL_FOR(SetDataBase) {if(pValue) pValue->Reset(); return TRUE; }
	
	BL_PROC_WITH_DEFVAL(SetParam, "", 3)
	{
		m_sqlParams.setSqlParam(ppParams[0]->GetString(), ppParams[1], ppParams[2]->GetNumeric());
		return TRUE;
	}
	BL_DEFVAL_FOR(SetParam)
	{
		if(nParam == 2)
		{
			if(pValue)
				pValue = 0L;
			return TRUE;
		}
		return FALSE;
	}
	BL_PROC(Substitute, "", 2)
	{
		m_metaParser.setTextParam(ppParams[0]->GetString(), ppParams[1]);
		return TRUE;
	}
	BL_PROC_WITH_DEFVAL(SetQueryText, "", 3);
	BL_DEFVAL_FOR(SetQueryText)
	{
		if(nParam >= 2)
		{
			if(pValue)
				pValue->Reset();
			return TRUE;
		}
		return FALSE;
	}
	BL_PROC(Debug, "", 1)
	{
		m_debug = (long)ppParams[0]->GetNumeric() != 0;
		return TRUE;
	}
	BL_PROC(Reread, "", 0)
	{
		ResetData();
		return TRUE;
	}
	BL_PROC(NoDeleteFields, "", 1)
	{
		setFlagOnFields(ppParams[0]->GetString(), field_info::NoAutoDelete | field_info::inUse);
		setColumnsChanged();
		return TRUE;
	}
	BL_PROC(QuickSearchFields, "", 1)
	{
		setFlagOnFields(ppParams[0]->GetString(), field_info::qsPossible);
		return TRUE;
	}
	BL_FUNC(GetQueryText, "", 1);

	BL_END_CONTEXT();
private:
	enum qTypes{qDown, qUp, qTop, qBottom, qID, qCurRow, qQuickSearch, qLast};
	
	struct sqlParamStore
	{
		struct node
		{
			node(const CValue* pVal, int m) : value(*pVal), mod(m){}
			CValue value;
			int mod;
		};
		struct node_del{void operator()(node* p){delete p;}};
		struct setter
		{
			setter(SQLiteQuery* p) : pQ(p){}
			SQLiteQuery* pQ;
			void operator()(const CString& name, node* p)
			{
				pQ->setSqlParam(CValue(name), p->value, p->mod, FALSE);
			}
		};
		
		CNoCaseMap<node*> nodes;
		DWORD dirtyQueries;

		void setSqlParam(const CString& name, const CValue* pVal, int mod)
		{
			node* pNode;
			if(nodes.Lookup(name, pNode))
			{
				pNode->value = *pVal;
				pNode->mod = mod;
			}
			else
				nodes[name] = new node(pVal, mod);
			dirtyQueries = 0xFFFFFFFF;
		}
		inline void applyParamsToQuery(SQLiteQuery* pQ, int type)
		{
			if(type >= 0 && (dirtyQueries & (1 << type)) == 0)
				return;
			nodes.ForEachPair(setter(pQ));
			if(type >= 0)
				dirtyQueries &= ~(1<<type);
		}
		~sqlParamStore()
		{
			nodes.ForEachValue(node_del());
		}
	};

	struct field_info
	{
		DWORD posInQuery, flags;
		typesOfFields type;
		CString expression, alias, nameOfQueryColumn;
		enum{
			keyField = 1, idField = 2, NoAutoDelete = 4, inUse = 8, qsPossible,
		};
	};
	typedef CArray<field_info, field_info> FieldArray;

		
	SQLiteQuery*		getQuery(qTypes type);
	void				clearRows();
	void				clearQueriesData();
	void				clearAll();
	void				bindKeyValues(SQLiteQuery* pQuery, SQLiteDataRow* pRow);
	DWORD				fieldsInfoCount() const				{ return m_fieldsInfoCount; }
	const field_info&	fieldInfo(DWORD idx) const			{ return m_fieldsInfo[idx]; }
	DWORD				keyFieldsCount() const				{ return m_keyFieldCount;}
	const CString&		keySQLParamName(DWORD idx) const	{ return m_keyParamNames[idx]; }
	DWORD				idFieldPos() const					{ return m_idFieldPos; }
	void				setColumnsChanged();
	void				setFlagOnFields(const CString& fields, int flag);

	CSLDataBase*		m_pDataBase;		//  
	SQLiteQuery*		m_queries[qLast];	//    
	MetaParser			m_metaParser;		//    
	sqlParamStore		m_sqlParams;		//   sql-
	RowsArray			m_rows;				//    
	LPCSTR*				m_queryFieldsNames;	//     
	CString*			m_keyParamNames;	//  SQL-  
	field_info*			m_fieldsInfo;		//      
	DWORD				m_fieldsInfoCount;	//    
	DWORD				m_keyFieldCount;	//   
	DWORD				m_idFieldPos;		//  -    
	DWORD				m_countOfColumns;	//     
	BOOL				m_debug;			//  
	field_info*			m_lastQSColumn;		//       
	DWORD				m_QSColumn;			//      ,   
	CString				m_select;			// select-  ,    
	CString				m_from;				//  from 
	CString				m_where;			//  where 
	CNoCaseMap<field_info*>	m_fieldByName;	//      
};

class SimpleResultLoader :  public CBLContext, public ISQLiteResultLoader
{
public:
	virtual DWORD init(DWORD colCountInResult, sqlite3* pBase, CValue* pParam)
	{
		return m_count = colCountInResult;
	}
	virtual void setColumn(DWORD colIdx, const CString& colName, const CType& type){}
	virtual void assignRetValue(CValue& retVal){}

	void execute(SQLiteQuery* pQuery)
	{
		CValue me;
		me.type = 100;
		me.m_Context = this;
		pQuery->execute(&me, NULL, CValue());
		me.m_Context = NULL;
	}
protected:
	DWORD m_count;
};

class DataProviderResultLoader : public SimpleResultLoader
{
public:
	DataProviderResultLoader(SQLiteDataProvider* pProvider, RowsArray* pDest)
		:m_pProvider(pProvider), m_pDestination(pDest){}
	virtual void addValues(CValue** ppValues);
protected:
	SQLiteDataProvider* m_pProvider;
	RowsArray* m_pDestination;
};

class QuickSearchResultLoader : public SimpleResultLoader
{
public:
	QuickSearchResultLoader(const CString& p, CValue* keys, DWORD kc, DWORD tf)
		:m_pattern(p), m_pBestKey(keys), m_keysCount(kc),
		m_testField(tf), m_maxSymbols(0)
	{
	}
	virtual void addValues(CValue** ppValues);

	int find(SQLiteQuery* pQuery)
	{
		IncrRef();
		try{ execute(pQuery); } catch(int){}
		return m_maxSymbols;
	}

protected:
	const CString& m_pattern;
	CValue* m_pBestKey;
	int m_maxSymbols;
	DWORD m_keysCount, m_testField;
};