mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-11-29 18:27:43 +08:00
Start adding sqlite3 support
This commit is contained in:
parent
bd5cd65c6a
commit
161a964238
@ -90,6 +90,15 @@ if(MYSQL_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#Find sqlite3.
|
||||
find_package (SQLite3)
|
||||
if (SQLITE3_FOUND)
|
||||
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||
link_libraries(${SQLITE3_LIBRARIES})
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl DIR_SRCS)
|
||||
set(USE_ORM TRUE)
|
||||
endif (SQLITE3_FOUND)
|
||||
|
||||
message(STATUS ${DIR_SRCS})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "")
|
||||
@ -136,6 +145,13 @@ if(USE_ORM)
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_MYSQL 0\n")
|
||||
endif()
|
||||
|
||||
if(SQLITE3_FOUND)
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_SQLITE3 1\n")
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_SQLITE3 0\n")
|
||||
endif()
|
||||
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_ORM 0\n")
|
||||
endif()
|
||||
|
37
cmake_modules/FindSQLite3.cmake
Normal file
37
cmake_modules/FindSQLite3.cmake
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright (C) 2007-2009 LuaDist.
|
||||
# Created by Peter Kapec <kapecp@gmail.com>
|
||||
# Redistribution and use of this file is allowed according to the terms of the MIT license.
|
||||
# For details see the COPYRIGHT file distributed with LuaDist.
|
||||
# Note:
|
||||
# Searching headers and libraries is very simple and is NOT as powerful as scripts
|
||||
# distributed with CMake, because LuaDist defines directories to search for.
|
||||
# Everyone is encouraged to contact the author with improvements. Maybe this file
|
||||
# becomes part of CMake distribution sometimes.
|
||||
|
||||
# - Find sqlite3
|
||||
# Find the native SQLITE3 headers and libraries.
|
||||
#
|
||||
# SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc.
|
||||
# SQLITE3_LIBRARIES - List of libraries when using sqlite.
|
||||
# SQLITE3_FOUND - True if sqlite found.
|
||||
|
||||
# Look for the header file.
|
||||
FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h)
|
||||
|
||||
# Look for the library.
|
||||
FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE.
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR)
|
||||
|
||||
# Copy the results to the output variables.
|
||||
IF(SQLITE3_FOUND)
|
||||
SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY})
|
||||
SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR})
|
||||
ELSE(SQLITE3_FOUND)
|
||||
SET(SQLITE3_LIBRARIES)
|
||||
SET(SQLITE3_INCLUDE_DIRS)
|
||||
ENDIF(SQLITE3_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)
|
@ -40,7 +40,20 @@ namespace orm
|
||||
enum class ClientType
|
||||
{
|
||||
PostgreSQL = 0,
|
||||
Mysql
|
||||
Mysql,
|
||||
Sqlite3
|
||||
};
|
||||
|
||||
enum Sqlite3Type
|
||||
{
|
||||
Sqlite3TypeChar = 0,
|
||||
Sqlite3TypeShort,
|
||||
Sqlite3TypeInt,
|
||||
Sqlite3TypeInt64,
|
||||
Sqlite3TypeDouble,
|
||||
Sqlite3TypeText,
|
||||
Sqlite3TypeBlob,
|
||||
Sqlite3TypeNull
|
||||
};
|
||||
|
||||
class DbClient;
|
||||
@ -296,6 +309,28 @@ class SqlBinder
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (_type == ClientType::Sqlite3)
|
||||
{
|
||||
_objs.push_back(obj);
|
||||
_parameters.push_back((char *)obj.get());
|
||||
_length.push_back(0);
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1:
|
||||
_format.push_back(Sqlite3TypeChar);
|
||||
break;
|
||||
case 2:
|
||||
_format.push_back(Sqlite3TypeShort);
|
||||
break;
|
||||
case 4:
|
||||
_format.push_back(Sqlite3TypeInt);
|
||||
break;
|
||||
case 8:
|
||||
_format.push_back(Sqlite3TypeInt64);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//LOG_TRACE << "Bind parameter:" << parameter;
|
||||
return *this;
|
||||
}
|
||||
|
@ -31,57 +31,57 @@ namespace orm
|
||||
|
||||
class DbClientImpl : public DbClient, public std::enable_shared_from_this<DbClientImpl>
|
||||
{
|
||||
public:
|
||||
DbClientImpl(const std::string &connInfo, const size_t connNum, ClientType type);
|
||||
virtual ~DbClientImpl() noexcept;
|
||||
virtual void execSql(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback) override;
|
||||
virtual std::shared_ptr<Transaction> newTransaction(const std::function<void(bool)> &commitCallback = std::function<void(bool)>()) override;
|
||||
public:
|
||||
DbClientImpl(const std::string &connInfo, const size_t connNum, ClientType type);
|
||||
virtual ~DbClientImpl() noexcept;
|
||||
virtual void execSql(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback) override;
|
||||
virtual std::shared_ptr<Transaction> newTransaction(const std::function<void(bool)> &commitCallback = std::function<void(bool)>()) override;
|
||||
|
||||
private:
|
||||
void ioLoop();
|
||||
std::shared_ptr<trantor::EventLoop> _loopPtr;
|
||||
void execSql(const DbConnectionPtr &conn, const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback);
|
||||
private:
|
||||
void ioLoop();
|
||||
std::shared_ptr<trantor::EventLoop> _loopPtr;
|
||||
void execSql(const DbConnectionPtr &conn, const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback);
|
||||
|
||||
DbConnectionPtr newConnection();
|
||||
DbConnectionPtr newConnection();
|
||||
|
||||
std::unordered_set<DbConnectionPtr> _connections;
|
||||
std::unordered_set<DbConnectionPtr> _readyConnections;
|
||||
std::unordered_set<DbConnectionPtr> _busyConnections;
|
||||
std::string _connInfo;
|
||||
std::thread _loopThread;
|
||||
std::mutex _connectionsMutex;
|
||||
std::condition_variable _condConnectionReady;
|
||||
size_t _transWaitNum = 0;
|
||||
std::unordered_set<DbConnectionPtr> _connections;
|
||||
std::unordered_set<DbConnectionPtr> _readyConnections;
|
||||
std::unordered_set<DbConnectionPtr> _busyConnections;
|
||||
std::string _connInfo;
|
||||
std::thread _loopThread;
|
||||
std::mutex _connectionsMutex;
|
||||
std::condition_variable _condConnectionReady;
|
||||
size_t _transWaitNum = 0;
|
||||
|
||||
size_t _connectNum;
|
||||
bool _stop = false;
|
||||
size_t _connectNum;
|
||||
bool _stop = false;
|
||||
|
||||
struct SqlCmd
|
||||
{
|
||||
std::string _sql;
|
||||
size_t _paraNum;
|
||||
std::vector<const char *> _parameters;
|
||||
std::vector<int> _length;
|
||||
std::vector<int> _format;
|
||||
QueryCallback _cb;
|
||||
ExceptPtrCallback _exceptCb;
|
||||
};
|
||||
std::deque<SqlCmd> _sqlCmdBuffer;
|
||||
std::mutex _bufferMutex;
|
||||
struct SqlCmd
|
||||
{
|
||||
std::string _sql;
|
||||
size_t _paraNum;
|
||||
std::vector<const char *> _parameters;
|
||||
std::vector<int> _length;
|
||||
std::vector<int> _format;
|
||||
QueryCallback _cb;
|
||||
ExceptPtrCallback _exceptCb;
|
||||
};
|
||||
std::deque<SqlCmd> _sqlCmdBuffer;
|
||||
std::mutex _bufferMutex;
|
||||
|
||||
void handleNewTask(const DbConnectionPtr &conn);
|
||||
void handleNewTask(const DbConnectionPtr &conn);
|
||||
};
|
||||
|
||||
} // namespace orm
|
||||
|
@ -26,10 +26,11 @@ int main()
|
||||
*clientPtr << "select * from users where id!=139 order by id" << Mode::Blocking >> [](const Result &r) {
|
||||
std::cout << "rows:" << r.size() << std::endl;
|
||||
std::cout << "column num:" << r.columns() << std::endl;
|
||||
// for (auto row : r)
|
||||
// {
|
||||
// std::cout << "user_id=" << row["user_id"].as<std::string>() << std::endl;
|
||||
// }
|
||||
|
||||
for (auto row : r)
|
||||
{
|
||||
std::cout << "id=" << row["id"].as<int>() << std::endl;
|
||||
}
|
||||
// for (auto row : r)
|
||||
// {
|
||||
// for (auto f : row)
|
||||
|
155
orm_lib/src/sqlite3_impl/Sqlite3Connection.cc
Normal file
155
orm_lib/src/sqlite3_impl/Sqlite3Connection.cc
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
*
|
||||
* Sqlite3Connection.cc
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Sqlite3Connection.h"
|
||||
#include "Sqlite3ResultImpl.h"
|
||||
using namespace drogon::orm;
|
||||
|
||||
std::once_flag Sqlite3Connection::_once;
|
||||
|
||||
Sqlite3Connection::Sqlite3Connection(trantor::EventLoop *loop, const std::string &connInfo)
|
||||
: DbConnection(loop),
|
||||
_queue("Sqlite")
|
||||
{
|
||||
std::call_once(_once, []() {
|
||||
auto ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
LOG_FATAL << sqlite3_errstr(ret);
|
||||
}
|
||||
});
|
||||
auto thisPtr = shared_from_this();
|
||||
_queue.runTaskInQueue([thisPtr, connInfo]() {
|
||||
sqlite3 *tmp = nullptr;
|
||||
auto ret = sqlite3_open(connInfo.data(), &tmp);
|
||||
thisPtr->_conn = std::shared_ptr<sqlite3>(tmp, [=](sqlite3 *ptr) { sqlite3_close(ptr); });
|
||||
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
LOG_FATAL << sqlite3_errstr(ret);
|
||||
thisPtr->_closeCb(thisPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlite3_extended_result_codes(tmp, true);
|
||||
thisPtr->_okCb(thisPtr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Sqlite3Connection::execSql(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback,
|
||||
const std::function<void()> &idleCb)
|
||||
{
|
||||
auto thisPtr = shared_from_this();
|
||||
_queue.runTaskInQueue([=]() {
|
||||
thisPtr->execSqlInQueue(sql, paraNum, parameters, length, format, rcb, exceptCallback, idleCb);
|
||||
});
|
||||
}
|
||||
|
||||
void Sqlite3Connection::execSqlInQueue(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback,
|
||||
const std::function<void()> &idleCb)
|
||||
{
|
||||
sqlite3_stmt *stmt = nullptr;
|
||||
const char *remaining;
|
||||
auto ret = sqlite3_prepare_v2(_conn.get(), sql.data(), -1, &stmt, &remaining);
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
//FIXME:throw exception here;
|
||||
return;
|
||||
}
|
||||
if (!std::all_of(remaining, sql.data() + sql.size(), [](char ch) { return std::isspace(ch); }))
|
||||
{
|
||||
///close stmt
|
||||
///FIXME
|
||||
///throw errors::more_statements("Multiple semicolon separated statements are unsupported", sql);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
int bindRet;
|
||||
switch (format[i])
|
||||
{
|
||||
case Sqlite3TypeChar:
|
||||
bindRet = sqlite3_bind_int(stmt, i + 1, *(char *)parameters[i]);
|
||||
break;
|
||||
case Sqlite3TypeShort:
|
||||
bindRet = sqlite3_bind_int(stmt, i + 1, *(short *)parameters[i]);
|
||||
break;
|
||||
case Sqlite3TypeInt:
|
||||
bindRet = sqlite3_bind_int(stmt, i + 1, *(int32_t *)parameters[i]);
|
||||
break;
|
||||
case Sqlite3TypeInt64:
|
||||
bindRet = sqlite3_bind_int64(stmt, i + 1, *(int64_t *)parameters[i]);
|
||||
break;
|
||||
case Sqlite3TypeDouble:
|
||||
bindRet = sqlite3_bind_double(stmt, i + 1, *(double *)parameters[i]);
|
||||
break;
|
||||
case Sqlite3TypeText:
|
||||
bindRet = sqlite3_bind_text(stmt, i + 1, parameters[i], -1, SQLITE_STATIC);
|
||||
break;
|
||||
case Sqlite3TypeBlob:
|
||||
bindRet = sqlite3_bind_blob(stmt, i + 1, parameters[i], length[i], SQLITE_STATIC);
|
||||
break;
|
||||
case Sqlite3TypeNull:
|
||||
bindRet = sqlite3_bind_null(stmt, i + 1);
|
||||
break;
|
||||
}
|
||||
if (bindRet != SQLITE_OK)
|
||||
{
|
||||
//FIXME throw!
|
||||
return;
|
||||
}
|
||||
}
|
||||
int r;
|
||||
int columnNum = sqlite3_column_count(stmt);
|
||||
Sqlite3ResultImpl result(sql);
|
||||
while ((r = sqlite3_step(stmt)) == SQLITE_ROW)
|
||||
{
|
||||
std::vector<std::shared_ptr<std::string>> row;
|
||||
for (int i = 0; i < columnNum; i++)
|
||||
{
|
||||
|
||||
switch (sqlite3_column_type(stmt, i))
|
||||
{
|
||||
case SQLITE_INTEGER:
|
||||
case SQLITE_FLOAT:
|
||||
case SQLITE_TEXT:
|
||||
case SQLITE_BLOB:
|
||||
case SQLITE_NULL:
|
||||
row.push_back(nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result._result->push_back(std::move(row));
|
||||
}
|
||||
if (r != SQLITE_DONE)
|
||||
{
|
||||
//FIXME throw
|
||||
return;
|
||||
}
|
||||
rcb(result);
|
||||
idleCb();
|
||||
}
|
64
orm_lib/src/sqlite3_impl/Sqlite3Connection.h
Normal file
64
orm_lib/src/sqlite3_impl/Sqlite3Connection.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
* Sqlite3Connection.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../DbConnection.h"
|
||||
#include <drogon/orm/DbClient.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/utils/SerialTaskQueue.h>
|
||||
#include <sqlite3.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
namespace orm
|
||||
{
|
||||
|
||||
class Sqlite3Connection;
|
||||
typedef std::shared_ptr<Sqlite3Connection> Sqlite3ConnectionPtr;
|
||||
class Sqlite3Connection : public DbConnection, public std::enable_shared_from_this<Sqlite3Connection>
|
||||
{
|
||||
public:
|
||||
Sqlite3Connection(trantor::EventLoop *loop, const std::string &connInfo);
|
||||
|
||||
virtual void execSql(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback,
|
||||
const std::function<void()> &idleCb) override;
|
||||
|
||||
private:
|
||||
static std::once_flag _once;
|
||||
void execSqlInQueue(const std::string &sql,
|
||||
size_t paraNum,
|
||||
const std::vector<const char *> ¶meters,
|
||||
const std::vector<int> &length,
|
||||
const std::vector<int> &format,
|
||||
const ResultCallback &rcb,
|
||||
const std::function<void(const std::exception_ptr &)> &exceptCallback,
|
||||
const std::function<void()> &idleCb);
|
||||
trantor::SerialTaskQueue _queue;
|
||||
std::shared_ptr<sqlite3> _conn;
|
||||
};
|
||||
|
||||
} // namespace orm
|
||||
} // namespace drogon
|
55
orm_lib/src/sqlite3_impl/Sqlite3ResultImpl.cc
Normal file
55
orm_lib/src/sqlite3_impl/Sqlite3ResultImpl.cc
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
*
|
||||
* Sqlite3ResultImpl.cc
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Sqlite3ResultImpl.h"
|
||||
#include <assert.h>
|
||||
|
||||
using namespace drogon::orm;
|
||||
|
||||
Result::size_type Sqlite3ResultImpl::size() const noexcept
|
||||
{
|
||||
return _result->size();
|
||||
}
|
||||
Result::row_size_type Sqlite3ResultImpl::columns() const noexcept
|
||||
{
|
||||
return _result->empty() ? 0 : (*_result)[0].size();
|
||||
}
|
||||
const char *Sqlite3ResultImpl::columnName(row_size_type number) const
|
||||
{
|
||||
//FIXME
|
||||
return "";
|
||||
}
|
||||
Result::size_type Sqlite3ResultImpl::affectedRows() const noexcept
|
||||
{
|
||||
return _affectedRows;
|
||||
}
|
||||
Result::row_size_type Sqlite3ResultImpl::columnNumber(const char colName[]) const
|
||||
{
|
||||
//FIXME
|
||||
return 0;
|
||||
}
|
||||
const char *Sqlite3ResultImpl::getValue(size_type row, row_size_type column) const
|
||||
{
|
||||
auto col = (*_result)[row][column];
|
||||
return col ? nullptr : col->c_str();
|
||||
}
|
||||
bool Sqlite3ResultImpl::isNull(size_type row, row_size_type column) const
|
||||
{
|
||||
return !(*_result)[row][column];
|
||||
}
|
||||
Result::field_size_type Sqlite3ResultImpl::getLength(size_type row, row_size_type column) const
|
||||
{
|
||||
auto col = (*_result)[row][column];
|
||||
return col ? 0 : col->length();
|
||||
}
|
53
orm_lib/src/sqlite3_impl/Sqlite3ResultImpl.h
Normal file
53
orm_lib/src/sqlite3_impl/Sqlite3ResultImpl.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
*
|
||||
* Sqlite3ResultImpl.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../ResultImpl.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
namespace orm
|
||||
{
|
||||
class Sqlite3ResultImpl : public ResultImpl
|
||||
{
|
||||
public:
|
||||
Sqlite3ResultImpl(const std::string &query) noexcept
|
||||
: _query(query),
|
||||
_result(new std::vector<std::vector<std::shared_ptr<std::string>>>)
|
||||
{
|
||||
|
||||
}
|
||||
virtual size_type size() const noexcept override;
|
||||
virtual row_size_type columns() const noexcept override;
|
||||
virtual const char *columnName(row_size_type Number) const override;
|
||||
virtual size_type affectedRows() const noexcept override;
|
||||
virtual row_size_type columnNumber(const char colName[]) const override;
|
||||
virtual const char *getValue(size_type row, row_size_type column) const override;
|
||||
virtual bool isNull(size_type row, row_size_type column) const override;
|
||||
virtual field_size_type getLength(size_type row, row_size_type column) const override;
|
||||
|
||||
private:
|
||||
friend class Sqlite3Connection;
|
||||
std::shared_ptr<std::vector<std::vector<std::shared_ptr<std::string>>>> _result;
|
||||
std::string _query;
|
||||
size_t _affectedRows = 0;
|
||||
};
|
||||
} // namespace orm
|
||||
} // namespace drogon
|
Loading…
Reference in New Issue
Block a user