diff --git a/hikyuu_cpp/hikyuu/DataType.h b/hikyuu_cpp/hikyuu/DataType.h index cfc22fb1..a2242364 100644 --- a/hikyuu_cpp/hikyuu/DataType.h +++ b/hikyuu_cpp/hikyuu/DataType.h @@ -47,13 +47,29 @@ namespace hku { * @{ */ -typedef long long hku_int64; -typedef unsigned long long hku_uint64; -typedef int hku_int32; -typedef unsigned hku_uint32; -typedef char hku_int8; -typedef unsigned char hku_uint8; +#if !defined(int64) +typedef long long int64; +#endif +#if !defined(uint64) +typedef unsigned long long uint64; +#endif + +#if !defined(int32) +typedef int int32; +#endif + +#if !defined(uint32) +typedef unsigned uint32; +#endif + +#if !defined(int8) +typedef char int8; +#endif + +#if !defined(uint8) +typedef unsigned char uint8; +#endif typedef double price_t; diff --git a/hikyuu_cpp/hikyuu/KQuery.cpp b/hikyuu_cpp/hikyuu/KQuery.cpp index 97c16f23..00091843 100644 --- a/hikyuu_cpp/hikyuu/KQuery.cpp +++ b/hikyuu_cpp/hikyuu/KQuery.cpp @@ -29,41 +29,41 @@ const string KQuery::HOUR12("HOUR12"); //const string KQuery::INVALID_KTYPE("Z"); -KQuery KQueryByIndex(hku_int64 start, hku_int64 end, +KQuery KQueryByIndex(int64 start, int64 end, KQuery::KType dataType, KQuery::RecoverType recoverType) { return KQuery(start, end, dataType, recoverType, KQuery::INDEX); } KQuery KQueryByDate(const Datetime& start, const Datetime& end, KQuery::KType dataType, KQuery::RecoverType recoverType) { - hku_int64 start_number = start == Null() - ? (hku_int64)start.number() - : (hku_int64)(start.number()*100 + start.second()); - hku_int64 end_number = end == Null() - ? (hku_int64)end.number() - : (hku_int64)(end.number()*100 + end.second()); + int64 start_number = start == Null() + ? (int64)start.number() + : (int64)(start.number()*100 + start.second()); + int64 end_number = end == Null() + ? (int64)end.number() + : (int64)(end.number()*100 + end.second()); return KQuery(start_number, end_number, dataType, recoverType, KQuery::DATE); } Datetime KQuery::startDatetime() const { - if (m_queryType != DATE || (hku_uint64)m_start == Null()) { + if (m_queryType != DATE || (uint64)m_start == Null()) { return Null(); } - hku_uint64 number = (hku_uint64)(m_start/100); + uint64 number = (uint64)(m_start/100); Datetime d(number); return Datetime(d.year(), d.month(), d.day(), d.hour(), d.minute(), m_start - number * 100); } Datetime KQuery::endDatetime() const { - if (m_queryType != DATE || (hku_uint64)m_end == Null()) { + if (m_queryType != DATE || (uint64)m_end == Null()) { return Null(); } - hku_uint64 number = (hku_uint64)(m_end/100); + uint64 number = (uint64)(m_end/100); Datetime d(number); return Datetime(d.year(), d.month(), d.day(), d.hour(), d.minute(), m_end - number * 100); diff --git a/hikyuu_cpp/hikyuu/KQuery.h b/hikyuu_cpp/hikyuu/KQuery.h index db412800..42b42181 100644 --- a/hikyuu_cpp/hikyuu/KQuery.h +++ b/hikyuu_cpp/hikyuu/KQuery.h @@ -85,7 +85,7 @@ public: /** 默认构造,按索引方式查询全部日线数据,不复权 */ KQuery() : m_start(0), - m_end(Null()), + m_end(Null()), m_queryType(INDEX), m_dataType(DAY), m_recoverType(NO_RECOVER) { }; @@ -98,8 +98,8 @@ public: * @param recoverType 复权类型 * @param queryType 默认按索引方式查询 */ - KQuery(hku_int64 start, - hku_int64 end = Null(), + KQuery(int64 start, + int64 end = Null(), KType dataType = DAY, RecoverType recoverType = NO_RECOVER, QueryType queryType = INDEX) @@ -110,17 +110,17 @@ public: m_recoverType(recoverType) { } /** - * 按索引方式查询时,返回指定的起始索引,否则返回Null() + * 按索引方式查询时,返回指定的起始索引,否则返回Null() */ - hku_int64 start() const { - return m_queryType != INDEX ? Null() : m_start; + int64 start() const { + return m_queryType != INDEX ? Null() : m_start; } /** - * 按索引方式查询时,返回指定的结束索引,否则返回Null() + * 按索引方式查询时,返回指定的结束索引,否则返回Null() */ - hku_int64 end() const { - return m_queryType != INDEX ? Null() : m_end; + int64 end() const { + return m_queryType != INDEX ? Null() : m_end; } /** @@ -162,8 +162,8 @@ public: static RecoverType getRecoverTypeEnum(const string&); private: - hku_int64 m_start; - hku_int64 m_end; + int64 m_start; + int64 m_end; QueryType m_queryType; KType m_dataType; RecoverType m_recoverType; @@ -179,8 +179,8 @@ private: * @see KQuery * @ingroup StockManage* */ -KQuery HKU_API KQueryByIndex(hku_int64 start = 0, - hku_int64 end = Null(), +KQuery HKU_API KQueryByIndex(int64 start = 0, + int64 end = Null(), KQuery::KType dataType = KQuery::DAY, KQuery::RecoverType recoverType = KQuery::NO_RECOVER); @@ -241,8 +241,8 @@ class Null { public: Null() {} operator KQuery() { - return KQuery(Null(), - Null(), + return KQuery(Null(), + Null(), "", //KQuery::INVALID_KTYPE, KQuery::INVALID_RECOVER_TYPE, KQuery::INVALID diff --git a/hikyuu_cpp/hikyuu/Stock.cpp b/hikyuu_cpp/hikyuu/Stock.cpp index 7cadeace..ddfa03b4 100644 --- a/hikyuu_cpp/hikyuu/Stock.cpp +++ b/hikyuu_cpp/hikyuu/Stock.cpp @@ -20,7 +20,7 @@ const string Stock::default_market; const string Stock::default_code; const string Stock::default_market_code; const string Stock::default_name; -const hku_uint32 Stock::default_type = Null(); +const uint32 Stock::default_type = Null(); const bool Stock::default_valid = false; const Datetime Stock::default_startDate;// = Null(); const Datetime Stock::default_lastDate;// = Null(); @@ -83,7 +83,7 @@ Stock::Data::Data() Stock::Data::Data(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber) @@ -165,7 +165,7 @@ Stock::Stock(const string& market, Stock::Stock(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate) { m_data = shared_ptr( new Data(market, code, name, type, valid, @@ -177,7 +177,7 @@ Stock::Stock(const string& market, const string& code, Stock::Stock(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber) { @@ -221,7 +221,7 @@ const string& Stock::name() const { return m_data ? m_data->m_name : default_name; } -hku_uint32 Stock::type() const { +uint32 Stock::type() const { return m_data ? m_data->m_type : default_type; } @@ -453,7 +453,7 @@ _getIndexRangeByIndex(const KQuery& query, size_t& out_start, size_t& out_end) c return false; } - hku_int64 startix, endix; + int64 startix, endix; startix = query.start(); if(startix < 0) { startix += total; diff --git a/hikyuu_cpp/hikyuu/Stock.h b/hikyuu_cpp/hikyuu/Stock.h index 58a9ee11..79a5d0b1 100644 --- a/hikyuu_cpp/hikyuu/Stock.h +++ b/hikyuu_cpp/hikyuu/Stock.h @@ -34,7 +34,7 @@ private: static const string default_code; static const string default_market_code; static const string default_name; - static const hku_uint32 default_type; + static const uint32 default_type; static const bool default_valid; static const Datetime default_startDate; static const Datetime default_lastDate; @@ -52,10 +52,10 @@ public: Stock(const string& market, const string& code, const string& name); Stock(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate); Stock(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber); @@ -65,7 +65,7 @@ public: bool operator!=(const Stock&) const; /** 获取内部id,一般用于作为map的键值使用,该id实质为m_data的内存地址 */ - hku_uint64 id() const; + uint64 id() const; /** 获取所属市场简称,市场简称是市场的唯一标识 */ const string& market() const; @@ -80,7 +80,7 @@ public: const string& name() const; /** 获取证券类型 */ - hku_uint32 type() const; + uint32 type() const; /** 该证券当前是否有效 */ bool valid() const; @@ -220,7 +220,7 @@ struct HKU_API Stock::Data { string m_code; //证券代码 string m_market_code; //市场简称证券代码 string m_name; //证券名称 - hku_uint32 m_type; //证券类型 + uint32 m_type; //证券类型 bool m_valid; //当前证券是否有效 Datetime m_startDate; //证券起始日期 Datetime m_lastDate; //证券最后日期 @@ -239,7 +239,7 @@ struct HKU_API Stock::Data { Data(); Data(const string& market, const string& code, - const string& name, hku_uint32 type, bool valid, + const string& name, uint32 type, bool valid, const Datetime& startDate, const Datetime& lastDate, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber); @@ -274,8 +274,8 @@ inline bool operator < (const Stock& s1, const Stock& s2) { return s1.id() < s2.id(); } -inline hku_uint64 Stock::id() const { - return isNull() ? 0 : (hku_int64)m_data.get(); +inline uint64 Stock::id() const { + return isNull() ? 0 : (int64)m_data.get(); } inline StockWeightList Stock::getWeight() const { diff --git a/hikyuu_cpp/hikyuu/StockManager.cpp b/hikyuu_cpp/hikyuu/StockManager.cpp index 42cc3c57..b8b7c4a4 100644 --- a/hikyuu_cpp/hikyuu/StockManager.cpp +++ b/hikyuu_cpp/hikyuu/StockManager.cpp @@ -312,7 +312,7 @@ MarketInfo StockManager::getMarketInfo(const string& market) const { } -StockTypeInfo StockManager::getStockTypeInfo(hku_uint32 type) const { +StockTypeInfo StockManager::getStockTypeInfo(uint32 type) const { auto iter = m_stockTypeInfo.find(type); if( iter != m_stockTypeInfo.end() ){ return iter->second; diff --git a/hikyuu_cpp/hikyuu/StockManager.h b/hikyuu_cpp/hikyuu/StockManager.h index 54811e7f..9a238c64 100644 --- a/hikyuu_cpp/hikyuu/StockManager.h +++ b/hikyuu_cpp/hikyuu/StockManager.h @@ -90,7 +90,7 @@ public: * @param type 证券类型 * @return 对应的证券类型信息,如果不存在,则返回Null() */ - StockTypeInfo getStockTypeInfo(hku_uint32 type) const; + StockTypeInfo getStockTypeInfo(uint32 type) const; /** 获取市场简称列表 */ MarketList getAllMarket() const; @@ -188,7 +188,7 @@ private: typedef unordered_map MarketInfoMap; MarketInfoMap m_marketInfoDict; - typedef unordered_map StockTypeInfoMap; + typedef unordered_map StockTypeInfoMap; StockTypeInfoMap m_stockTypeInfo; Parameter m_baseInfoDriverParam; diff --git a/hikyuu_cpp/hikyuu/StockTypeInfo.cpp b/hikyuu_cpp/hikyuu/StockTypeInfo.cpp index 6b3a1975..431ca136 100644 --- a/hikyuu_cpp/hikyuu/StockTypeInfo.cpp +++ b/hikyuu_cpp/hikyuu/StockTypeInfo.cpp @@ -53,7 +53,7 @@ string StockTypeInfo::toString() const { } StockTypeInfo::StockTypeInfo() -: m_type(Null()), +: m_type(Null()), m_tick(0.0), m_tickValue(0.0), m_unit(1.0), @@ -62,7 +62,7 @@ StockTypeInfo::StockTypeInfo() m_maxTradeNumber(0) { } -StockTypeInfo::StockTypeInfo(hku_uint32 type, +StockTypeInfo::StockTypeInfo(uint32 type, const string& description, price_t tick, price_t tickValue, int precision, size_t minTradeNumber, size_t maxTradeNumber) diff --git a/hikyuu_cpp/hikyuu/StockTypeInfo.h b/hikyuu_cpp/hikyuu/StockTypeInfo.h index b760d905..954ee98c 100644 --- a/hikyuu_cpp/hikyuu/StockTypeInfo.h +++ b/hikyuu_cpp/hikyuu/StockTypeInfo.h @@ -34,11 +34,11 @@ class HKU_API StockTypeInfo { public: /** 默认构造函数,返回Null() */ StockTypeInfo(); - StockTypeInfo(hku_uint32, const string&, price_t, price_t, + StockTypeInfo(uint32, const string&, price_t, price_t, int, size_t, size_t); /** 获取证券类型 */ - hku_uint32 type() const { return m_type; } + uint32 type() const { return m_type; } /** 获取证券类型描述信息 */ const string& description() const { return m_description; } @@ -65,7 +65,7 @@ public: string toString() const; private: - hku_uint32 m_type; //证券类型 + uint32 m_type; //证券类型 string m_description; //描述信息 price_t m_tick; //最小跳动量 price_t m_tickValue; //每一个tick价格 diff --git a/hikyuu_cpp/hikyuu/data_driver/BaseInfoDriver.h b/hikyuu_cpp/hikyuu/data_driver/BaseInfoDriver.h index 8ceebe40..9cd3659c 100644 --- a/hikyuu_cpp/hikyuu/data_driver/BaseInfoDriver.h +++ b/hikyuu_cpp/hikyuu/data_driver/BaseInfoDriver.h @@ -24,7 +24,7 @@ class HKU_API BaseInfoDriver { public: typedef unordered_map MarketInfoMap; - typedef unordered_map StockTypeInfoMap; + typedef unordered_map StockTypeInfoMap; BaseInfoDriver(const string& name); virtual ~BaseInfoDriver() { } diff --git a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp index 63985ac7..e58d64c5 100644 --- a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp @@ -52,7 +52,7 @@ PriceList HistoryFinanceReader memcpy(&report_size, header_buf + 12, 4); char stock_code[7]; - hku_uint32 address = 0; + uint32 address = 0; for (int i = 0; i < max_count; i++) { if (!fread(stock_code, 1, 7, fp)) { HKU_ERROR("read stock_code failed! {}", filename); diff --git a/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.cpp b/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.cpp index 7176d9f7..dd5d697c 100644 --- a/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.cpp @@ -132,7 +132,7 @@ bool MySQLBaseInfoDriver::_loadMarketInfo() { to_upper(market); Datetime last_date; try { - hku_int64 d = (boost::lexical_cast(row[4])*10000); + int64 d = (boost::lexical_cast(row[4])*10000); last_date = Datetime(d); } catch(...) { last_date = Null(); @@ -178,7 +178,7 @@ bool MySQLBaseInfoDriver::_loadStockTypeInfo() { StockManager& sm = StockManager::instance(); while((row = mysql_fetch_row(result))) { - hku_uint32 type = boost::lexical_cast(row[0]); + uint32 type = boost::lexical_cast(row[0]); try { StockTypeInfo stkTypeInfo(type, HKU_STR(row[1]), boost::lexical_cast(row[2]), @@ -199,7 +199,7 @@ bool MySQLBaseInfoDriver::_loadStockTypeInfo() { bool MySQLBaseInfoDriver:: -_getStockWeightList(hku_uint64 stockid, StockWeightList& out) { +_getStockWeightList(uint64 stockid, StockWeightList& out) { if (!m_mysql) { HKU_ERROR("Null m_mysql!"); return false; @@ -292,7 +292,7 @@ bool MySQLBaseInfoDriver::_loadStock() { StockManager& sm = StockManager::instance(); while((row = mysql_fetch_row(result))) { - hku_uint64 stockid = boost::lexical_cast(row[0]); + uint64 stockid = boost::lexical_cast(row[0]); string market(row[1]); to_upper(market); @@ -323,7 +323,7 @@ bool MySQLBaseInfoDriver::_loadStock() { Stock stock(market, row[2], //code HKU_STR(row[3]), //name - boost::lexical_cast(row[4]), //type + boost::lexical_cast(row[4]), //type boost::lexical_cast(row[5]), //valid; start_date, //startDate end_date, //endDate diff --git a/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.h b/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.h index 5e586cf1..f7433e3a 100644 --- a/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.h +++ b/hikyuu_cpp/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.h @@ -30,7 +30,7 @@ public: virtual bool _loadStock(); private: - bool _getStockWeightList(hku_uint64, StockWeightList&); + bool _getStockWeightList(uint64, StockWeightList&); private: shared_ptr m_mysql; diff --git a/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.cpp b/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.cpp index 3205cf88..e1c1d198 100644 --- a/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.cpp @@ -81,11 +81,11 @@ int SQLiteBaseInfoDriver::_getMarketTableCallBack(void *out, int nCol, char **azVals, char **azCols) { assert(nCol==5); int result = 0; - hku_uint64 d; + uint64 d; string market(azVals[0]); to_upper(market); try{ - d = (boost::lexical_cast(azVals[4])*10000); + d = (boost::lexical_cast(azVals[4])*10000); Datetime datetime; try { datetime = Datetime(d); @@ -145,7 +145,7 @@ int SQLiteBaseInfoDriver::_getStockTypeInfoTableCallBack( assert(nCol == 7); int result = 0; try{ - hku_uint32 type = boost::lexical_cast(azVals[0]); + uint32 type = boost::lexical_cast(azVals[0]); StockTypeInfo stockTypeInfo( type, HKU_STR(azVals[1]), boost::lexical_cast(azVals[2]), @@ -168,7 +168,7 @@ int SQLiteBaseInfoDriver::_getStockTypeInfoTableCallBack( return result; } -bool SQLiteBaseInfoDriver::_getStockWeightList(hku_uint32 id, +bool SQLiteBaseInfoDriver::_getStockWeightList(uint32 id, StockWeightList& out) { if (!m_db) { return false; @@ -200,8 +200,8 @@ int SQLiteBaseInfoDriver::_getStockWeightCallBack( int id = 0; try{ id = boost::lexical_cast(azVals[0]); - hku_uint64 datetime; - datetime = boost::lexical_cast(azVals[1]) * 10000; + uint64 datetime; + datetime = boost::lexical_cast(azVals[1]) * 10000; StockWeight weight(Datetime(datetime), boost::lexical_cast(azVals[2]) * 0.0001, boost::lexical_cast(azVals[3]) * 0.0001, @@ -230,11 +230,11 @@ int SQLiteBaseInfoDriver::_getStockWeightCallBack( } struct StockTable { - hku_uint32 id; + uint32 id; string market; string code; string name; - hku_uint32 type; + uint32 type; bool valid; Datetime startDate; Datetime endDate; @@ -307,17 +307,17 @@ int SQLiteBaseInfoDriver::_getStockTableCallBack( int result = 0; StockTable stockRecord; try { - stockRecord.id = boost::lexical_cast(azVals[0]); + stockRecord.id = boost::lexical_cast(azVals[0]); stockRecord.market = string(azVals[1]); stockRecord.code = string(azVals[2]); stockRecord.name = string(HKU_STR(azVals[3])); - stockRecord.type = boost::lexical_cast(azVals[4]); - hku_uint32 temp_valid = boost::lexical_cast(azVals[5]); + stockRecord.type = boost::lexical_cast(azVals[4]); + uint32 temp_valid = boost::lexical_cast(azVals[5]); stockRecord.valid = temp_valid > 0 ? true : false; Datetime datetime; - hku_uint64 startDate, endDate; - startDate = boost::lexical_cast(azVals[6])*10000; - endDate = boost::lexical_cast(azVals[7])*10000; + uint64 startDate, endDate; + startDate = boost::lexical_cast(azVals[6])*10000; + endDate = boost::lexical_cast(azVals[7])*10000; if(startDate > endDate || startDate == 0 || endDate == 0) { //日期非法,置为Null stockRecord.startDate = Null(); diff --git a/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h b/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h index 94fab052..d504cbae 100644 --- a/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h +++ b/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h @@ -28,7 +28,7 @@ public: virtual Parameter getFinanceInfo(const string& market, const string& code); private: - bool _getStockWeightList(hku_uint32, StockWeightList&); + bool _getStockWeightList(uint32, StockWeightList&); private: static int _getMarketTableCallBack(void *out, int nCol, diff --git a/hikyuu_cpp/hikyuu/data_driver/kdata/hdf5/H5KDataDriver.cpp b/hikyuu_cpp/hikyuu/data_driver/kdata/hdf5/H5KDataDriver.cpp index 120440ee..8664cbb2 100644 --- a/hikyuu_cpp/hikyuu/data_driver/kdata/hdf5/H5KDataDriver.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/kdata/hdf5/H5KDataDriver.cpp @@ -595,8 +595,8 @@ _getBaseIndexRangeByDate(const string& market, const string& code, H5::DataSet dataset; H5::DataSpace dataspace; - hku_uint64 start_number = query.startDatetime().number(); - hku_uint64 end_number = query.endDatetime().number(); + uint64 start_number = query.startDatetime().number(); + uint64 end_number = query.endDatetime().number(); hsize_t startpos = 0, endpos = 0; try { dataset = group.openDataSet(market + code); @@ -726,7 +726,7 @@ _getOtherIndexRangeByDate(const string& market, const string& code, } size_t mid, low=0, high=total-1; - hku_uint64 startDatetime = query.startDatetime().number(); + uint64 startDatetime = query.startDatetime().number(); H5IndexRecord h5record; while(low<=high){ H5ReadIndexRecords(dataset, high, 1, &h5record); @@ -757,7 +757,7 @@ _getOtherIndexRangeByDate(const string& market, const string& code, out_start = mid; - hku_uint64 endDatetime = query.endDatetime().number(); + uint64 endDatetime = query.endDatetime().number(); low=mid, high = total-1; while(low<=high){ H5ReadIndexRecords(dataset, high, 1, &h5record); @@ -810,7 +810,7 @@ TimeLineList H5KDataDriver TimeLineList H5KDataDriver ::_getTimeLine(const string& market, const string& code, - hku_int64 start_ix, hku_int64 end_ix) { + int64 start_ix, int64 end_ix) { TimeLineList result; H5FilePtr h5file; H5::Group group; @@ -895,8 +895,8 @@ TimeLineList H5KDataDriver H5::DataSet dataset; H5::DataSpace dataspace; - hku_uint64 start_number = start.number(); - hku_uint64 end_number = end.number(); + uint64 start_number = start.number(); + uint64 end_number = end.number(); hsize_t startpos = 0, endpos = 0; try { dataset = group.openDataSet(market + code); @@ -1031,7 +1031,7 @@ TransList H5KDataDriver TransList H5KDataDriver ::_getTransList(const string& market, const string& code, - hku_int64 start_ix, hku_int64 end_ix) { + int64 start_ix, int64 end_ix) { TransList result; H5FilePtr h5file; H5::Group group; @@ -1074,7 +1074,7 @@ TransList H5KDataDriver TransRecord record; result.reserve(total + 2); - hku_uint64 number = 0, second = 0; + uint64 number = 0, second = 0; for(hsize_t i=0; i H5FilePtr; struct H5Record { - hku_uint64 datetime; - hku_uint32 openPrice; - hku_uint32 highPrice; - hku_uint32 lowPrice; - hku_uint32 closePrice; - hku_uint64 transAmount; - hku_uint64 transCount; + uint64 datetime; + uint32 openPrice; + uint32 highPrice; + uint32 lowPrice; + uint32 closePrice; + uint64 transAmount; + uint64 transCount; }; struct H5IndexRecord { - hku_uint64 datetime; - hku_uint64 start; + uint64 datetime; + uint64 start; }; struct H5TimeLineRecord { - hku_uint64 datetime; - hku_uint64 price; - hku_uint64 vol; + uint64 datetime; + uint64 price; + uint64 vol; }; struct H5TransRecord { - hku_uint64 datetime; - hku_uint64 price; - hku_uint64 vol; - hku_uint8 buyorsell; + uint64 datetime; + uint64 price; + uint64 vol; + uint8 buyorsell; }; } /* namespae */ diff --git a/hikyuu_cpp/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.cpp b/hikyuu_cpp/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.cpp index af071ed5..7c61cead 100644 --- a/hikyuu_cpp/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.cpp @@ -165,7 +165,7 @@ loadKData(const string& market, const string& code, while ((row = mysql_fetch_row(result))) { try { KRecord k; - hku_uint64 d = boost::lexical_cast(row[0]); + uint64 d = boost::lexical_cast(row[0]); k.datetime = Datetime(d); k.openPrice = boost::lexical_cast(row[1]); k.highPrice = boost::lexical_cast(row[2]); @@ -342,7 +342,7 @@ getKRecord(const string& market, const string& code, while ((row = mysql_fetch_row(mysql_result))) { try { - hku_uint64 d = boost::lexical_cast(row[0]); + uint64 d = boost::lexical_cast(row[0]); result.datetime = Datetime(d); result.openPrice = boost::lexical_cast(row[1]); result.highPrice = boost::lexical_cast(row[2]); diff --git a/hikyuu_cpp/hikyuu/data_driver/kdata/tdx/TdxKDataDriver.cpp b/hikyuu_cpp/hikyuu/data_driver/kdata/tdx/TdxKDataDriver.cpp index 84e1dc90..47212323 100644 --- a/hikyuu_cpp/hikyuu/data_driver/kdata/tdx/TdxKDataDriver.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/kdata/tdx/TdxKDataDriver.cpp @@ -13,21 +13,21 @@ namespace hku { struct TdxDayData { - hku_uint32 date; - hku_uint32 open; - hku_uint32 high; - hku_uint32 low; - hku_uint32 close; + uint32 date; + uint32 open; + uint32 high; + uint32 low; + uint32 close; float amount; - hku_uint32 vol; - hku_uint32 other; + uint32 vol; + uint32 other; Datetime getDatetime() { - return Datetime(hku_uint64(date) * 10000); + return Datetime(uint64(date) * 10000); } void toKRecord(KRecord& record) { - record.datetime = Datetime(hku_uint64(date) * 10000); + record.datetime = Datetime(uint64(date) * 10000); record.openPrice = price_t(open) * 0.01; record.highPrice = price_t(high) * 0.01; record.lowPrice = price_t(low) * 0.01; @@ -46,8 +46,8 @@ struct TdxMinData { float low; float close; float amount; - hku_uint32 vol; - hku_uint32 other; + uint32 vol; + uint32 other; Datetime getDatetime() { int tmp_date = date >> 11; diff --git a/hikyuu_cpp/hikyuu/db_connect/DBConnect.h b/hikyuu_cpp/hikyuu/db_connect/DBConnect.h new file mode 100644 index 00000000..29642183 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/DBConnect.h @@ -0,0 +1,19 @@ +/* + * DBManager.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-11 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_H +#define HIKYUU_DB_CONNECT_H + +#include "DBConnectBase.h" +#include "DBConnectPool.h" +#include "SQLStatementBase.h" +#include "TransAction.h" +#include "TableMacro.h" + +#endif /* HIKYUU_DB_CONNECT_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/DBConnectBase.h b/hikyuu_cpp/hikyuu/db_connect/DBConnectBase.h new file mode 100644 index 00000000..6acbd255 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/DBConnectBase.h @@ -0,0 +1,345 @@ +/* + * DBConnectBase.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-1 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_DBCONNECTBASE_H +#define HIKYUU_DB_CONNECT_DBCONNECTBASE_H + +#include "../DataType.h" +#include "../utilities/Parameter.h" +#include "SQLStatementBase.h" + +namespace hku { + +/** + * 数据驱动基类 + * @ingroup DataDriver + */ +class HKU_API DBConnectBase: public std::enable_shared_from_this { + PARAMETER_SUPPORT + +public: + DBConnectBase(const Parameter& param); + virtual ~DBConnectBase() = default; + + /** 开始事务 */ + void transaction(); + + /** 提交事务 */ + void commit(); + + /** 回滚事务 */ + void rollback(); + + //------------------------------------------------------------------------- + // 子类接口 + //------------------------------------------------------------------------- + /** 执行无返回结果的 SQL */ + virtual void exec(const string& sql_string) = 0; + + /** 获取 SQLStatement */ + virtual SQLStatementPtr getStatement(const string& sql_statement) = 0; + + /** 判断表是否存在 */ + virtual bool tableExist(const string& tablename) = 0; + + //------------------------------------------------------------------------- + // 模板方法 + //------------------------------------------------------------------------- + /** + * 保存或更新 通过 TABLE_BIND 绑定的表结构 + * 可由 driver 直接保存,示例如下: + * @code + * class TTT { + * TABLE_BIND(TTT, ttt_table, age, name) + * + * public: + * int age; + * string name; + * public: + * void save(const DBConnectPtr& driver) const { + * SQLStatementPtr st = driver->getStatement("insert into ttt (name, age) values (?,?)"); + * st->bind(0, name, age); + * st->exec(); + * } + * }; + * + * TEST_CASE("test_temp", "temp") { + * Parameter param; + * param.set("db", TST_DATA("test.db")); + * DBConnectPtr driver = make_shared(param); + * driver->exec("create table ttt (name, age)"); + * TTT a; + * a.name = "TTT"; + * a.age = 11; + * driver->save(a); + * } + * @endcode + * + */ + template + void save(const T& item); + + /** + * 批量保存 + * @param container 拥有迭代器的容器 + * @param autotrans 启动事务 + */ + template + void batchSave(Container& container, bool autotrans=true); + + /** + * 批量保存,迭代器中的数据必须是通过 TABLE_BIND 绑定的表模型 + * @param first 迭代器起始点 + * @param last 迭代器终止点 + * @param autotrans 启动事务 + */ + template + void batchSave(InputIterator first, InputIterator last, bool autotrans=true); + + /** + * 加载模型数据至指定的模型实例 + * @note 查询条件应只返回一条记录,如果有多条查询结果,将只取一条 + * @param item 指定的模型实例 + * @param where 查询条件,如:“id=1" + */ + template + void load(T& item, const string& where=""); + + /** + * 批量加载模型数据至容器(vector,list 等支持 push_back 的容器) + * @param container 指定容器 + * @param where 查询条件 + */ + template + void batchLoad(Container& container, const string& where=""); + + /** + * 批量更新 + * @param container 拥有迭代器的容器 + * @param autotrans 启动事务 + */ + template + void batchUpdate(Container& container, bool autotrans=true); + + /** + * 批量更新 + * @param first 迭代器起始点 + * @param last 迭代器终止点 + * @param autotrans 启动事务 + */ + template + void batchUpdate(InputIterator first, InputIterator last, bool autotrans=true); + + /** + * 批量保存或更新 + * @param container 拥有迭代器的容器 + * @param autotrans 启动事务 + */ + template + void batchSaveOrUpdate(Container& container, bool autotrans=true); + + /** + * 批量保存或更新 + * @param first 迭代器起始点 + * @param last 迭代器终止点 + * @param autotrans 启动事务 + */ + template + void batchSaveOrUpdate(InputIterator first, InputIterator last, bool autotrans=true); + + /** + * 查询单个整数,如:select count(*) from table + * @note sql 语句应只返回单个元素,否则将抛出异常,如多条记录、多个列 + * @param query 查询语句 + */ + int queryInt(const string& query); + +private: + DBConnectBase() = delete; +}; + +/** @ingroup DataDriver */ +typedef shared_ptr DBConnectPtr; + + +//------------------------------------------------------------------------- +// inline方法实现 +//------------------------------------------------------------------------- + +inline DBConnectBase::DBConnectBase(const Parameter& param): m_params(param) {} + +inline void DBConnectBase::transaction() { + exec("BEGIN TRANSACTION"); +} + +inline void DBConnectBase::commit() { + exec("COMMIT TRANSACTION"); +} + +inline void DBConnectBase::rollback() { + exec("ROLLBACK TRANSACTION"); +} + +inline int DBConnectBase::queryInt(const string& query) { + SQLStatementPtr st = getStatement(query); + st->exec(); + HKU_ASSERT_M((st->moveNext() && st->getNumColumns() == 1), + "query doesn't result in exactly 1 element"); + int result = 0; + st->getColumn(0, result); + HKU_ASSERT_M(!st->moveNext(), "query doesn't result in exactly 1 element"); + return result; +} + +//------------------------------------------------------------------------- +// 模板方法实现 +//------------------------------------------------------------------------- + +template +void DBConnectBase::save(const T& x) { + if (x.id() == 0) { + SQLStatementPtr st = getStatement(T::getInsertSQL()); + x.save(st); + st->exec(); + } else { + SQLStatementPtr st = getStatement(T::getUpdateSQL()); + x.update(st); + st->exec(); + } +} + +template +inline void DBConnectBase::batchSave(Container& container, bool autotrans) { + batchSave(container.begin(), container.end(), autotrans); +} + + +template +void DBConnectBase::batchSave(InputIterator first, InputIterator last, bool autotrans) { + SQLStatementPtr st = getStatement(InputIterator::value_type::getInsertSQL()); + if (autotrans) { + transaction(); + } + + try { + for (InputIterator iter = first; iter != last; ++iter) { + iter->save(st); + st->exec(); + } + + if (autotrans) { + commit(); + } + + } catch (std::exception& e) { + if (autotrans) { + rollback(); + } + HKU_THROW("failed batch save! sql: {}! {}", st->getSqlString(), e.what()); + + } catch (...) { + if (autotrans) { + rollback(); + } + HKU_THROW("failed batch save! sql: {}! Unknow error!", st->getSqlString()); + } +} + +template +void DBConnectBase::load(T& x, const string& where) { + std::ostringstream sql; + if (where != "") { + sql << T::getSelectSQL() << " where " << where << " limit 1"; + } else { + sql << T::getSelectSQL() << " limit 1"; + } + SQLStatementPtr st = getStatement(sql.str()); + st->exec(); + if(st->moveNext()) { + x.load(st); + } +} + +template +void DBConnectBase::batchLoad(Container& con, const string& where) { + std::ostringstream sql; + if (where != "") { + sql << Container::value_type::getSelectSQL() << " where " << where; + } else { + sql << Container::value_type::getSelectSQL(); + } + SQLStatementPtr st = getStatement(sql.str()); + st->exec(); + while (st->moveNext()) { + typename Container::value_type tmp; + tmp.load(st); + con.push_back(tmp); + } +} + +template +inline void DBConnectBase::batchUpdate(Container& container, bool autotrans) { + batchUpdate(container.begin(), container.end(), autotrans); +} + +template +void DBConnectBase::batchUpdate(InputIterator first, InputIterator last, bool autotrans) { + SQLStatementPtr st = getStatement(InputIterator::value_type::getUpdateSQL()); + if (autotrans) { + transaction(); + } + + try { + for (InputIterator iter = first; iter != last; ++iter) { + iter->update(st); + st->exec(); + } + + if (autotrans) { + commit(); + } + + } catch (std::exception& e) { + if (autotrans) { + rollback(); + } + HKU_THROW("failed batch save! sql: {}! {}", st->getSqlString(), e.what()); + + } catch (...) { + if (autotrans) { + rollback(); + } + HKU_THROW("failed batch save! sql: {}! Unknow error!", st->getSqlString()); + } +} + +template +void DBConnectBase::batchSaveOrUpdate(InputIterator first, InputIterator last, bool autotrans) { + vector save_list; + vector update_list; + for (auto iter = first; iter != last; ++iter) { + if (iter->id() == 0) { + save_list.push_back(*iter); + } else { + update_list.push_back(*iter); + } + } + + batchSave(save_list.begin(), save_list.end(), autotrans); + batchUpdate(update_list.begin(), update_list.end(), autotrans); +} + +template +inline void DBConnectBase::batchSaveOrUpdate(Container& container, bool autotrans) { + batchSaveOrUpdate(container.begin(), container.end(), autotrans); +} + +} /* namespace */ + +#endif /* HIKYUU_DB_CONNECT_DBCONNECTBASE_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.cpp b/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.cpp new file mode 100644 index 00000000..963deb1a --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.cpp @@ -0,0 +1,41 @@ +/* + * DBConnectPool.cpp + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-8-6 + * Author: fasiondog + */ + +#include "DBConnectPool.h" +#include "sqlite/SQLiteConnect.h" + +namespace hku { + +DBConnectPool::DBConnectPool(const Parameter& param, int size): m_param(param) { + HKU_ASSERT(size > 0); + for (int i = 0; i < size; i++) { + m_connectList.push_back(make_shared(param)); + } +} + +DBConnectPtr DBConnectPool::getDriver() noexcept { + std::lock_guard lock(m_mutex); + if (m_connectList.empty()) { + return DBConnectPtr(); + } + DBConnectPtr p = m_connectList.front(); + m_connectList.pop_front(); + return p; +} + +void DBConnectPool::returnDriver(DBConnectPtr& p) { + std::lock_guard lock(m_mutex); + if (p) { + m_connectList.push_back(std::move(p)); + } else { + HKU_WARN("Trying to return an empty pointer!"); + } +} + +} /* namespace */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.h b/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.h new file mode 100644 index 00000000..1a169447 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/DBConnectPool.h @@ -0,0 +1,79 @@ +/* + * DBConnectPool.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-8-5 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_DBCONNECTPOOL_H +#define HIKYUU_DB_CONNECT_DBCONNECTPOOL_H + +#include +#include "DBConnectBase.h" + +namespace hku { + +/** + * 数据驱动池(连接池) + * @ingroup DataDriver + */ +class HKU_API DBConnectPool { +public: + /** + * 构造函数 + * @param param 驱动参数 + * @param size 驱动池大小 + */ + DBConnectPool(const Parameter& param, int size=10); + + virtual ~DBConnectPool() = default; + + /** 获取数据驱动,如果当前无可用驱动,将返回空指针 */ + DBConnectPtr getDriver() noexcept; + + /** 归还数据驱动至驱动池 */ + void returnDriver(DBConnectPtr& p); + +private: + Parameter m_param; + std::mutex m_mutex; + std::list m_connectList; + +private: + DBConnectPool() = delete; + DBConnectPool(const DBConnectPool&) = delete; + DBConnectPool& operator=(const DBConnectPool&) = delete; +}; + + +/** + * 从池中获取驱动辅助工具,以保证退出作用域时能够及时归还驱动至驱动池 + * @ingroup DataDriver + */ +struct DataDriverGuard { + DataDriverGuard(DBConnectPool *pool): m_pool(pool) { + if (m_pool) { + m_driver = m_pool->getDriver(); + } + } + + ~DataDriverGuard() { + if (m_pool && m_driver) { + m_pool->returnDriver(m_driver); + } + } + + DBConnectPtr getDriver() { + return m_driver; + } + +private: + DBConnectPtr m_driver; + DBConnectPool *m_pool; +}; + +} /* namespace */ + +#endif /* HIKYUU_DB_CONNECT_DBCONNECTPOOL_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/SQLStatementBase.h b/hikyuu_cpp/hikyuu/db_connect/SQLStatementBase.h new file mode 100644 index 00000000..788348db --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/SQLStatementBase.h @@ -0,0 +1,248 @@ +/* + * SQLStatemantBase.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-11 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_SQLSTATEMENTBASE_H +#define HIKYUU_DB_CONNECT_SQLSTATEMENTBASE_H + +#include +#include "../DataType.h" + +namespace hku { + +class DBConnectBase; +typedef shared_ptr DBConnectPtr; + +class null_blob_exception: public exception { +public: + null_blob_exception(): exception("Blob is null!") {} +}; + +/** + * SQL Statement 基类 + * @ingroup DataDriver + */ +class HKU_API SQLStatementBase { +public: + SQLStatementBase(const DBConnectPtr& driver, const string& sql_statement); + + virtual ~SQLStatementBase() = default; + + /** 获取构建时传入的表达式SQL语句 */ + const string& getSqlString() const; + + /** 获取数据驱动 */ + DBConnectPtr getDriver() const; + + /** 当前 SQL 表达式是否有效 */ + bool isValid() const; + + /** 执行 SQL */ + void exec(); + + /** 移动至下一结果 */ + bool moveNext(); + + void bind(int idx); //bind_null + void bind(int idx, float item); + void bind(int idx, double item); + void bind(int idx, const string& item); + void bindBlob(int idx, const string& item); + + template + typename std::enable_if::is_integer>::type + bind(int idx, const T& item); + + template + typename std::enable_if::is_integer>::type + bind(int idx, const T& item); + + template + void bind(int idx, const T&, const Args&... rest); + + int getNumColumns() const; + + //void getColumn(int idx, int64& item); + void getColumn(int idx, double& item); + void getColumn(int idx, float& item); + void getColumn(int idx, string& item); + + template + typename std::enable_if::is_integer>::type + getColumn(int idx, T&); + + template + typename std::enable_if::is_integer>::type + getColumn(int idx, T&); + + template + void getColumn(int idx, T&, Args&... rest); + + //------------------------------------------------------------------------- + // 子类接口 + //------------------------------------------------------------------------- + virtual bool sub_isValid() const = 0; + virtual void sub_exec() = 0; + virtual bool sub_moveNext() = 0; + + virtual void sub_bindNull(int idx) = 0; + virtual void sub_bindInt(int idx, int64 value) = 0; + virtual void sub_bindDouble(int idx, double item) = 0; + virtual void sub_bindText(int idx, const string& item) = 0; + virtual void sub_bindBlob(int idx, const string& item) = 0; + + virtual int sub_getNumColumns() const = 0; + virtual void sub_getColumnAsInt64(int idx, int64&) = 0; + virtual void sub_getColumnAsDouble(int idx, double&) = 0; + virtual void sub_getColumnAsText(int idx, string&) = 0; + virtual void sub_getColumnAsBlob(int idx, string&) = 0; + +private: + SQLStatementBase() = delete; + +protected: + DBConnectPtr m_driver; + string m_sql_string; +}; + +/** @ingroup DataDriver */ +typedef shared_ptr SQLStatementPtr; + + +inline SQLStatementBase +::SQLStatementBase(const DBConnectPtr& driver, const string& sql_statement) +: m_driver(driver), m_sql_string(sql_statement) { + HKU_ASSERT_M(driver, "driver is null!"); +} + +inline const string& SQLStatementBase::getSqlString() const { + return m_sql_string; +} + +inline DBConnectPtr SQLStatementBase::getDriver() const { + return m_driver; +} + +inline bool SQLStatementBase::isValid() const { + return m_driver && sub_isValid() ? true : false; +} + +inline void SQLStatementBase::bind(int idx, float item) { + bind(idx, (double)item); +} + +inline void SQLStatementBase::exec() { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_exec(); +} + +inline bool SQLStatementBase::moveNext() { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + return sub_moveNext(); +} + +inline void SQLStatementBase::bind(int idx) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_bindNull(idx); +} + +inline void SQLStatementBase::bind(int idx, const string& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_bindText(idx, item); +} + +inline void SQLStatementBase::bind(int idx, double item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_bindDouble(idx, item); +} + +inline void SQLStatementBase::bindBlob(int idx, const string& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_bindBlob(idx, item); +} + +inline int SQLStatementBase::getNumColumns() const { + return sub_getNumColumns(); +} + +inline void SQLStatementBase::getColumn(int idx, double& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_getColumnAsDouble(idx, item); +} + +inline void SQLStatementBase::getColumn(int idx, float& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + double temp; + sub_getColumnAsDouble(idx, temp); + item = (float)temp; +} + +inline void SQLStatementBase::getColumn(int idx, string& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_getColumnAsText(idx, item); +} + +template +typename std::enable_if::is_integer>::type +SQLStatementBase::bind(int idx, const T& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + sub_bindInt(idx, item); +} + +template +typename std::enable_if::is_integer>::type +SQLStatementBase::bind(int idx, const T& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + using namespace dlib; + std::ostringstream sout; + boost::archive::binary_iarchive oa(sout); + oa << BOOST_SERIALIZATION_NVP(item); + const std::string& str = sout.str(); + sub_bindBlob(idx, str); +} + +template +typename std::enable_if::is_integer>::type +SQLStatementBase::getColumn(int idx, T& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + int64 temp; + sub_getColumnAsInt64(idx, temp); + item = (T)temp; +} + +template +typename std::enable_if::is_integer>::type +SQLStatementBase::getColumn(int idx, T& item) { + HKU_ASSERT_M(isValid(), "Invalid statement!"); + using namespace dlib; + string tmp; + try { + sub_getColumnAsBlob(idx, tmp); + } catch (null_blob_exception&) { + return; + } + std::istringstream sin(tmp); + boost::archive::binary_iarchive ia(sin); + ia >> BOOST_SERIALIZATION_NVP(item); +} + +template +void SQLStatementBase::bind(int idx, const T& item, const Args&... rest) { + bind(idx, item); + bind(idx+1, rest...); +} + +template +void SQLStatementBase::getColumn(int i, T& item, Args&... rest) { + getColumn(i, item); + getColumn(i+1, rest...); +} + +} /* namespace */ + +#endif /* HIKYUU_DB_CONNECT_SQLSTATEMENTBASE_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/TableMacro.h b/hikyuu_cpp/hikyuu/db_connect/TableMacro.h new file mode 100644 index 00000000..31039221 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/TableMacro.h @@ -0,0 +1,618 @@ +/* + * TableMacro.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-14 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_TABLE_MACRO_H +#define HIKYUU_DB_CONNECT_TABLE_MACRO_H + +#include "DBConnectBase.h" +#include "SQLStatementBase.h" + +namespace hku { + +#define TABLE_BIND1(table, f1) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`) values (?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0, f1, m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1); \ + } + +#define TABLE_BIND2(table, f1, f2) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`) values (?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1, f2); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0, f1, f2, m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2); \ + } + +#define TABLE_BIND3(table, f1, f2, f3) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`) values (?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3"` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1, f2, f3); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0, f1, f2, f3, m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1, f2, f3);\ + } + +#define TABLE_BIND4(table, f1, f2, f3, f4) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`) values (?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0,m_id,f1,f2,f3,f4); \ + } + +#define TABLE_BIND5(table, f1, f2, f3, f4, f5) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 "`) values (?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5); \ + } + +#define TABLE_BIND6(table, f1,f2,f3,f4,f5,f6) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 \ + "`) values (?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 \ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 \ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6); \ + } + +#define TABLE_BIND7(table, f1,f2,f3,f4,f5,f6,f7) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7\ + "`) values (?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 \ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7); \ + } + +#define TABLE_BIND8(table, f1,f2,f3,f4,f5,f6,f7,f8) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8\ + "`) values (?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 \ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8); \ + } + +#define TABLE_BIND9(table, f1,f2,f3,f4,f5,f6,f7,f8,f9) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9\ + "`) values (?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 \ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9); \ + } + +#define TABLE_BIND10(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10\ + "`) values (?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10); \ + } + +#define TABLE_BIND11(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11\ + "`) values (?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11); \ + } + +#define TABLE_BIND12(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12); \ + } + +#define TABLE_BIND13(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13); \ + } + +#define TABLE_BIND14(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14); \ + } + +#define TABLE_BIND15(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15); \ + } + +#define TABLE_BIND16(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15 "`=?,`" #f16\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16); \ + } + +#define TABLE_BIND17(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15 "`=?,`" #f16 "`=?,`" #f17\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17); \ + } + +#define TABLE_BIND18(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15 "`=?,`" #f16 "`=?,`" #f17\ + "`=?,`" #f18\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18); \ + } + +#define TABLE_BIND19(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18 "`,`" #f19\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15 "`=?,`" #f16 "`=?,`" #f17\ + "`=?,`" #f18 "`=?,`" #f19\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18 "`,`" #f19\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19); \ + } + +#define TABLE_BIND20(table, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20) \ +private: \ + int64 m_id = 0; \ +public: \ + int64 id() const { return m_id; } \ + static const char * getInsertSQL() {\ + return "insert into `" #table "` (`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18 "`,`" #f19 "`,`" #f20\ + "`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";\ + }\ + static const char * getUpdateSQL() {\ + return "update `" #table "` set `" #f1 "`=?,`" #f2 "`=?,`" #f3 "`=?,`" #f4 "`=?,`" #f5 \ + "`=?,`" #f6 "`=?,`" #f7 "`=?,`" #f8 "`=?,`" #f9 "`=?,`" #f10 "`=?,`" #f11\ + "`=?,`" #f12 "`=?,`" #f13 "`=?,`" #f14 "`=?,`" #f15 "`=?,`" #f16 "`=?,`" #f17\ + "`=?,`" #f18 "`=?,`" #f19 "`=?,`" #f20\ + "`=? where `id`=?";\ + }\ + static const char * getSelectSQL() {\ + return "select `id`,`" #f1 "`,`" #f2 "`,`" #f3 "`,`" #f4 "`,`" #f5 \ + "`,`" #f6 "`,`" #f7 "`,`" #f8 "`,`" #f9 "`,`" #f10 "`,`" #f11 "`,`" #f12\ + "`,`" #f13 "`,`" #f14 "`,`" #f15 "`,`" #f16 "`,`" #f17 "`,`" #f18 "`,`" #f19 "`,`" #f20\ + "` from `" #table "`";\ + }\ + void save(const SQLStatementPtr& st) const { \ + st->bind(0, f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20); \ + }\ + void update(const SQLStatementPtr& st) const { \ + st->bind(0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,m_id); \ + }\ + void load(const SQLStatementPtr& st) {\ + st->getColumn(0, m_id,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f20); \ + } + +} /* namespace */ + +#endif /* HIKYUU_DB_CONNECT_TABLE_MACRO_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/TransAction.h b/hikyuu_cpp/hikyuu/db_connect/TransAction.h new file mode 100644 index 00000000..a0dcc2a6 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/TransAction.h @@ -0,0 +1,51 @@ +/* + * TransAction.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-11 + * Author: fasiondog + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_TRANSACTION_H +#define HIKYUU_DB_CONNECT_TRANSACTION_H + +#include "DBConnectBase.h" + +namespace hku { + +/** + * 自动事务处理,在代码块中自动启动事务,并在代码块退出后自动提交 + * @code + * try { + * TransAction trans(driver); + * ... + * } catch (...) { + * driver->rollback(); + * } + * @endcode + * @note 事务提交失败时,这里并没有处理回滚 + * @ingroup DataDriver + */ +class TransAction { +public: + TransAction(const DBConnectPtr& driver) : m_driver(driver) { + m_driver->transaction(); + } + + ~TransAction() { + m_driver->commit(); + } + +private: + TransAction() = delete; + TransAction(const TransAction&) = delete; + TransAction& operator=(const TransAction&) = delete; + +private: + DBConnectPtr m_driver; +}; + +} /* namespace */ + +#endif /* HIKYUU_DB_CONNECT_TRANSACTION_H */ diff --git a/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.cpp b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.cpp new file mode 100644 index 00000000..3de9955d --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.cpp @@ -0,0 +1,95 @@ +/* + * SQLiteConnect.cpp + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-1 + * Author: fasiondog + */ + +#include "../../config.h" +#include "../../Log.h" +#include "SQLiteConnect.h" +#include "SQLiteStatement.h" + +namespace hku { + +class Sqlite3Closer{ +public: + void operator()(sqlite3 *db){ + if(db){ + sqlite3_close(db); +/*#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, "YIHUA", "Closed Sqlite3 database!"); +#else + //don't use log output(HKU_TRACE...) when exiting! + std::cout << "Closed Sqlite3 database!" << std::endl; +#endif*/ + } + } +}; + +// sqlite3 多线程处理时,等待其他锁释放回调处理 +static int sqlite_busy_call_back(void *ptr, int count) { + //std::this_thread::sleep_for(std::chrono::milliseconds(200)); + std::this_thread::yield(); + return 1; +} + +SQLiteConnect::SQLiteConnect(const Parameter& param): DBConnectBase(param) { + try { + m_dbname = getParam("db"); + int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; + // 多线程模式下,不同数据库连接不能使用 SQLITE_OPEN_SHAREDCACHE + // 将导致 table is locked! + //| SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE; + if (haveParam("flags")) { + flags = getParam("flags"); + } + sqlite3 *db = NULL; + int rc = sqlite3_open_v2(m_dbname.c_str(), &db, flags, NULL); + if (rc != SQLITE_OK) { + sqlite3_close(db); + throw exception(sqlite3_errmsg(db)); + } + m_db.reset(db, Sqlite3Closer()); + sqlite3_busy_handler(db, sqlite_busy_call_back, (void *)db); + + } catch (std::out_of_range& e) { + HKU_THROW("Can't get database name! {}", e.what()); + } catch (hku::exception& e) { + HKU_THROW("Failed initialize data driver({})! SQLite3 error: {}", m_dbname, e.what()); + } catch (std::exception& e) { + HKU_THROW("Failed initialize data driver({})! exception: {}", m_dbname, e.what()); + } catch (...) { + HKU_THROW("Failed open database({})! Unkown error!", m_dbname); + } +} + +void SQLiteConnect::exec(const string& sql_string) { + HKU_ASSERT_M(m_db, "database is not open! {}", m_dbname); + int rc = sqlite3_exec(m_db.get(), sql_string.c_str(), NULL, NULL, NULL); + HKU_ASSERT_M(rc == SQLITE_OK, "SQL error: {}! ({})", sqlite3_errmsg(m_db.get()), sql_string); +} + +SQLStatementPtr SQLiteConnect::getStatement(const string& sql_statement) { + return make_shared(shared_from_this(), sql_statement); +} + +bool SQLiteConnect::tableExist(const string& tablename) { + std::ostringstream sql; + sql << "select count(1) from sqlite_master where name = '" << tablename << "'"; + SQLStatementPtr st = getStatement(sql.str()); + st->exec(); + bool result = false; + if (st->moveNext()) { + int tmp; + st->getColumn(0, tmp); + if (tmp == 1) { + result = true; + } + } + return result;; +} + +} /* namespace hku */ diff --git a/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.h b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.h new file mode 100644 index 00000000..68d60e8e --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteConnect.h @@ -0,0 +1,45 @@ +/* + * SQLiteConnect.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-1 + * Author: fasiondog + */ +#pragma once +#ifndef HIYUU_DB_CONNECT_SQLITE_SQLITECONNECT_H +#define HIYUU_DB_CONNECT_SQLITE_SQLITECONNECT_H + +#include +#include "../DBConnectPool.h" +#include "SQLiteStatement.h" + +namespace hku { + +/** + * @defgroup SQLite SQLite3 driver SQLITE3 数据驱动 + * @ingroup DataDriver + */ + +/** + * @ingroup SQLite + */ +class HKU_API SQLiteConnect: public DBConnectBase { +public: + SQLiteConnect(const Parameter& param); + virtual ~SQLiteConnect() {} + + virtual void exec(const string& sql_string); + virtual SQLStatementPtr getStatement(const string& sql_statement); + virtual bool tableExist(const string& tablename); + +private: + friend class SQLiteStatement; + + string m_dbname; + shared_ptr m_db; +}; + +} /* namespace */ + +#endif /* HIYUU_DB_MANAGER_SQLITE_SQLITECONNECT_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.cpp b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.cpp new file mode 100644 index 00000000..89ea3a1e --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.cpp @@ -0,0 +1,139 @@ +/* + * SQLiteStatement.cpp + * + * Copyright (c) 2019, hiyuu.org + * + * Created on: 2019-7-11 + * Author: linjinhai + */ + +#include "SQLiteStatement.h" +#include "SQLiteConnect.h" + +namespace hku { + +SQLiteStatement +::SQLiteStatement(const DBConnectPtr& driver, const string& sql_statement) +: SQLStatementBase(driver, sql_statement), + m_needs_reset(false), + m_step_status(SQLITE_DONE), + m_at_first_step(true), + m_stmt(NULL) { + m_db = (dynamic_cast(driver.get()))->m_db; + int status = sqlite3_prepare_v2(m_db.get(), + m_sql_string.c_str(), + m_sql_string.size()+1, + &m_stmt, + NULL); + if (status != SQLITE_OK) { + sqlite3_finalize(m_stmt); + HKU_THROW(sqlite3_errmsg(m_db.get())); + } + + HKU_ASSERT_M(m_stmt != 0, "Invalid SQL statement: {}", m_sql_string); +} + +SQLiteStatement::~SQLiteStatement() { + sqlite3_finalize(m_stmt); +} + +void SQLiteStatement::_reset() { + if (m_needs_reset) { + if (sqlite3_reset(m_stmt) != SQLITE_OK) { + m_step_status = SQLITE_DONE; + HKU_THROW(sqlite3_errmsg(m_db.get())); + } + m_needs_reset = false; + m_step_status = SQLITE_DONE; + m_at_first_step = true; + } +} + +void SQLiteStatement::sub_exec() { + _reset(); + m_step_status = sqlite3_step(m_stmt); + m_needs_reset = true; + if (m_step_status != SQLITE_DONE && m_step_status != SQLITE_ROW) { + HKU_THROW(sqlite3_errmsg(m_db.get())); + } +} + +bool SQLiteStatement::sub_moveNext () { + if (m_step_status == SQLITE_ROW) { + if (m_at_first_step) { + m_at_first_step = false; + return true; + } else { + m_step_status = sqlite3_step(m_stmt); + if (m_step_status == SQLITE_DONE) { + return false; + } else if (m_step_status == SQLITE_ROW) { + return true; + } else { + HKU_THROW(sqlite3_errmsg(m_db.get())); + } + } + } else { + return false; + } +} + +int SQLiteStatement::sub_getNumColumns() const { + return (m_at_first_step == false) && (m_step_status == SQLITE_ROW) + ? sqlite3_column_count(m_stmt) + : 0; +} + +void SQLiteStatement::sub_bindNull(int idx) { + _reset(); + int status = sqlite3_bind_null(m_stmt, idx+1); + HKU_ASSERT_M(status == SQLITE_OK, sqlite3_errmsg(m_db.get())); +} + +void SQLiteStatement::sub_bindInt(int idx, int64 value) { + _reset(); + int status = sqlite3_bind_int64(m_stmt, idx+1, value); + HKU_ASSERT_M(status == SQLITE_OK, sqlite3_errmsg(m_db.get())); +} + +void SQLiteStatement::sub_bindText(int idx, const string& item) { + _reset(); + int status = sqlite3_bind_text(m_stmt, idx+1, item.c_str(), -1, SQLITE_TRANSIENT); + HKU_ASSERT_M(status == SQLITE_OK, sqlite3_errmsg(m_db.get())); +} + +void SQLiteStatement::sub_bindDouble(int idx, double item) { + _reset(); + int status = sqlite3_bind_double(m_stmt, idx+1, item); + HKU_ASSERT_M(status == SQLITE_OK, sqlite3_errmsg(m_db.get())); +} + +void SQLiteStatement::sub_bindBlob(int idx, const string& item) { + _reset(); + int status = sqlite3_bind_blob(m_stmt, idx+1, item.data(), item.size(), SQLITE_TRANSIENT); + HKU_ASSERT_M(status == SQLITE_OK, sqlite3_errmsg(m_db.get())); +} + +void SQLiteStatement::sub_getColumnAsInt64(int idx, int64& item) { + item = sqlite3_column_int64(m_stmt, idx); +} + +void SQLiteStatement::sub_getColumnAsDouble(int idx, double& item) { + item = sqlite3_column_double(m_stmt, idx); +} + +void SQLiteStatement::sub_getColumnAsText(int idx, string& item) { + const char* data = reinterpret_cast(sqlite3_column_text(m_stmt, idx)); + item = (data != 0) ? string(data) : string(); +} + +void SQLiteStatement::sub_getColumnAsBlob(int idx, string& item) { + const char* data = static_cast(sqlite3_column_blob(m_stmt, idx)); + if (data == NULL) { + throw null_blob_exception(); + } + const int size = sqlite3_column_bytes(m_stmt, idx); + item = std::string(data,size); +} + +} /* namespace */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.h b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.h new file mode 100644 index 00000000..c7df6004 --- /dev/null +++ b/hikyuu_cpp/hikyuu/db_connect/sqlite/SQLiteStatement.h @@ -0,0 +1,61 @@ +/* + * SQLiteStatement.h + * + * Copyright (c) 2019, hikyuu.org + * + * Created on: 2019-7-11 + * Author: linjinhai + */ +#pragma once +#ifndef HIKYUU_DB_CONNECT_SQLITE_SQLITESTATEMENT_H +#define HIKYUU_DB_CONNECT_SQLITE_SQLITESTATEMENT_H + +#include +#include "../SQLStatementBase.h" + +namespace hku { + +/** + * SQLite Statemen + * @ingroup SQLite + */ +class HKU_API SQLiteStatement: public SQLStatementBase { +public: + SQLiteStatement() = delete; + SQLiteStatement(const DBConnectPtr& driver, const string& sql_statement); + virtual ~SQLiteStatement(); + + virtual bool sub_isValid() const; + virtual void sub_exec(); + virtual bool sub_moveNext(); + + virtual void sub_bindNull(int idx); + virtual void sub_bindInt(int idx, int64 value); + virtual void sub_bindDouble(int idx, double item); + virtual void sub_bindText(int idx, const string& item); + virtual void sub_bindBlob(int idx, const string& item); + + virtual int sub_getNumColumns() const; + virtual void sub_getColumnAsInt64(int idx, int64& item); + virtual void sub_getColumnAsDouble(int idx, double& item); + virtual void sub_getColumnAsText(int idx, string& item); + virtual void sub_getColumnAsBlob(int idx, string& item); + +private: + void _reset(); + +private: + bool m_needs_reset; // true if sqlite3_step() has been called more recently than sqlite3_reset() + int m_step_status; + bool m_at_first_step; + shared_ptr m_db; + sqlite3_stmt* m_stmt; +}; + +inline bool SQLiteStatement::sub_isValid() const { + return m_stmt ? true : false; +} + +} /* namespace hku */ + +#endif /* HIKYUU_DB_CONNECT_SQLITE_SQLITESTATEMENT_H */ \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp index 105e48b3..98592cff 100644 --- a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp +++ b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp @@ -794,7 +794,7 @@ void IndicatorImp::execute_mod() { if (m_right->get(i-diff, r) == 0.0) { _set(Null(), i, r); } else { - _set(hku_int64(m_left->get(i, r)) % hku_int64(m_right->get(i-diff, r)), i, r); + _set(int64(m_left->get(i, r)) % int64(m_right->get(i-diff, r)), i, r); } } } @@ -804,7 +804,7 @@ void IndicatorImp::execute_mod() { if (m_right->get(i, r) == 0.0) { _set(Null(), i, r); } else { - _set(hku_int64(m_left->get(i-diff, r)) % hku_int64(m_right->get(i, r)), i, r); + _set(int64(m_left->get(i-diff, r)) % int64(m_right->get(i, r)), i, r); } } } diff --git a/hikyuu_cpp/hikyuu/serialization/KQuery_serialization.h b/hikyuu_cpp/hikyuu/serialization/KQuery_serialization.h index be048c55..d169a874 100644 --- a/hikyuu_cpp/hikyuu/serialization/KQuery_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/KQuery_serialization.h @@ -31,13 +31,13 @@ void save(Archive & ar, const hku::KQuery & query, unsigned int version) { ar & BOOST_SERIALIZATION_NVP(recoverType); if (query.queryType() == hku::KQuery::INDEX) { - hku::hku_int64 start = query.start(); - hku::hku_int64 end = query.end(); + hku::int64 start = query.start(); + hku::int64 end = query.end(); ar & BOOST_SERIALIZATION_NVP(start); ar & BOOST_SERIALIZATION_NVP(end); } else if (query.queryType() == hku::KQuery::DATE) { - hku::hku_uint64 start = query.startDatetime().number(); - hku::hku_uint64 end = query.endDatetime().number(); + hku::uint64 start = query.startDatetime().number(); + hku::uint64 end = query.endDatetime().number(); ar & BOOST_SERIALIZATION_NVP(start); ar & BOOST_SERIALIZATION_NVP(end); } else { @@ -57,12 +57,12 @@ void load(Archive & ar, hku::KQuery& query, unsigned int version) { hku::KQuery::RecoverType enum_recover = hku::KQuery::getRecoverTypeEnum(recoverType); if (enum_query == hku::KQuery::INDEX) { - hku::hku_int64 start, end; + hku::int64 start, end; ar & BOOST_SERIALIZATION_NVP(start); ar & BOOST_SERIALIZATION_NVP(end); query = hku::KQuery(start, end, enmu_ktype, enum_recover); } else if (enum_query == hku::KQuery::DATE) { - hku::hku_uint64 start, end; + hku::uint64 start, end; ar & BOOST_SERIALIZATION_NVP(start); ar & BOOST_SERIALIZATION_NVP(end); query = hku::KQueryByDate(hku::Datetime(start), hku::Datetime(end), diff --git a/hikyuu_cpp/hikyuu/serialization/KRecord_serialization.h b/hikyuu_cpp/hikyuu/serialization/KRecord_serialization.h index fb93c38f..dad5eb10 100644 --- a/hikyuu_cpp/hikyuu/serialization/KRecord_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/KRecord_serialization.h @@ -21,7 +21,7 @@ namespace boost { namespace serialization { template void save(Archive & ar, const hku::KRecord& record, unsigned int version) { - hku::hku_uint64 datetime = record.datetime.number(); + hku::uint64 datetime = record.datetime.number(); ar & BOOST_SERIALIZATION_NVP(datetime); ar & make_nvp("openPrice", record.openPrice); ar & make_nvp("highPrice", record.highPrice); @@ -33,7 +33,7 @@ void save(Archive & ar, const hku::KRecord& record, unsigned int version) { template void load(Archive & ar, hku::KRecord& record, unsigned int version) { - hku::hku_uint64 datetime; + hku::uint64 datetime; ar & BOOST_SERIALIZATION_NVP(datetime); record.datetime = hku::Datetime(datetime); ar & make_nvp("openPrice", record.openPrice); diff --git a/hikyuu_cpp/hikyuu/serialization/MarketInfo_serialization.h b/hikyuu_cpp/hikyuu/serialization/MarketInfo_serialization.h index 885bd27f..0db3a493 100644 --- a/hikyuu_cpp/hikyuu/serialization/MarketInfo_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/MarketInfo_serialization.h @@ -46,7 +46,7 @@ void save(Archive & ar, const hku::MarketInfo& record, unsigned int version) { hku::string name = HKU_GB_TO_UTF8(record.name()); hku::string description = HKU_GB_TO_UTF8(record.description()); hku::string code = record.code(); - hku::hku_uint64 lastDate = record.lastDate().number(); + hku::uint64 lastDate = record.lastDate().number(); ar & BOOST_SERIALIZATION_NVP(market); ar & BOOST_SERIALIZATION_NVP(name); ar & BOOST_SERIALIZATION_NVP(description); @@ -57,7 +57,7 @@ void save(Archive & ar, const hku::MarketInfo& record, unsigned int version) { template void load(Archive & ar, hku::MarketInfo& record, unsigned int version) { hku::string market, name, description, code; - hku::hku_uint64 lastDate; + hku::uint64 lastDate; ar & BOOST_SERIALIZATION_NVP(market); ar & BOOST_SERIALIZATION_NVP(name); ar & BOOST_SERIALIZATION_NVP(description); diff --git a/hikyuu_cpp/hikyuu/serialization/StockTypeInfo_serialization.h b/hikyuu_cpp/hikyuu/serialization/StockTypeInfo_serialization.h index 1207cf98..f2dfc668 100644 --- a/hikyuu_cpp/hikyuu/serialization/StockTypeInfo_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/StockTypeInfo_serialization.h @@ -41,7 +41,7 @@ namespace serialization { template void save(Archive & ar, const hku::StockTypeInfo& record, unsigned int version) { - hku::hku_uint32 type = record.type(); + hku::uint32 type = record.type(); hku::string description = HKU_GB_TO_UTF8(record.description()); hku::price_t tick = record.tick(); hku::price_t tickValue = record.tickValue(); @@ -59,7 +59,7 @@ void save(Archive & ar, const hku::StockTypeInfo& record, unsigned int version) template void load(Archive & ar, hku::StockTypeInfo& record, unsigned int version) { - hku::hku_uint32 type; + hku::uint32 type; hku::string description; hku::price_t tick, tickValue; int precision; diff --git a/hikyuu_cpp/hikyuu/serialization/StockWeight_serialization.h b/hikyuu_cpp/hikyuu/serialization/StockWeight_serialization.h index f132bea3..f7ed6efb 100644 --- a/hikyuu_cpp/hikyuu/serialization/StockWeight_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/StockWeight_serialization.h @@ -21,7 +21,7 @@ namespace boost { namespace serialization { template void save(Archive & ar, const hku::StockWeight& record, unsigned int version) { - hku::hku_uint64 datetime = record.datetime().number(); + hku::uint64 datetime = record.datetime().number(); hku::price_t countAsGift = record.countAsGift(); hku::price_t countForSell = record.countForSell(); hku::price_t priceForSell = record.priceForSell(); @@ -41,7 +41,7 @@ void save(Archive & ar, const hku::StockWeight& record, unsigned int version) { template void load(Archive & ar, hku::StockWeight& record, unsigned int version) { - hku::hku_uint64 datetime; + hku::uint64 datetime; hku::price_t countAsGift, countForSell, priceForSell, bonus; hku::price_t increasement, totalCount, freeCount; ar & BOOST_SERIALIZATION_NVP(datetime); diff --git a/hikyuu_cpp/hikyuu/serialization/TimeLineRecord_serialization.h b/hikyuu_cpp/hikyuu/serialization/TimeLineRecord_serialization.h index 4e59bd37..8c56f0a6 100644 --- a/hikyuu_cpp/hikyuu/serialization/TimeLineRecord_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/TimeLineRecord_serialization.h @@ -21,7 +21,7 @@ namespace boost { namespace serialization { template void save(Archive & ar, const hku::TimeLineRecord& record, unsigned int version) { - hku::hku_uint64 datetime = record.datetime.number(); + hku::uint64 datetime = record.datetime.number(); ar & BOOST_SERIALIZATION_NVP(datetime); ar & make_nvp("price", record.price); ar & make_nvp("vol", record.vol); @@ -29,7 +29,7 @@ void save(Archive & ar, const hku::TimeLineRecord& record, unsigned int version) template void load(Archive & ar, hku::TimeLineRecord& record, unsigned int version) { - hku::hku_uint64 datetime; + hku::uint64 datetime; ar & BOOST_SERIALIZATION_NVP(datetime); record.datetime = hku::Datetime(datetime); ar & make_nvp("price", record.price); diff --git a/hikyuu_cpp/hikyuu/serialization/TransRecord_serialization.h b/hikyuu_cpp/hikyuu/serialization/TransRecord_serialization.h index 0366f216..454aee0a 100644 --- a/hikyuu_cpp/hikyuu/serialization/TransRecord_serialization.h +++ b/hikyuu_cpp/hikyuu/serialization/TransRecord_serialization.h @@ -21,7 +21,7 @@ namespace boost { namespace serialization { template void save(Archive & ar, const hku::TransRecord& record, unsigned int version) { - hku::hku_uint64 datetime = record.datetime.number(); + hku::uint64 datetime = record.datetime.number(); ar & BOOST_SERIALIZATION_NVP(datetime); ar & make_nvp("price", record.price); ar & make_nvp("vol", record.vol); @@ -30,7 +30,7 @@ void save(Archive & ar, const hku::TransRecord& record, unsigned int version) { template void load(Archive & ar, hku::TransRecord& record, unsigned int version) { - hku::hku_uint64 datetime; + hku::uint64 datetime; ar & BOOST_SERIALIZATION_NVP(datetime); record.datetime = hku::Datetime(datetime); ar & make_nvp("price", record.price); diff --git a/hikyuu_cpp/hikyuu/trade_manage/BorrowRecord.h b/hikyuu_cpp/hikyuu/trade_manage/BorrowRecord.h index 5d2cc08e..4fd6e788 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/BorrowRecord.h +++ b/hikyuu_cpp/hikyuu/trade_manage/BorrowRecord.h @@ -46,7 +46,7 @@ public: friend class boost::serialization::access; template void save(Archive & ar, const unsigned int version) const { - hku_uint64 datetime_num = datetime.number(); + uint64 datetime_num = datetime.number(); ar & boost::serialization::make_nvp("datetime", datetime_num); ar & BOOST_SERIALIZATION_NVP(number); ar & BOOST_SERIALIZATION_NVP(price); @@ -54,7 +54,7 @@ public: template void load(Archive & ar, const unsigned int version) { - hku_uint64 datetime_num; + uint64 datetime_num; ar & boost::serialization::make_nvp("datetime", datetime_num); datetime = Datetime(datetime_num); ar & BOOST_SERIALIZATION_NVP(number); diff --git a/hikyuu_cpp/hikyuu/trade_manage/LoanRecord.h b/hikyuu_cpp/hikyuu/trade_manage/LoanRecord.h index 89d9a208..a1cc6f48 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/LoanRecord.h +++ b/hikyuu_cpp/hikyuu/trade_manage/LoanRecord.h @@ -38,7 +38,7 @@ private: template void save(Archive & ar, const unsigned int version) const { namespace bs = boost::serialization; - hku::hku_uint64 date_number = datetime.number(); + hku::uint64 date_number = datetime.number(); ar & bs::make_nvp("datetime", date_number); ar & BOOST_SERIALIZATION_NVP(value); } @@ -46,7 +46,7 @@ private: template void load(Archive & ar, const unsigned int version) { namespace bs = boost::serialization; - hku::hku_uint64 date_number; + hku::uint64 date_number; ar & bs::make_nvp("datetime", date_number); datetime = Datetime(date_number); ar & BOOST_SERIALIZATION_NVP(value); diff --git a/hikyuu_cpp/hikyuu/trade_manage/PositionRecord.h b/hikyuu_cpp/hikyuu/trade_manage/PositionRecord.h index a87209a9..dc83a6c7 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/PositionRecord.h +++ b/hikyuu_cpp/hikyuu/trade_manage/PositionRecord.h @@ -62,8 +62,8 @@ private: void save(Archive & ar, const unsigned int version) const { namespace bs = boost::serialization; ar & BOOST_SERIALIZATION_NVP(stock); - hku_uint64 take = takeDatetime.number(); - hku_uint64 clean = cleanDatetime.number(); + uint64 take = takeDatetime.number(); + uint64 clean = cleanDatetime.number(); ar & bs::make_nvp("takeDatetime", take); ar & bs::make_nvp("cleanDatetime", clean); ar & BOOST_SERIALIZATION_NVP(number); @@ -80,7 +80,7 @@ private: void load(Archive & ar, const unsigned int version) { namespace bs = boost::serialization; ar & BOOST_SERIALIZATION_NVP(stock); - hku_uint64 take, clean; + uint64 take, clean; ar & bs::make_nvp("takeDatetime", take); ar & bs::make_nvp("cleanDatetime", clean); takeDatetime = Datetime(take); diff --git a/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp index 72451ac2..4d7bcaab 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp +++ b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp @@ -1530,12 +1530,12 @@ FundsRecord TradeManager price_t checkout_cash = 0.0; price_t checkin_stock = 0.0; price_t checkout_stock = 0.0; - map stock_map; - map short_stock_map; - map::iterator stock_iter; - map::iterator short_stock_iter; - map bor_stock_map; - map::iterator bor_stock_iter; + map stock_map; + map short_stock_map; + map::iterator stock_iter; + map::iterator short_stock_iter; + map bor_stock_map; + map::iterator bor_stock_iter; TradeRecordList::const_iterator iter = m_trade_list.begin(); for (; iter != m_trade_list.end(); ++iter) { diff --git a/hikyuu_cpp/hikyuu/trade_manage/TradeManager.h b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.h index d24e049d..59366564 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/TradeManager.h +++ b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.h @@ -532,12 +532,12 @@ private: list m_loan_list; //当前融资情况 - typedef map borrow_stock_map_type; + typedef map borrow_stock_map_type; borrow_stock_map_type m_borrow_stock; //当前借入的股票及其数量 TradeRecordList m_trade_list; //交易记录 - typedef map position_map_type; + typedef map position_map_type; position_map_type m_position; //当前持仓交易对象的持仓记录 ["sh000001"-> ] PositionRecordList m_position_history; //持仓历史记录 position_map_type m_short_position; //空头仓位记录 diff --git a/hikyuu_cpp/hikyuu/trade_manage/TradeRecord.h b/hikyuu_cpp/hikyuu/trade_manage/TradeRecord.h index 13b43f02..81b433a3 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/TradeRecord.h +++ b/hikyuu_cpp/hikyuu/trade_manage/TradeRecord.h @@ -95,7 +95,7 @@ private: void save(Archive & ar, const unsigned int version) const { namespace bs = boost::serialization; ar & BOOST_SERIALIZATION_NVP(stock); - hku::hku_uint64 date_number = datetime.number(); + hku::uint64 date_number = datetime.number(); ar & bs::make_nvp("datetime", date_number); string business_name = getBusinessName(business); ar & bs::make_nvp("business", business_name); @@ -114,7 +114,7 @@ private: void load(Archive & ar, const unsigned int version) { namespace bs = boost::serialization; ar & BOOST_SERIALIZATION_NVP(stock); - hku::hku_uint64 date_number; + hku::uint64 date_number; ar & bs::make_nvp("datetime", date_number); datetime = Datetime(date_number); string business_name; diff --git a/hikyuu_cpp/hikyuu/trade_sys/system/TradeRequest.h b/hikyuu_cpp/hikyuu/trade_sys/system/TradeRequest.h index 9e3f389c..eaf98bbf 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/system/TradeRequest.h +++ b/hikyuu_cpp/hikyuu/trade_sys/system/TradeRequest.h @@ -47,7 +47,7 @@ private: ar & BOOST_SERIALIZATION_NVP(valid); string business_name(getBusinessName(business)); ar & bs::make_nvp("business", business_name); - hku_uint64 datetime_num = datetime.number(); + uint64 datetime_num = datetime.number(); ar & bs::make_nvp("datetime", datetime_num); ar & BOOST_SERIALIZATION_NVP(stoploss); ar & BOOST_SERIALIZATION_NVP(goal); @@ -65,7 +65,7 @@ private: string business_name; ar & bs::make_nvp("business", business_name); business = getBusinessEnum(business_name); - hku_uint64 datetime_num; + uint64 datetime_num; ar & bs::make_nvp("datetime", datetime_num); datetime = Datetime(datetime_num); ar & BOOST_SERIALIZATION_NVP(stoploss); diff --git a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_KData.cpp b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_KData.cpp index ae4cef63..c44a49a6 100644 --- a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_KData.cpp +++ b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_KData.cpp @@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001日线数据,KQuery(-total) */ total = stock.getCount(); - query = KQuery(-(hku_int64)total); + query = KQuery(-(int64)total); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 5121); BOOST_CHECK(kdata.empty() == false); @@ -313,7 +313,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001日线数据,KQuery(-total-1) */ total = stock.getCount(); - query = KQuery(-1-(hku_int64)total); + query = KQuery(-1-(int64)total); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 5121); BOOST_CHECK(kdata.empty() == false); @@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001日线数据,KQuery(-total + 1) */ total = stock.getCount(); - query = KQuery(1-(hku_int64)total); + query = KQuery(1-(int64)total); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 5120); BOOST_CHECK(kdata.empty() == false); @@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(kdata.lastPos() == 0); /** @arg SH000001日线数据,KQuery(-total, 1) */ - query = KQuery(-(hku_int64)total, 1); + query = KQuery(-(int64)total, 1); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 1); BOOST_CHECK(kdata.empty() == false); @@ -396,7 +396,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(record == expect); /** @arg SH000001日线数据,KQuery(-total, 2) */ - query = KQuery(-(hku_int64)total, 2); + query = KQuery(-(int64)total, 2); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 2); BOOST_CHECK(kdata.empty() == false); @@ -411,7 +411,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(record.datetime == Datetime(199012200000)); /** @arg SH000001日线数据,KQuery(0, -total) */ - query = KQuery(0, -(hku_int64)total); + query = KQuery(0, -(int64)total); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 0); BOOST_CHECK(kdata.empty() == true); @@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /// 测试分钟线 ///============================== /** @arg SH000001全部1分钟K线数据,KQuery(0) */ - query = KQuery(0, Null(), KQuery::MIN); + query = KQuery(0, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 682823L); record = kdata[0]; @@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001分钟线数据,KQuery(total-1) */ total = stock.getCount(KQuery::MIN); - query = KQuery(total - 1, Null(), KQuery::MIN); + query = KQuery(total - 1, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 1); record = kdata[0]; @@ -462,7 +462,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001分钟线数据,KQuery(total) */ total = stock.getCount(KQuery::MIN); - query = KQuery(total, Null(), KQuery::MIN); + query = KQuery(total, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 0); @@ -516,7 +516,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(kdata.size() == 0); /** @arg SH000001分钟线数据,KQuery(-1) */ - query = KQuery(-1, Null(), KQuery::MIN); + query = KQuery(-1, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 1); record = kdata[0]; @@ -524,7 +524,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001分钟线数据,KQuery(-total) */ total = stock.getCount(KQuery::MIN); - query = KQuery(-(hku_int64)total, Null(), KQuery::MIN); + query = KQuery(-(int64)total, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 682823); record = kdata[0]; @@ -535,7 +535,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001分钟线数据,KQuery(-total-1) */ total = stock.getCount(KQuery::MIN); - query = KQuery(-1-(hku_int64)total, Null(), KQuery::MIN); + query = KQuery(-1-(int64)total, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 682823); record = kdata[0]; @@ -546,7 +546,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { /** @arg SH000001分钟线数据,KQuery(-total + 1) */ total = stock.getCount(KQuery::MIN); - query = KQuery(1-(hku_int64)total, Null(), KQuery::MIN); + query = KQuery(1-(int64)total, Null(), KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 682822); record = kdata[0]; @@ -578,14 +578,14 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(kdata.size() == 0); /** @arg SH000001分钟线数据,KQuery(-total, 1) */ - query = KQuery(-(hku_int64)total, 1, KQuery::MIN); + query = KQuery(-(int64)total, 1, KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 1); record = kdata[0]; BOOST_CHECK(record.datetime == Datetime(200001040931)); /** @arg SH000001分钟线数据,KQuery(-total, 2) */ - query = KQuery(-(hku_int64)total, 2, KQuery::MIN); + query = KQuery(-(int64)total, 2, KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 2); record = kdata[0]; @@ -595,7 +595,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_by_index ) { BOOST_CHECK(record.datetime == Datetime(200001040932)); /** @arg SH000001分钟线数据,KQuery(0, -total) */ - query = KQuery(0, -(hku_int64)total, KQuery::MIN); + query = KQuery(0, -(int64)total, KQuery::MIN); kdata = stock.getKData(query); BOOST_CHECK(kdata.size() == 0); @@ -1188,7 +1188,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_recover ) { KData kdata; /** @arg 前向复权*/ - query = KQuery(0, Null(), KQuery::DAY, KQuery::FORWARD); + query = KQuery(0, Null(), KQuery::DAY, KQuery::FORWARD); kdata = stock.getKData(query); BOOST_CHECK(kdata[2710] == KRecord(Datetime(201106030000), 10.02, 10.14, 10.0, 10.09, 38726.1, 384820)); BOOST_CHECK(kdata[2709] == KRecord(Datetime(201106020000), 10.34, 10.38, 9.93, 10.04, 103909.3, 780543.0)); @@ -1197,7 +1197,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_recover ) { BOOST_CHECK(kdata[2547] == KRecord(Datetime(201009280000), 9.82, 9.82, 9.55, 9.55, 81241.5, 639882)); /** @arg 后向复权*/ - query = KQuery(0, Null(), KQuery::DAY, KQuery::BACKWARD); + query = KQuery(0, Null(), KQuery::DAY, KQuery::BACKWARD); kdata = stock.getKData(query); BOOST_CHECK(kdata[0] == KRecord(Datetime(199911100000), 29.5, 29.8, 27.0, 27.75, 485910.2, 1740850)); BOOST_CHECK(kdata[151] == KRecord(Datetime(200007050000), 23.25, 23.47, 23.15, 23.22, 3298.8, 14218)); @@ -1206,7 +1206,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_recover ) { BOOST_CHECK(kdata[658] == KRecord(Datetime(200208220000), 18.77, 18.89, 18.62, 18.81, 13101.3, 106872)); /** @arg 前向等比复权*/ - query = KQuery(0, Null(), KQuery::DAY, KQuery::EQUAL_FORWARD); + query = KQuery(0, Null(), KQuery::DAY, KQuery::EQUAL_FORWARD); kdata = stock.getKData(query); BOOST_CHECK(kdata[2710] == KRecord(Datetime(201106030000), 10.02, 10.14, 10.0, 10.09, 38726.1, 384820)); BOOST_CHECK(kdata[2709] == KRecord(Datetime(201106020000), 10.33, 10.37, 9.93, 10.04, 103909.3, 780543.0)); @@ -1215,7 +1215,7 @@ BOOST_AUTO_TEST_CASE( test_getKData_recover ) { BOOST_CHECK(kdata[2547] == KRecord(Datetime(201009280000), 9.82, 9.82, 9.55, 9.56, 81241.5, 639882)); /** @arg 等比后向复权*/ - query = KQuery(0, Null(), KQuery::DAY, KQuery::EQUAL_BACKWARD); + query = KQuery(0, Null(), KQuery::DAY, KQuery::EQUAL_BACKWARD); kdata = stock.getKData(query); BOOST_CHECK(kdata[0] == KRecord(Datetime(199911100000), 29.5, 29.8, 27.0, 27.75, 485910.2, 1740850)); BOOST_CHECK(kdata[151] == KRecord(Datetime(200007050000), 23.25, 23.47, 23.15, 23.22, 3298.8, 14218)); diff --git a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_Stock.cpp b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_Stock.cpp index fa142fb1..91c7712a 100644 --- a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_Stock.cpp +++ b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_Stock.cpp @@ -483,61 +483,61 @@ BOOST_AUTO_TEST_CASE( test_Stock_getIndexRange ) { BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 5121); - query = KQuery(0, Null(), KQuery::WEEK); + query = KQuery(0, Null(), KQuery::WEEK); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 1059); - query = KQuery(0, Null(), KQuery::MONTH); + query = KQuery(0, Null(), KQuery::MONTH); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 253); - query = KQuery(0, Null(), KQuery::QUARTER); + query = KQuery(0, Null(), KQuery::QUARTER); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 85); - query = KQuery(0, Null(), KQuery::HALFYEAR); + query = KQuery(0, Null(), KQuery::HALFYEAR); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 43); - query = KQuery(0, Null(), KQuery::YEAR); + query = KQuery(0, Null(), KQuery::YEAR); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 22); - query = KQuery(0, Null(), KQuery::MIN); + query = KQuery(0, Null(), KQuery::MIN); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 682823L); - query = KQuery(0, Null(), KQuery::MIN5); + query = KQuery(0, Null(), KQuery::MIN5); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 133980L); - query = KQuery(0, Null(), KQuery::MIN15); + query = KQuery(0, Null(), KQuery::MIN15); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 44750); - query = KQuery(0, Null(), KQuery::MIN30); + query = KQuery(0, Null(), KQuery::MIN30); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); BOOST_CHECK(out_end == 22380L); - query = KQuery(0, Null(), KQuery::MIN60); + query = KQuery(0, Null(), KQuery::MIN60); success = stock.getIndexRange(query, out_start, out_end); BOOST_CHECK(success == true); BOOST_CHECK(out_start == 0); diff --git a/hikyuu_pywrap/_Constant.cpp b/hikyuu_pywrap/_Constant.cpp index 5b767d69..b7e965dc 100644 --- a/hikyuu_pywrap/_Constant.cpp +++ b/hikyuu_pywrap/_Constant.cpp @@ -19,7 +19,7 @@ struct Constant { null_price(Null()), null_int(Null()), null_size(Null()), - null_int64(Null()), + null_int64(Null()), STOCKTYPE_BLOCK(0), STOCKTYPE_A(1), STOCKTYPE_INDEX(2), @@ -43,7 +43,7 @@ struct Constant { price_t null_price; int null_int; size_t null_size; - hku_int64 null_int64; + int64 null_int64; bool pickle_support; //是否支持pickle int STOCKTYPE_BLOCK; ///板块 diff --git a/hikyuu_pywrap/_KQuery.cpp b/hikyuu_pywrap/_KQuery.cpp index c1c6fdd7..2fa43009 100644 --- a/hikyuu_pywrap/_KQuery.cpp +++ b/hikyuu_pywrap/_KQuery.cpp @@ -20,7 +20,7 @@ void export_KQuery() { def("KQueryByIndex", KQueryByIndex, KQueryByIndex_overload()); scope in_Query = class_("KQuery", init<>()) - .def(init >()) + .def(init >()) .def(self_ns::str(self)) .add_property("start", &KQuery::start) .add_property("end", &KQuery::end) diff --git a/hikyuu_pywrap/_StockTypeInfo.cpp b/hikyuu_pywrap/_StockTypeInfo.cpp index 1c965591..b2454e40 100644 --- a/hikyuu_pywrap/_StockTypeInfo.cpp +++ b/hikyuu_pywrap/_StockTypeInfo.cpp @@ -14,7 +14,7 @@ using namespace hku; void export_StockTypeInfo() { class_("StockTypeInfo", init<>()) - .def(init()) + .def(init()) //.def(self_ns::str(self)) .def("__str__", &StockTypeInfo::toString) .add_property("type", &StockTypeInfo::type)