mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-02 03:48:19 +08:00
SQLite Connect support Datetime
This commit is contained in:
parent
c069892c6f
commit
3d9cc793bb
@ -13,6 +13,7 @@
|
||||
#include <type_traits>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include "hikyuu/utilities/datetime/Datetime.h"
|
||||
#include "../../DataType.h"
|
||||
|
||||
namespace hku {
|
||||
@ -40,15 +41,15 @@ public:
|
||||
* @param driver 数据库连接
|
||||
* @param sql_statement SQL语句
|
||||
*/
|
||||
SQLStatementBase(DBConnectBase* driver, const string& sql_statement);
|
||||
SQLStatementBase(DBConnectBase *driver, const string &sql_statement);
|
||||
|
||||
virtual ~SQLStatementBase() = default;
|
||||
|
||||
/** 获取构建时传入的表达式SQL语句 */
|
||||
const string& getSqlString() const;
|
||||
const string &getSqlString() const;
|
||||
|
||||
/** 获取数据驱动 */
|
||||
DBConnectBase* getConnect() const;
|
||||
DBConnectBase *getConnect() const;
|
||||
|
||||
/** 执行 SQL */
|
||||
void exec();
|
||||
@ -71,6 +72,9 @@ public:
|
||||
/** 将字符串类型 item 绑定至 idx 指定的 SQL 参数中 */
|
||||
void bind(int idx, const char *item, size_t len);
|
||||
|
||||
/** 将 Datetime 类型 item 绑定至指定的 SQL 参数中 */
|
||||
void bind(int idx, const Datetime &item);
|
||||
|
||||
/** 将 item 的值绑定至 idx 指定的 SQL 参数中 */
|
||||
void bindBlob(int idx, const std::string &item);
|
||||
|
||||
@ -109,6 +113,9 @@ public:
|
||||
/** 获取 idx 指定的数据至 item */
|
||||
void getColumn(int idx, std::string &item);
|
||||
|
||||
/** 获取 idx 指定的数据至 item */
|
||||
void getColumn(int idx, Datetime &item);
|
||||
|
||||
/** 获取 idx 指定的数据至 item */
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer>::type getColumn(int idx, T &);
|
||||
@ -128,10 +135,11 @@ public:
|
||||
virtual bool sub_moveNext() = 0; ///< 子类接口 @see moveNext
|
||||
virtual uint64_t sub_getLastRowid() = 0; ///< 子类接口 @see getLastRowid();
|
||||
|
||||
virtual void sub_bindNull(int idx) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindInt(int idx, int64_t value) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindDouble(int idx, double item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindText(int idx, const std::string &item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindNull(int idx) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindInt(int idx, int64_t value) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindDouble(int idx, double item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindDatetime(int idx, const Datetime &item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindText(int idx, const std::string &item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindText(int idx, const char *item, size_t len) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindBlob(int idx, const std::string &item) = 0; ///< 子类接口 @see bind
|
||||
virtual void sub_bindBlob(int idx, const char *item, size_t len) = 0; ///< 子类接口 @see bind
|
||||
@ -139,8 +147,9 @@ public:
|
||||
virtual int sub_getNumColumns() const = 0; ///< 子类接口 @see getNumColumns
|
||||
virtual void sub_getColumnAsInt64(int idx, int64_t &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsDouble(int idx, double &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsText(int idx, std::string &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsBlob(int idx, std::string &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsDatetime(int idx, Datetime &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsText(int idx, std::string &) = 0; ///< 子类接口 @see getColumn
|
||||
virtual void sub_getColumnAsBlob(int idx, std::string &) = 0; ///< 子类接口 @see getColumn
|
||||
|
||||
private:
|
||||
SQLStatementBase() = delete;
|
||||
@ -162,7 +171,7 @@ inline const std::string &SQLStatementBase::getSqlString() const {
|
||||
return m_sql_string;
|
||||
}
|
||||
|
||||
inline DBConnectBase* SQLStatementBase::getConnect() const {
|
||||
inline DBConnectBase *SQLStatementBase::getConnect() const {
|
||||
return m_driver;
|
||||
}
|
||||
|
||||
@ -193,6 +202,10 @@ inline void SQLStatementBase::bind(int idx, double item) {
|
||||
sub_bindDouble(idx, item);
|
||||
}
|
||||
|
||||
inline void SQLStatementBase::bind(int idx, const Datetime &item) {
|
||||
sub_bindDatetime(idx, item);
|
||||
}
|
||||
|
||||
inline void SQLStatementBase::bindBlob(int idx, const std::string &item) {
|
||||
sub_bindBlob(idx, item);
|
||||
}
|
||||
@ -219,6 +232,10 @@ inline void SQLStatementBase::getColumn(int idx, float &item) {
|
||||
item = (float)temp;
|
||||
}
|
||||
|
||||
inline void SQLStatementBase::getColumn(int idx, Datetime &item) {
|
||||
sub_getColumnAsDatetime(idx, item);
|
||||
}
|
||||
|
||||
inline void SQLStatementBase::getColumn(int idx, std::string &item) {
|
||||
sub_getColumnAsText(idx, item);
|
||||
}
|
||||
@ -231,7 +248,7 @@ typename std::enable_if<std::numeric_limits<T>::is_integer>::type SQLStatementBa
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<!std::numeric_limits<T>::is_integer>::type SQLStatementBase::bind(
|
||||
int idx, const T& item) {
|
||||
int idx, const T &item) {
|
||||
std::ostringstream sout;
|
||||
boost::archive::binary_oarchive oa(sout);
|
||||
oa << BOOST_SERIALIZATION_NVP(item);
|
||||
@ -240,7 +257,7 @@ typename std::enable_if<!std::numeric_limits<T>::is_integer>::type SQLStatementB
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer>::type SQLStatementBase::getColumn(
|
||||
int idx, T& item) {
|
||||
int idx, T &item) {
|
||||
int64_t temp;
|
||||
sub_getColumnAsInt64(idx, temp);
|
||||
item = (T)temp;
|
||||
@ -248,11 +265,11 @@ typename std::enable_if<std::numeric_limits<T>::is_integer>::type SQLStatementBa
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<!std::numeric_limits<T>::is_integer>::type SQLStatementBase::getColumn(
|
||||
int idx, T& item) {
|
||||
int idx, T &item) {
|
||||
string tmp;
|
||||
try {
|
||||
sub_getColumnAsBlob(idx, tmp);
|
||||
} catch (null_blob_exception&) {
|
||||
} catch (null_blob_exception &) {
|
||||
return;
|
||||
}
|
||||
std::istringstream sin(tmp);
|
||||
@ -261,7 +278,7 @@ typename std::enable_if<!std::numeric_limits<T>::is_integer>::type SQLStatementB
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void SQLStatementBase::bind(int idx, const T& item, const Args&... rest) {
|
||||
void SQLStatementBase::bind(int idx, const T &item, const Args &...rest) {
|
||||
bind(idx, item);
|
||||
bind(idx + 1, rest...);
|
||||
}
|
||||
|
@ -197,6 +197,10 @@ void MySQLStatement::sub_bindDouble(int idx, double item) {
|
||||
m_param_bind[idx].buffer = boost::any_cast<double>(&buf);
|
||||
}
|
||||
|
||||
void MySQLStatement::sub_bindDatetime(int idx, const Datetime& item) {
|
||||
HKU_THROW("Not yet implemented");
|
||||
}
|
||||
|
||||
void MySQLStatement::sub_bindText(int idx, const string& item) {
|
||||
HKU_CHECK(idx < m_param_bind.size(), "idx out of range! idx: {}, total: {}", idx,
|
||||
m_param_bind.size());
|
||||
@ -293,6 +297,10 @@ void MySQLStatement::sub_getColumnAsDouble(int idx, double& item) {
|
||||
}
|
||||
}
|
||||
|
||||
void MySQLStatement::sub_getColumnAsDatetime(int idx, Datetime& item) {
|
||||
HKU_THROW("Not yet implemented");
|
||||
}
|
||||
|
||||
void MySQLStatement::sub_getColumnAsText(int idx, string& item) {
|
||||
HKU_CHECK(idx < m_result_buffer.size(), "idx out of range! idx: {}, total: {}",
|
||||
m_result_buffer.size());
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
virtual void sub_bindNull(int idx) override;
|
||||
virtual void sub_bindInt(int idx, int64_t value) override;
|
||||
virtual void sub_bindDouble(int idx, double item) override;
|
||||
virtual void sub_bindDatetime(int idx, const Datetime& item) override;
|
||||
virtual void sub_bindText(int idx, const std::string& item) override;
|
||||
virtual void sub_bindText(int idx, const char* item, size_t len) override;
|
||||
virtual void sub_bindBlob(int idx, const std::string& item) override;
|
||||
@ -53,6 +54,7 @@ public:
|
||||
virtual int sub_getNumColumns() const override;
|
||||
virtual void sub_getColumnAsInt64(int idx, int64_t& item) override;
|
||||
virtual void sub_getColumnAsDouble(int idx, double& item) override;
|
||||
virtual void sub_getColumnAsDatetime(int idx, Datetime& item) override;
|
||||
virtual void sub_getColumnAsText(int idx, std::string& item) override;
|
||||
virtual void sub_getColumnAsBlob(int idx, std::string& item) override;
|
||||
|
||||
|
@ -95,6 +95,14 @@ void SQLiteStatement::sub_bindInt(int idx, int64_t value) {
|
||||
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
|
||||
}
|
||||
|
||||
void SQLiteStatement::sub_bindDatetime(int idx, const Datetime &item) {
|
||||
if (item == Null<Datetime>()) {
|
||||
sub_bindNull(idx);
|
||||
} else {
|
||||
sub_bindText(idx, item.str());
|
||||
}
|
||||
}
|
||||
|
||||
void SQLiteStatement::sub_bindText(int idx, const string &item) {
|
||||
_reset();
|
||||
int status =
|
||||
@ -135,6 +143,12 @@ void SQLiteStatement::sub_getColumnAsDouble(int idx, double &item) {
|
||||
item = sqlite3_column_double(m_stmt, idx);
|
||||
}
|
||||
|
||||
void SQLiteStatement::sub_getColumnAsDatetime(int idx, Datetime &item) {
|
||||
std::string date_str;
|
||||
sub_getColumnAsText(idx, date_str);
|
||||
item = date_str.empty() ? Datetime() : Datetime(date_str);
|
||||
}
|
||||
|
||||
void SQLiteStatement::sub_getColumnAsText(int idx, std::string &item) {
|
||||
const char *data = reinterpret_cast<const char *>(sqlite3_column_text(m_stmt, idx));
|
||||
item = (data != 0) ? std::string(data) : std::string();
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
virtual void sub_bindNull(int idx) override;
|
||||
virtual void sub_bindInt(int idx, int64_t value) override;
|
||||
virtual void sub_bindDouble(int idx, double item) override;
|
||||
virtual void sub_bindDatetime(int idx, const Datetime &item) override;
|
||||
virtual void sub_bindText(int idx, const std::string &item) override;
|
||||
virtual void sub_bindText(int idx, const char *item, size_t len) override;
|
||||
virtual void sub_bindBlob(int idx, const std::string &item) override;
|
||||
@ -48,6 +49,7 @@ public:
|
||||
virtual int sub_getNumColumns() const override;
|
||||
virtual void sub_getColumnAsInt64(int idx, int64_t &item) override;
|
||||
virtual void sub_getColumnAsDouble(int idx, double &item) override;
|
||||
virtual void sub_getColumnAsDatetime(int idx, Datetime &item) override;
|
||||
virtual void sub_getColumnAsText(int idx, std::string &item) override;
|
||||
virtual void sub_getColumnAsBlob(int idx, std::string &item) override;
|
||||
|
||||
|
@ -37,12 +37,15 @@ TEST_CASE("test_sqlite") {
|
||||
"data_int64_t" INTEGER,
|
||||
"data_double" REAL,
|
||||
"data_float" REAL,
|
||||
"create_at" DATETIME,
|
||||
"null_date" DATETIME,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
);)");
|
||||
}
|
||||
|
||||
class T2019 {
|
||||
TABLE_BIND5(T2019, t2019, name, data_int32_t, data_int64_t, data_double, data_float);
|
||||
TABLE_BIND7(T2019, t2019, name, data_int32_t, data_int64_t, data_double, data_float,
|
||||
create_at, null_date);
|
||||
|
||||
public:
|
||||
void reset() {
|
||||
@ -51,6 +54,8 @@ TEST_CASE("test_sqlite") {
|
||||
data_int64_t = Null<int64_t>();
|
||||
data_double = Null<double>();
|
||||
data_float = Null<float>();
|
||||
create_at = Null<Datetime>();
|
||||
null_date = Null<Datetime>();
|
||||
}
|
||||
|
||||
public:
|
||||
@ -59,6 +64,8 @@ TEST_CASE("test_sqlite") {
|
||||
int64_t data_int64_t;
|
||||
double data_double;
|
||||
float data_float;
|
||||
Datetime create_at;
|
||||
Datetime null_date;
|
||||
};
|
||||
|
||||
T2019 x;
|
||||
@ -67,6 +74,7 @@ TEST_CASE("test_sqlite") {
|
||||
x.data_int64_t = 3147483647;
|
||||
x.data_double = 3.1415926;
|
||||
x.data_float = 3.14f;
|
||||
x.create_at = Datetime(202310222221);
|
||||
con->save(x);
|
||||
|
||||
T2019 rx;
|
||||
@ -77,6 +85,9 @@ TEST_CASE("test_sqlite") {
|
||||
CHECK(rx.data_int64_t == x.data_int64_t);
|
||||
CHECK(std::abs(rx.data_double - x.data_double) < 0.00001);
|
||||
CHECK(std::abs(rx.data_float - x.data_float) < 0.00001);
|
||||
CHECK(rx.create_at == x.create_at);
|
||||
CHECK(rx.null_date == x.null_date);
|
||||
CHECK(rx.null_date == Datetime());
|
||||
con->exec("drop table t2019");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user