00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef DBASQL_H
00013 #define DBASQL_H
00014
00015 #include <typeinfo>
00016 #include <vector>
00017 #include <deque>
00018 #include <string>
00019 #include "dba/database.h"
00020 #include "dba/storeablefilter.h"
00021 #include "dba/shared_ptr.h"
00022
00023 namespace dba {
00024
00025 class FilterMapper;
00026 class ConvSpec;
00027
00057 class dbaDLLEXPORT SQL {
00058 private:
00059 class DataContainerBase {
00060 public:
00061 virtual void* getPtr() const = 0;
00062 virtual ~DataContainerBase(){};
00063 protected:
00064 DataContainerBase() {};
00065 };
00066
00070 template <typename T> class DataContainer : public DataContainerBase {
00071 public:
00072 DataContainer(T* pData) { mData = pData; }
00073 virtual void* getPtr() const { return mData; }
00074 virtual ~DataContainer() { delete mData; }
00075 private:
00076 T* mData;
00077 };
00078 public:
00080 static const int VAR_INDEX_UNDEFINED = -1;
00081
00082 SQL();
00087 SQL(const char* pData);
00092 SQL(const std::string& pData);
00093 void setFilterDataForNextParam(DataContainerBase* pData, const char* pTypeName);
00094 void setFilterDataForNextParam(StoreableFilterBase* pFilter);
00095 void setFilterDataForNextVar(void* pData, const char* pTypeName, const char* pSQLName = NULL, int pSQLPos = VAR_INDEX_UNDEFINED);
00096 void setFilterDataForNextVar(StoreableFilterBase* pFilter, const char* pSQLName = NULL, int pSQLPos = VAR_INDEX_UNDEFINED);
00101 virtual std::string cstring(const FilterMapper& pMapper, const ConvSpec& pSpecs) const;
00105 virtual void updateVars(DbResult& pRes, const FilterMapper& pMapper, const ConvSpec& pSpecs) const;
00109 void appendData(const SQL& pQuery);
00113 void appendFilterData(const SQL& pQuery);
00114
00118 SQL& operator<< (const char* pData) {
00119 DataContainerBase* data = new DataContainer<std::string>(new std::string(pData));
00120 setFilterDataForNextParam(data,typeid(std::string).name());
00121 return *this;
00122 }
00123
00128 template <typename T> SQL& operator<< (T* pData) {
00129 setFilterDataForNextParam(pData);
00130 return *this;
00131 };
00132
00137 template <typename T> SQL& operator<<(const T& pData) {
00138 DataContainerBase* data = new DataContainer<T>(new T(pData));
00139 setFilterDataForNextParam(data,typeid(pData).name());
00140 return *this;
00141 }
00142
00147 template <typename T> SQL& into(T& pVar) {
00148 setFilterDataForNextVar(&pVar,typeid(pVar).name());
00149 return *this;
00150 }
00151
00157 SQL& into(StoreableFilterBase* pFilter) {
00158 setFilterDataForNextVar(pFilter);
00159 return *this;
00160 }
00161
00165 dba::SQL& operator+ (const SQL& pFrom);
00166 dba::SQL& operator+= (const SQL& pFrom);
00167
00168 virtual ~SQL();
00169 protected:
00170 void parseQuery();
00171 private:
00172 typedef enum {
00173 PARAM_UNKNOWN = 0,
00174 PARAM_ESCAPED,
00175 PARAM_STR_VALUE,
00176 PARAM_STR_LIKE,
00177 PARAM_INT,
00178 PARAM_DATE,
00179 PARAM_FLOAT,
00180 PARAM_ESCAPE_CHAR
00181 } convert_type;
00182
00186 class ParamData {
00187 public:
00188 ParamData(DataContainerBase* pData, const char* pTypeName)
00189 : mData(pData),
00190 mTypeName(pTypeName),
00191 mFilter(NULL)
00192 {}
00193 ParamData(StoreableFilterBase* pFilter)
00194 : mData(NULL),
00195 mTypeName(NULL),
00196 mFilter(pFilter)
00197 {}
00198 ~ParamData() {}
00199 shared_ptr<DataContainerBase> mData;
00200 const char* mTypeName;
00201 shared_ptr<StoreableFilterBase> mFilter;
00202 };
00203
00204
00208 class VarData {
00209 public:
00210 VarData(void* pData, const char* pTypeName, const char* pSQLName, int pSQLIndex = VAR_INDEX_UNDEFINED)
00211 : mData(pData),
00212 mTypeName(pTypeName),
00213 mFilter(NULL),
00214 mSQLName(pSQLName),
00215 mSQLIndex(pSQLIndex),
00216 mStoreType(Database::UNKNOWN)
00217 {}
00218 VarData(StoreableFilterBase* pFilter, const char* pSQLName, int pSQLIndex = VAR_INDEX_UNDEFINED)
00219 : mData(NULL),
00220 mTypeName(NULL),
00221 mFilter(pFilter),
00222 mSQLName(pSQLName),
00223 mSQLIndex(pSQLIndex),
00224 mStoreType(Database::UNKNOWN)
00225 {}
00226 bool hasName() const { return mSQLName != NULL; }
00227 bool hasIndex() const { return mSQLIndex != VAR_INDEX_UNDEFINED; }
00228 void* mData;
00229 const char* mTypeName;
00230 const char* mSQLName;
00231 int mSQLIndex;
00232 Database::StoreType mStoreType;
00233 StoreableFilterBase* mFilter;
00234 };
00235
00239 class ParamPlaceholder {
00240 public:
00241 ParamPlaceholder(size_t pIndex, convert_type pConv, bool pShouldQuote = false)
00242 : mIndex(pIndex), mConvertType(pConv), mShouldQuote(pShouldQuote)
00243 {}
00244 bool operator==(const ParamPlaceholder& pArg) {
00245 return (mIndex == pArg.mIndex && mConvertType == pArg.mConvertType && mShouldQuote == pArg.mShouldQuote);
00246 }
00247 size_t mIndex;
00248 convert_type mConvertType;
00249 bool mShouldQuote;
00250 };
00251
00252 typedef std::vector<ParamData> Params;
00253 typedef std::vector<VarData> Vars;
00254 typedef std::vector<ParamPlaceholder> Placeholders;
00255
00259 class dbaDLLEXPORT SQLParamParser {
00260 public:
00261 SQLParamParser(const std::string& pSQLQuery,SQL::Placeholders& pParams);
00266 void parse();
00267 ~SQLParamParser() {}
00268 private:
00269 typedef enum {
00270 SCAN,
00271 PARAM_TEST,
00272 QUOTED_FIELD,
00273 QUOTE_TEST,
00274 AFTER_LIKE,
00275 QUOTED_LIKE
00276 } state;
00277 std::string mSQLQuery;
00278 std::deque<state> mState;
00279 Placeholders& mPlaceholders;
00280 void setCurrentParamIndex(std::string::iterator& pPos);
00281 void checkSQLLike(const std::string::iterator& pPos);
00282 };
00283
00284 class ParamVal {
00285 public:
00286 ParamVal() {};
00287 ParamVal(const char* pData) : mValue(pData), mIsNull(false) {}
00288
00289 std::string mValue;
00290 bool mIsNull;
00291 };
00292
00293 Params mParams;
00294 Vars mVars;
00295 Placeholders mPlaceholders;
00296 std::string mSQLQuery;
00297
00298 std::string fillQueryParams(const FilterMapper& pMapper, const ConvSpec& pSpecs) const;
00299 ParamVal convertParam(const FilterMapper& pMapper, const ConvSpec& pSpecs, const ParamData& pData) const;
00300 int getCountWithoutEscapes(const Placeholders& pPh) const;
00301 };
00302
00303 dba::SQL
00304 operator+(const dba::SQL& pQuery, const SQL& pFrom);
00305
00306 }
00307
00308 #endif