Skip to content

Commit

Permalink
db, feat: support savepoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Jan 17, 2021
1 parent 16f0705 commit 37214ba
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 62 deletions.
7 changes: 4 additions & 3 deletions fibjs/include/SQLite.h
Expand Up @@ -27,10 +27,11 @@ class SQLite : public SQLite_base {
// DbConnection_base
virtual result_t get_type(exlib::string& retVal);
virtual result_t close(AsyncEvent* ac);
virtual result_t begin(AsyncEvent* ac);
virtual result_t commit(AsyncEvent* ac);
virtual result_t rollback(AsyncEvent* ac);
virtual result_t begin(exlib::string point, AsyncEvent* ac);
virtual result_t commit(exlib::string point, AsyncEvent* ac);
virtual result_t rollback(exlib::string point, AsyncEvent* ac);
virtual result_t trans(v8::Local<v8::Function> func, bool& retVal);
virtual result_t trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal);
virtual result_t execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal, AsyncEvent* ac);
virtual result_t createTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
virtual result_t dropTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
Expand Down
44 changes: 29 additions & 15 deletions fibjs/include/ifs/DbConnection.h
Expand Up @@ -23,10 +23,11 @@ class DbConnection_base : public object_base {
// DbConnection_base
virtual result_t get_type(exlib::string& retVal) = 0;
virtual result_t close(AsyncEvent* ac) = 0;
virtual result_t begin(AsyncEvent* ac) = 0;
virtual result_t commit(AsyncEvent* ac) = 0;
virtual result_t rollback(AsyncEvent* ac) = 0;
virtual result_t begin(exlib::string point, AsyncEvent* ac) = 0;
virtual result_t commit(exlib::string point, AsyncEvent* ac) = 0;
virtual result_t rollback(exlib::string point, AsyncEvent* ac) = 0;
virtual result_t trans(v8::Local<v8::Function> func, bool& retVal) = 0;
virtual result_t trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal) = 0;
virtual result_t execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal, AsyncEvent* ac) = 0;
virtual result_t createTable(v8::Local<v8::Object> opts, AsyncEvent* ac) = 0;
virtual result_t dropTable(v8::Local<v8::Object> opts, AsyncEvent* ac) = 0;
Expand Down Expand Up @@ -72,9 +73,9 @@ class DbConnection_base : public object_base {

public:
ASYNC_MEMBER0(DbConnection_base, close);
ASYNC_MEMBER0(DbConnection_base, begin);
ASYNC_MEMBER0(DbConnection_base, commit);
ASYNC_MEMBER0(DbConnection_base, rollback);
ASYNC_MEMBER1(DbConnection_base, begin, exlib::string);
ASYNC_MEMBER1(DbConnection_base, commit, exlib::string);
ASYNC_MEMBER1(DbConnection_base, rollback, exlib::string);
ASYNC_MEMBERVALUE3(DbConnection_base, execute, exlib::string, OptArgs, obj_ptr<NArray>);
ASYNC_MEMBER1(DbConnection_base, createTable, v8::Local<v8::Object>);
ASYNC_MEMBER1(DbConnection_base, dropTable, v8::Local<v8::Object>);
Expand Down Expand Up @@ -173,12 +174,14 @@ inline void DbConnection_base::s_begin(const v8::FunctionCallbackInfo<v8::Value>
METHOD_INSTANCE(DbConnection_base);
METHOD_ENTER();

ASYNC_METHOD_OVER(0, 0);
ASYNC_METHOD_OVER(1, 0);

OPT_ARG(exlib::string, 0, "");

if (!cb.IsEmpty())
hr = pInst->acb_begin(cb, args);
hr = pInst->acb_begin(v0, cb, args);
else
hr = pInst->ac_begin();
hr = pInst->ac_begin(v0);

METHOD_VOID();
}
Expand All @@ -189,12 +192,14 @@ inline void DbConnection_base::s_commit(const v8::FunctionCallbackInfo<v8::Value
METHOD_INSTANCE(DbConnection_base);
METHOD_ENTER();

ASYNC_METHOD_OVER(0, 0);
ASYNC_METHOD_OVER(1, 0);

OPT_ARG(exlib::string, 0, "");

if (!cb.IsEmpty())
hr = pInst->acb_commit(cb, args);
hr = pInst->acb_commit(v0, cb, args);
else
hr = pInst->ac_commit();
hr = pInst->ac_commit(v0);

METHOD_VOID();
}
Expand All @@ -205,12 +210,14 @@ inline void DbConnection_base::s_rollback(const v8::FunctionCallbackInfo<v8::Val
METHOD_INSTANCE(DbConnection_base);
METHOD_ENTER();

ASYNC_METHOD_OVER(0, 0);
ASYNC_METHOD_OVER(1, 0);

OPT_ARG(exlib::string, 0, "");

if (!cb.IsEmpty())
hr = pInst->acb_rollback(cb, args);
hr = pInst->acb_rollback(v0, cb, args);
else
hr = pInst->ac_rollback();
hr = pInst->ac_rollback(v0);

METHOD_VOID();
}
Expand All @@ -229,6 +236,13 @@ inline void DbConnection_base::s_trans(const v8::FunctionCallbackInfo<v8::Value>

hr = pInst->trans(v0, vr);

METHOD_OVER(2, 2);

ARG(exlib::string, 0);
ARG(v8::Local<v8::Function>, 1);

hr = pInst->trans(v0, v1, vr);

METHOD_RETURN();
}

Expand Down
7 changes: 4 additions & 3 deletions fibjs/include/mssql.h
Expand Up @@ -29,10 +29,11 @@ class mssql : public MSSQL_base {
// DbConnection_base
virtual result_t get_type(exlib::string& retVal);
virtual result_t close(AsyncEvent* ac);
virtual result_t begin(AsyncEvent* ac);
virtual result_t commit(AsyncEvent* ac);
virtual result_t rollback(AsyncEvent* ac);
virtual result_t begin(exlib::string point, AsyncEvent* ac);
virtual result_t commit(exlib::string point, AsyncEvent* ac);
virtual result_t rollback(exlib::string point, AsyncEvent* ac);
virtual result_t trans(v8::Local<v8::Function> func, bool& retVal);
virtual result_t trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal);
virtual result_t execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal, AsyncEvent* ac);
virtual result_t createTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
virtual result_t dropTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
Expand Down
7 changes: 4 additions & 3 deletions fibjs/include/mysql.h
Expand Up @@ -28,10 +28,11 @@ class mysql : public MySQL_base {
// DbConnection_base
virtual result_t get_type(exlib::string& retVal);
virtual result_t close(AsyncEvent* ac);
virtual result_t begin(AsyncEvent* ac);
virtual result_t commit(AsyncEvent* ac);
virtual result_t rollback(AsyncEvent* ac);
virtual result_t begin(exlib::string point, AsyncEvent* ac);
virtual result_t commit(exlib::string point, AsyncEvent* ac);
virtual result_t rollback(exlib::string point, AsyncEvent* ac);
virtual result_t trans(v8::Local<v8::Function> func, bool& retVal);
virtual result_t trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal);
virtual result_t execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal, AsyncEvent* ac);
virtual result_t createTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
virtual result_t dropTable(v8::Local<v8::Object> opts, AsyncEvent* ac);
Expand Down
19 changes: 12 additions & 7 deletions fibjs/src/db/sql/SQLite.cpp
Expand Up @@ -327,24 +327,29 @@ result_t SQLite::execute(const char* sql, int32_t sLen, obj_ptr<NArray>& retVal)
return 0;
}

result_t SQLite::begin(AsyncEvent* ac)
result_t SQLite::begin(exlib::string point, AsyncEvent* ac)
{
return db_begin(this, ac);
return db_begin(this, point, ac);
}

result_t SQLite::commit(AsyncEvent* ac)
result_t SQLite::commit(exlib::string point, AsyncEvent* ac)
{
return db_commit(this, ac);
return db_commit(this, point, ac);
}

result_t SQLite::rollback(AsyncEvent* ac)
result_t SQLite::rollback(exlib::string point, AsyncEvent* ac)
{
return db_rollback(this, ac);
return db_rollback(this, point, ac);
}

result_t SQLite::trans(v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, func, retVal);
return trans("", func, retVal);
}

result_t SQLite::trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, point, func, retVal);
}

result_t SQLite::execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal,
Expand Down
40 changes: 29 additions & 11 deletions fibjs/src/db/sql/db_api.h
Expand Up @@ -147,7 +147,7 @@ result_t db_remove(T* pThis, v8::Local<v8::Object> opts, int32_t& retVal,
}

template <typename T>
result_t db_begin(T* pThis, AsyncEvent* ac)
result_t db_begin(T* pThis, exlib::string point, AsyncEvent* ac, bool mssql = false)
{
if (!pThis->m_conn)
return CHECK_ERROR(CALL_E_INVALID_CALL);
Expand All @@ -156,11 +156,17 @@ result_t db_begin(T* pThis, AsyncEvent* ac)
return CHECK_ERROR(CALL_E_NOSYNC);

obj_ptr<NArray> retVal;
return pThis->execute("BEGIN", 5, retVal);

if (point.empty())
return pThis->execute("BEGIN", 5, retVal);
else {
exlib::string str((mssql ? "SAVE TRANSACTION " : "SAVEPOINT ") + point);
return pThis->execute(str.c_str(), str.length(), retVal);
}
}

template <typename T>
result_t db_commit(T* pThis, AsyncEvent* ac)
result_t db_commit(T* pThis, exlib::string point, AsyncEvent* ac, bool mssql = false)
{
if (!pThis->m_conn)
return CHECK_ERROR(CALL_E_INVALID_CALL);
Expand All @@ -169,11 +175,17 @@ result_t db_commit(T* pThis, AsyncEvent* ac)
return CHECK_ERROR(CALL_E_NOSYNC);

obj_ptr<NArray> retVal;
return pThis->execute("COMMIT", 6, retVal);

if (point.empty())
return pThis->execute("COMMIT", 6, retVal);
else {
exlib::string str((mssql ? "COMMIT TRANSACTION " : "RELEASE SAVEPOINT ") + point);
return pThis->execute(str.c_str(), str.length(), retVal);
}
}

template <typename T>
result_t db_rollback(T* pThis, AsyncEvent* ac)
result_t db_rollback(T* pThis, exlib::string point, AsyncEvent* ac, bool mssql = false)
{
if (!pThis->m_conn)
return CHECK_ERROR(CALL_E_INVALID_CALL);
Expand All @@ -182,17 +194,23 @@ result_t db_rollback(T* pThis, AsyncEvent* ac)
return CHECK_ERROR(CALL_E_NOSYNC);

obj_ptr<NArray> retVal;
return pThis->execute("ROLLBACK", 8, retVal);

if (point.empty())
return pThis->execute("ROLLBACK", 8, retVal);
else {
exlib::string str((mssql ? "ROLLBACK TRANSACTION " : "ROLLBACK TO ") + point);
return pThis->execute(str.c_str(), str.length(), retVal);
}
}

template <typename T>
inline result_t db_trans(T* pThis, v8::Local<v8::Function> func, bool& retVal)
inline result_t db_trans(T* pThis, exlib::string point, v8::Local<v8::Function> func, bool& retVal)
{
v8::Local<v8::Value> v = pThis->wrap();
result_t hr = 0;
retVal = false;

hr = pThis->ac_begin();
hr = pThis->ac_begin(point);
if (hr < 0)
return hr;

Expand All @@ -201,15 +219,15 @@ inline result_t db_trans(T* pThis, v8::Local<v8::Function> func, bool& retVal)
pThis->enter();

if (result.IsEmpty()) {
pThis->ac_rollback();
pThis->ac_rollback(point);
return CALL_E_JAVASCRIPT;
}

if (result->IsFalse())
return pThis->ac_rollback();
return pThis->ac_rollback(point);
else {
retVal = true;
return pThis->ac_commit();
return pThis->ac_commit(point);
}
}
}
19 changes: 12 additions & 7 deletions fibjs/src/db/sql/mssql.cpp
Expand Up @@ -290,24 +290,29 @@ result_t mssql::execute(const char* sql, int32_t sLen,
return 0;
}

result_t mssql::begin(AsyncEvent* ac)
result_t mssql::begin(exlib::string point, AsyncEvent* ac)
{
return db_begin(this, ac);
return db_begin(this, point, ac, true);
}

result_t mssql::commit(AsyncEvent* ac)
result_t mssql::commit(exlib::string point, AsyncEvent* ac)
{
return db_commit(this, ac);
return db_commit(this, point, ac, true);
}

result_t mssql::rollback(AsyncEvent* ac)
result_t mssql::rollback(exlib::string point, AsyncEvent* ac)
{
return db_rollback(this, ac);
return db_rollback(this, point, ac, true);
}

result_t mssql::trans(v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, func, retVal);
return trans("", func, retVal);
}

result_t mssql::trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, point, func, retVal);
}

result_t mssql::execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal,
Expand Down
19 changes: 12 additions & 7 deletions fibjs/src/db/sql/mysql.cpp
Expand Up @@ -286,24 +286,29 @@ result_t mysql::execute(const char* sql, int32_t sLen,
return 0;
}

result_t mysql::begin(AsyncEvent* ac)
result_t mysql::begin(exlib::string point, AsyncEvent* ac)
{
return db_begin(this, ac);
return db_begin(this, point, ac);
}

result_t mysql::commit(AsyncEvent* ac)
result_t mysql::commit(exlib::string point, AsyncEvent* ac)
{
return db_commit(this, ac);
return db_commit(this, point, ac);
}

result_t mysql::rollback(AsyncEvent* ac)
result_t mysql::rollback(exlib::string point, AsyncEvent* ac)
{
return db_rollback(this, ac);
return db_rollback(this, point, ac);
}

result_t mysql::trans(v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, func, retVal);
return trans("", func, retVal);
}

result_t mysql::trans(exlib::string point, v8::Local<v8::Function> func, bool& retVal)
{
return db_trans(this, point, func, retVal);
}

result_t mysql::execute(exlib::string sql, OptArgs args, obj_ptr<NArray>& retVal,
Expand Down
33 changes: 27 additions & 6 deletions idl/zh-cn/DbConnection.idl
Expand Up @@ -7,14 +7,23 @@ interface DbConnection : object
/*! @brief 关闭当前数据库连接 */
close() async;

/*! @brief 在当前数据库连接上启动一个事务 */
begin() async;
/*! @brief 在当前数据库连接上启动一个事务

@param point 指定事务的名称,缺省不指定
*/
begin(String point = "") async;

/*! @brief 提交当前数据库连接上的事务 */
commit() async;
/*! @brief 提交当前数据库连接上的事务

@param point 指定事务的名称,缺省不指定
*/
commit(String point = "") async;

/*! @brief 回滚当前数据库连接上的事务 */
rollback() async;
/*! @brief 回滚当前数据库连接上的事务

@param point 指定事务的名称,缺省不指定
*/
rollback(String point = "") async;

/*! @brief 进入事务执行一个函数,并根据函数执行情况提交或者回滚
func 执行有三种结果:
Expand All @@ -27,6 +36,18 @@ interface DbConnection : object
*/
Boolean trans(Function func);

/*! @brief 进入事务执行一个函数,并根据函数执行情况提交或者回滚
func 执行有三种结果:
* 函数正常返回,包括运行结束和主动 return,此时事务将自动提交
* 函数返回 false,此时事务将回滚
* 函数运行错误,事务自动回滚

@param point 指定事务的名称
@param func 以事务方式执行的函数
@return 返回事务是否提交,正常 commit 时返回 true, rollback 时返回 false,如果事务出错则抛出错误
*/
Boolean trans(String point, Function func);

/*! @brief 执行一个 sql 命令,并返回执行结果,可根据参数格式化字符串

@param sql 格式化字符串,可选参数用 ? 指定。例如:'SELECT FROM TEST WHERE [id]=?'
Expand Down

0 comments on commit 37214ba

Please sign in to comment.