hikyuu2/hikyuu_cpp/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.cpp
2019-08-15 21:00:00 +08:00

448 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* SQLiteBaseInfoDriver.cpp
*
* Created on: 2012-8-14
* Author: fasiondog
*/
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include "SQLiteBaseInfoDriver.h"
#include "../../../utilities/util.h"
#include "../../../StockManager.h"
#include "../../../Log.h"
namespace hku {
class Sqlite3Closer{
public:
void operator()(sqlite3 *db){
if(db){
sqlite3_close(db);
//std::cout << "Closed Sqlite3 database!" << std::endl;
//Cannot use log output when exiting!
//HKU_TRACE("Closed Sqlite3 database!");
}
}
};
bool SQLiteBaseInfoDriver::_init() {
string dbname;
try {
dbname = getParam<string>("db");
HKU_TRACE("SQLITE3: {}", dbname);
} catch(...) {
HKU_ERROR("Can't get Sqlite3 filename!");
return false;
}
sqlite3 *db;
int rc=sqlite3_open_v2(dbname.c_str(), &db,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX,0);
if( rc ){
HKU_ERROR("Can't open database: err({}) - {}", sqlite3_errmsg(db), dbname);
sqlite3_close(db);
return false;
}
m_db = shared_ptr<sqlite3>(db, Sqlite3Closer());
return true;
}
bool SQLiteBaseInfoDriver::_loadMarketInfo() {
if (!m_db) {
return false;
}
list<MarketInfo> out;
char *zErrMsg=0;
int rc = sqlite3_exec(m_db.get(), "select market,name,"
"description,code,lastdate from market",
_getMarketTableCallBack, &out, &zErrMsg);
if( rc != SQLITE_OK ){
HKU_ERROR("SQL error: {}", zErrMsg);
sqlite3_free(zErrMsg);
return false;
}
StockManager& sm = StockManager::instance();
for (auto iter = out.begin(); iter != out.end(); ++iter) {
sm.loadMarketInfo(*iter);
}
return true;
}
//select market,name,description,code,lastdate from market
int SQLiteBaseInfoDriver::_getMarketTableCallBack(void *out,
int nCol, char **azVals, char **azCols) {
assert(nCol==5);
int result = 0;
uint64 d;
string market(azVals[0]);
to_upper(market);
try{
d = (boost::lexical_cast<uint64>(azVals[4])*10000);
Datetime datetime;
try {
datetime = Datetime(d);
} catch (std::out_of_range& e) {
datetime = Null<Datetime>();
HKU_WARN("LastDate of market({}) is invalid! Assigned to Null<Dateteim>!\n{}",
market, e.what());
}
MarketInfo marketInfo(market, HKU_STR(azVals[1]),
HKU_STR(azVals[2]), azVals[3], datetime);
((list<MarketInfo> *)out)->push_back(marketInfo);
result = 0;
} catch(boost::bad_lexical_cast& e){
HKU_ERROR("Can't get the information of market({})\n{}", market, e.what());
result = 1;
} catch(std::exception& e){
HKU_ERROR(e.what());
result = 1;
} catch(...) {
HKU_ERROR("Unkown error!");
result = 1;
}
return result;
}
bool SQLiteBaseInfoDriver::_loadStockTypeInfo() {
if (!m_db) {
return false;
}
list<StockTypeInfo> out;
char *zErrMsg=0;
int rc = sqlite3_exec(m_db.get(), "select type, description, tick, "
"tickValue, precision, minTradeNumber, "
"maxTradeNumber from StockTypeInfo",
_getStockTypeInfoTableCallBack, &out, &zErrMsg);
if( rc!=SQLITE_OK ){
HKU_ERROR("SQL error: {}", zErrMsg);
sqlite3_free(zErrMsg);
return false;
}
StockManager& sm = StockManager::instance();
for (auto iter = out.begin(); iter != out.end(); ++iter) {
sm.loadStockTypeInfo(*iter);
}
return true;
}
//select type,description,tick,precision,minTradeNumber,maxTradeNumber
//from stockTypeInfo
int SQLiteBaseInfoDriver::_getStockTypeInfoTableCallBack(
void *out, int nCol, char **azVals, char **azCols){
assert(nCol == 7);
int result = 0;
try{
uint32 type = boost::lexical_cast<uint32>(azVals[0]);
StockTypeInfo stockTypeInfo(
type, HKU_STR(azVals[1]),
boost::lexical_cast<price_t>(azVals[2]),
boost::lexical_cast<price_t>(azVals[3]),
boost::lexical_cast<int>(azVals[4]),
boost::lexical_cast<size_t>(azVals[5]),
boost::lexical_cast<size_t>(azVals[6]));
((list<StockTypeInfo> *)out)->push_back(stockTypeInfo);
result = 0;
} catch (boost::bad_lexical_cast& e) {
HKU_ERROR(e.what());
result = 1;
} catch (std::exception& e) {
HKU_ERROR(e.what());
result = 1;
} catch (...) {
HKU_ERROR("Unkown error!");
}
return result;
}
bool SQLiteBaseInfoDriver::_getStockWeightList(uint32 id,
StockWeightList& out) {
if (!m_db) {
return false;
}
char *zErrMsg=0;
std::stringstream buf (std::stringstream::out);
buf<<"select id, date, countAsGift, countForSell, priceForSell, bonus,\
countOfIncreasement, totalCount, freeCount from stkWeight \
where stockid=" << id << " order by date";
int rc = sqlite3_exec(m_db.get(), buf.str().c_str(),
_getStockWeightCallBack, &out, &zErrMsg);
if( rc!=SQLITE_OK ){
HKU_ERROR("SQL error: {}", zErrMsg);
sqlite3_free(zErrMsg);
return false;
}
return true;
}
//select id, date, countAsGift, countForSell, priceForSell,
//bobus, countOfIncreasement, totalCount, freeCount
//from stkweight where stockid=? order by date
int SQLiteBaseInfoDriver::_getStockWeightCallBack(
void *out, int nCol, char **azVals, char **azCols){
assert(nCol == 9);
int failure = 0;
int id = 0;
try{
id = boost::lexical_cast<int>(azVals[0]);
uint64 datetime;
datetime = boost::lexical_cast<uint64>(azVals[1]) * 10000;
StockWeight weight(Datetime(datetime),
boost::lexical_cast<price_t>(azVals[2]) * 0.0001,
boost::lexical_cast<price_t>(azVals[3]) * 0.0001,
boost::lexical_cast<price_t>(azVals[4]) * 0.001,
boost::lexical_cast<price_t>(azVals[5]) * 0.001,
boost::lexical_cast<price_t>(azVals[6]) * 0.0001,
boost::lexical_cast<price_t>(azVals[7]),
boost::lexical_cast<price_t>(azVals[8]));
((StockWeightList *)out)->push_back(weight);
failure = 0;
} catch (std::out_of_range& e) {
HKU_ERROR("Date of id({}) is invalid! {}", id, e.what());
//不返回失败,仅抛弃该条记录
} catch (boost::bad_lexical_cast& e){
HKU_ERROR("id({}) bad_lexical_cast{}", id, e.what());
failure = 1;
} catch (std::exception& e){
HKU_ERROR(e.what());
failure = 1;
} catch (...) {
HKU_ERROR("Unkown error!");
failure = 1;
}
return failure;
}
struct StockTable {
uint32 id;
string market;
string code;
string name;
uint32 type;
bool valid;
Datetime startDate;
Datetime endDate;
};
bool SQLiteBaseInfoDriver::_loadStock() {
if (!m_db) {
return false;
}
list<StockTable> stock_table;
char *zErrMsg=0;
int rc = sqlite3_exec(m_db.get(), "select stock.stockid,market.market,\
Stock.code,Stock.name,Stock.type,Stock.valid,Stock.startDate, \
Stock.endDate from Stock inner join Market \
on Stock.marketid = Market.marketid",
_getStockTableCallBack, &stock_table, &zErrMsg);
if (rc != SQLITE_OK) {
HKU_ERROR("SQL error: {}", zErrMsg);
sqlite3_free(zErrMsg);
return false;
}
Stock stock;
StockTypeInfo stockTypeInfo;
StockTypeInfo null_stockTypeInfo;
StockManager& sm = StockManager::instance();
list<StockTable>::iterator iter = stock_table.begin();
for(; iter != stock_table.end(); ++iter) {
stockTypeInfo = sm.getStockTypeInfo(iter->type);
if(stockTypeInfo != null_stockTypeInfo) {
stock = Stock(iter->market,
iter->code,
iter->name,
iter->type,
iter->valid,
iter->startDate,
iter->endDate,
stockTypeInfo.tick(),
stockTypeInfo.tickValue(),
stockTypeInfo.precision(),
stockTypeInfo.minTradeNumber(),
stockTypeInfo.maxTradeNumber());
} else {
stock = Stock(iter->market,
iter->code,
iter->name,
iter->type,
iter->valid,
iter->startDate,
iter->endDate);
}
if(sm.loadStock(stock)){
StockWeightList weightList;
_getStockWeightList(iter->id, weightList);
stock.setWeightList(weightList);
}
}
return true;
}
//select stock.stockid,market.market,stock.code,stock.name,stock.type,
//stock.valid,stock.startDate,stock.endDate from stock
//inner join market on stock.marketid = market.marketid
int SQLiteBaseInfoDriver::_getStockTableCallBack(
void *out, int nCol, char **azVals, char **azCols) {
assert(nCol == 8);
int result = 0;
StockTable stockRecord;
try {
stockRecord.id = boost::lexical_cast<uint32>(azVals[0]);
stockRecord.market = string(azVals[1]);
stockRecord.code = string(azVals[2]);
stockRecord.name = string(HKU_STR(azVals[3]));
stockRecord.type = boost::lexical_cast<uint32>(azVals[4]);
uint32 temp_valid = boost::lexical_cast<uint32>(azVals[5]);
stockRecord.valid = temp_valid > 0 ? true : false;
Datetime datetime;
uint64 startDate, endDate;
startDate = boost::lexical_cast<uint64>(azVals[6])*10000;
endDate = boost::lexical_cast<uint64>(azVals[7])*10000;
if(startDate > endDate || startDate == 0 || endDate == 0) {
//日期非法置为Null<Datetime>
stockRecord.startDate = Null<Datetime>();
stockRecord.endDate = Null<Datetime>();
} else {
stockRecord.startDate = (startDate == 999999990000LL)
? Null<Datetime>()
: Datetime(startDate);
stockRecord.endDate = (endDate == 999999990000LL)
? Null<Datetime>()
: Datetime(endDate);
}
((list<StockTable> *)out)->push_back(stockRecord);
result = 0;
} catch(std::out_of_range& e) {
HKU_WARN("Date of stock({}) is invalid! {}", stockRecord.id, e.what());
//不返回失败,仅抛弃该记录
result = 0;
} catch(boost::bad_lexical_cast& e) {
HKU_ERROR(e.what());
result = 1;
} catch(std::exception& e) {
HKU_ERROR(e.what());
result = 1;
} catch (...) {
HKU_ERROR("Unknow error!");
result = 1;
}
return result;
}
Parameter SQLiteBaseInfoDriver
::getFinanceInfo(const string& market, const string& code) {
Parameter result;
if (!m_db) {
return result;
}
std::stringstream buf;
buf << "select m.market, s.code, f.updated_date, f.ipo_date, f.province,"
<< "f.industry, f.zongguben, f.liutongguben, f.guojiagu, f.faqirenfarengu,"
<< "f.farengu, f.bgu, f.hgu, f.zhigonggu, f.zongzichan, f.liudongzichan,"
<< "f.gudingzichan, f.wuxingzichan, f.gudongrenshu, f.liudongfuzhai,"
<< "f.changqifuzhai, f.zibengongjijin, f.jingzichan, f.zhuyingshouru,"
<< "f.zhuyinglirun, f.yingshouzhangkuan, f.yingyelirun, f.touzishouyu,"
<< "f.jingyingxianjinliu, f.zongxianjinliu, f.cunhuo, f.lirunzonghe,"
<< "f.shuihoulirun, f.jinglirun, f.weifenpeilirun, f.meigujingzichan,"
<< "f.baoliu2 from stkfinance f, stock s, market m "
<< "where m.market='" << market << "'"
<< " and s.code = '" << code << "'"
<< " and s.marketid = m.marketid"
<< " and f.stockid = s.stockid"
<< " order by updated_date DESC limit 1";
//std::cout << buf.str() << std::endl;
char *zErrMsg=0;
int rc = sqlite3_exec(m_db.get(), buf.str().c_str(),
_getFinanceTableCallBack, &result, &zErrMsg);
if( rc != SQLITE_OK ){
HKU_ERROR("SQL error: {}", zErrMsg);
sqlite3_free(zErrMsg);
return result;
}
return result;
}
int SQLiteBaseInfoDriver
::_getFinanceTableCallBack(void *out, int nCol,
char **azVals, char **azCols) {
assert(nCol == 37);
int result = 0;
Parameter *p = static_cast<Parameter *>(out);
try {
p->set<string>("market", string(azVals[0]));
p->set<string>("code", string(azVals[1]));
p->set<int>("updated_date", atof(azVals[2]));
p->set<int>("ipo_date", atof(azVals[3]));
p->set<price_t>("province", atof(azVals[4]));
p->set<price_t>("industry", atof(azVals[5]));
p->set<price_t>("zongguben", atof(azVals[6]));
p->set<price_t>("liutongguben", atof(azVals[7]));
p->set<price_t>("guojiagu", atof(azVals[8]));
p->set<price_t>("faqirenfarengu", atof(azVals[9]));
p->set<price_t>("farengu", atof(azVals[10]));
p->set<price_t>("bgu", atof(azVals[11]));
p->set<price_t>("hgu", atof(azVals[12]));
p->set<price_t>("zhigonggu", atof(azVals[13]));
p->set<price_t>("zongzichan", atof(azVals[14]));
p->set<price_t>("liudongzichan", atof(azVals[15]));
p->set<price_t>("gudingzichan", atof(azVals[16]));
p->set<price_t>("wuxingzichan", atof(azVals[17]));
p->set<price_t>("gudongrenshu", atof(azVals[18]));
p->set<price_t>("liudongfuzhai", atof(azVals[19]));
p->set<price_t>("changqifuzhai", atof(azVals[20]));
p->set<price_t>("zibengongjijin", atof(azVals[21]));
p->set<price_t>("jingzichan", atof(azVals[22]));
p->set<price_t>("zhuyingshouru", atof(azVals[23]));
p->set<price_t>("zhuyinglirun", atof(azVals[24]));
p->set<price_t>("yingshouzhangkuan", atof(azVals[25]));
p->set<price_t>("yingyelirun", atof(azVals[26]));
p->set<price_t>("touzishouyi", atof(azVals[27]));
p->set<price_t>("jingyingxianjinliu", atof(azVals[28]));
p->set<price_t>("zongxianjinliu", atof(azVals[29]));
p->set<price_t>("cunhuo", atof(azVals[30]));
p->set<price_t>("lirunzonghe", atof(azVals[31]));
p->set<price_t>("shuihoulirun", atof(azVals[32]));
p->set<price_t>("jinglirun", atof(azVals[33]));
p->set<price_t>("weifenpeilirun", atof(azVals[34]));
p->set<price_t>("meigujingzichan", atof(azVals[35]));
p->set<price_t>("baoliu2", atof(azVals[36]));
result = 0;
} catch(std::exception& e) {
HKU_ERROR(e.what());
result = 1;
} catch (...) {
HKU_ERROR("Unkown error!");
result = 1;
}
return result;
}
} /* namespace hku */