progress on record fetch
This commit is contained in:
parent
ae5777bdb0
commit
171e8d36ce
|
|
@ -2,6 +2,7 @@
|
|||
#define QUERY_SQLITE_QUERY_RESULT_HPP
|
||||
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -9,8 +10,15 @@ namespace matador::backends::sqlite {
|
|||
|
||||
class sqlite_query_result : public sql::query_result_impl {
|
||||
public:
|
||||
using columns = std::vector<char*>;
|
||||
using rows = std::vector<columns>;
|
||||
|
||||
public:
|
||||
sqlite_query_result(sql::record prototype, rows result);
|
||||
~sqlite_query_result() override;
|
||||
|
||||
size_t column_count() const override;
|
||||
|
||||
void read_value(const char *id, size_t index, char &value) override;
|
||||
void read_value(const char *id, size_t index, short &value) override;
|
||||
void read_value(const char *id, size_t index, int &value) override;
|
||||
|
|
@ -39,9 +47,6 @@ private:
|
|||
void push_back(char **row_values, int column_count);
|
||||
|
||||
private:
|
||||
using columns = std::vector<char*>;
|
||||
using rows = std::vector<columns>;
|
||||
|
||||
rows result_;
|
||||
long long row_index_ = -1;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,14 +37,37 @@ bool sqlite_connection::is_open()
|
|||
return sqlite_db_ != nullptr;
|
||||
}
|
||||
|
||||
struct fetch_context
|
||||
{
|
||||
sql::record prototype;
|
||||
sqlite_query_result::rows rows;
|
||||
};
|
||||
|
||||
int sqlite_connection::parse_result(void* param, int column_count, char** values, char** columns)
|
||||
{
|
||||
auto *result = static_cast<sqlite_query_result*>(param);
|
||||
result->push_back(values, column_count);
|
||||
auto *context = static_cast<fetch_context*>(param);
|
||||
|
||||
sql::record prototype;
|
||||
sqlite_query_result::columns column;
|
||||
for(int i = 0; i < column_count; ++i) {
|
||||
prototype.append(sql::column{columns[i]});
|
||||
// copy and store column data;
|
||||
if (values[i] == nullptr) {
|
||||
auto val = new char[1];
|
||||
val[0] = '\0';
|
||||
column.push_back(val);
|
||||
} else {
|
||||
size_t size = strlen(values[i]);
|
||||
auto val = new char[size + 1];
|
||||
std::memcpy(val, values[i], size);
|
||||
val[size] = '\0';
|
||||
column.push_back(val);
|
||||
}
|
||||
}
|
||||
context->rows.emplace_back(column);
|
||||
|
||||
if (context->prototype.empty()) {
|
||||
for(int i = 0; i < column_count; ++i) {
|
||||
context->prototype.append(sql::column{columns[i]});
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -62,13 +85,13 @@ size_t sqlite_connection::execute(const std::string &stmt)
|
|||
|
||||
std::unique_ptr<sql::query_result_impl> sqlite_connection::fetch(const std::string &stmt)
|
||||
{
|
||||
auto result = std::make_unique<sqlite_query_result>();
|
||||
fetch_context context;
|
||||
char *errmsg = nullptr;
|
||||
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, result.get(), &errmsg);
|
||||
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, &context, &errmsg);
|
||||
|
||||
throw_sqlite_error(ret, sqlite_db_, "sqlite", stmt);
|
||||
|
||||
return std::move(result);
|
||||
return std::move(std::make_unique<sqlite_query_result>(std::move(context.prototype), std::move(context.rows)));
|
||||
}
|
||||
|
||||
void sqlite_connection::prepare(const std::string &stmt)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace matador::backends::sqlite {
|
||||
|
||||
template < class Type >
|
||||
|
|
@ -48,6 +50,11 @@ void read(Type &x, const char *val, typename std::enable_if<std::is_floating_poi
|
|||
}
|
||||
}
|
||||
|
||||
sqlite_query_result::sqlite_query_result(sql::record prototype, sqlite_query_result::rows result)
|
||||
: sql::query_result_impl(std::move(prototype))
|
||||
, result_(std::move(result))
|
||||
{}
|
||||
|
||||
sqlite_query_result::~sqlite_query_result()
|
||||
{
|
||||
std::for_each(result_.begin(), result_.end(), [](rows ::value_type& row) {
|
||||
|
|
@ -57,6 +64,11 @@ sqlite_query_result::~sqlite_query_result()
|
|||
});
|
||||
}
|
||||
|
||||
size_t sqlite_query_result::column_count() const
|
||||
{
|
||||
return prototype_.size();
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, char &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
|
|
@ -265,5 +277,4 @@ void sqlite_query_result::read_value(const char *id, size_t index, sql::any_type
|
|||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
#define QUERY_COLUMN_GENERATOR_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/types.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
|
@ -13,6 +12,8 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
class table_repository;
|
||||
|
||||
class fk_column_generator
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -29,17 +29,23 @@ public:
|
|||
[[nodiscard]] bool is_open() const;
|
||||
[[nodiscard]] const connection_info& info() const;
|
||||
|
||||
[[nodiscard]] record describe(const std::string &table_name) const;
|
||||
|
||||
template<class Type>
|
||||
query_result<Type> fetch(const std::string &sql)
|
||||
{
|
||||
return query_result<Type>(connection_->execute(sql));
|
||||
return query_result<Type>(connection_->fetch(sql));
|
||||
}
|
||||
query_result<record> fetch(const std::string &sql);
|
||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
||||
[[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
||||
[[nodiscard]] std::pair<size_t, std::string> execute(const std::string &sql) const;
|
||||
|
||||
private:
|
||||
friend class session;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<query_result_impl> call_fetch(const std::string &sql) const;
|
||||
|
||||
private:
|
||||
connection_info connection_info_;
|
||||
bool is_open_{false};
|
||||
std::unique_ptr<connection_impl> connection_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,13 @@ enum class join_type_t {
|
|||
INNER, OUTER, LEFT, RIGHT
|
||||
};
|
||||
|
||||
struct query
|
||||
{
|
||||
std::string sql;
|
||||
record prototype;
|
||||
std::vector<any_type> host_vars;
|
||||
};
|
||||
|
||||
class query_builder
|
||||
{
|
||||
private:
|
||||
|
|
@ -123,8 +130,6 @@ public:
|
|||
|
||||
std::string compile();
|
||||
|
||||
[[nodiscard]] const record& prototype() const;
|
||||
|
||||
private:
|
||||
void transition_to(state_t next);
|
||||
void initialize(command_t cmd, state_t state);
|
||||
|
|
@ -139,7 +144,7 @@ private:
|
|||
|
||||
detail::any_type_to_string_visitor value_to_string_;
|
||||
|
||||
record prototype_;
|
||||
query query_;
|
||||
|
||||
using query_state_set = std::unordered_set<state_t>;
|
||||
using query_state_transition_map = std::unordered_map<state_t, query_state_set>;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ protected:
|
|||
using query_intermediate::query_intermediate;
|
||||
|
||||
public:
|
||||
template < class Type >
|
||||
query_result<Type> fetch_all()
|
||||
{
|
||||
return query_result<Type>(fetch());
|
||||
}
|
||||
|
||||
query_result<record> fetch_all();
|
||||
record fetch_one();
|
||||
template<typename Type>
|
||||
|
|
@ -55,6 +61,9 @@ public:
|
|||
auto result = fetch_all();
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<query_result_impl> fetch();
|
||||
};
|
||||
|
||||
class query_limit_intermediate : public query_select_finish
|
||||
|
|
@ -124,7 +133,6 @@ public:
|
|||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||
|
||||
};
|
||||
|
||||
class query_into_intermediate : public query_intermediate
|
||||
|
|
@ -149,7 +157,7 @@ public:
|
|||
template<class Type>
|
||||
query_execute_finish table(const std::string &table_name)
|
||||
{
|
||||
const auto &info = repository_.attach<Type>(table_name, record{column_generator::generate<Type>(repository_)});
|
||||
const auto &info = repository_.attach<Type>(table_name/*, record{column_generator::generate<Type>(repository_)}*/);
|
||||
return {db(), query().table(table_name, info.prototype.columns())};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ public:
|
|||
public:
|
||||
explicit query_result(std::unique_ptr<query_result_impl> impl)
|
||||
: impl_(std::move(impl)) {}
|
||||
|
||||
query_result(std::unique_ptr<query_result_impl> impl, creator_func creator)
|
||||
: creator_(creator)
|
||||
, impl_(std::move(impl)) {}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/types.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -16,6 +17,8 @@ class query_result_impl
|
|||
public:
|
||||
virtual ~query_result_impl() = default;
|
||||
|
||||
virtual size_t column_count() const = 0;
|
||||
|
||||
virtual void read_value(const char *id, size_t index, char &value) = 0;
|
||||
virtual void read_value(const char *id, size_t index, short &value) = 0;
|
||||
virtual void read_value(const char *id, size_t index, int &value) = 0;
|
||||
|
|
@ -79,8 +82,14 @@ public:
|
|||
[[nodiscard]] virtual const char* column(size_t index) const = 0;
|
||||
[[nodiscard]] virtual bool fetch() = 0;
|
||||
|
||||
const record& prototype() const;
|
||||
|
||||
protected:
|
||||
explicit query_result_impl(record prototype);
|
||||
|
||||
protected:
|
||||
size_t column_index_ = 0;
|
||||
record prototype_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ public:
|
|||
query_update_intermediate update(const std::string &table);
|
||||
query_delete_intermediate remove();
|
||||
|
||||
query_result<record> fetch(const std::string &sql);
|
||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
||||
[[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
||||
[[nodiscard]] std::pair<size_t, std::string> execute(const std::string &sql) const;
|
||||
|
||||
template<typename Type>
|
||||
void attach(const std::string &table_name)
|
||||
|
|
@ -40,6 +40,11 @@ public:
|
|||
|
||||
[[nodiscard]] const table_repository& tables() const;
|
||||
|
||||
private:
|
||||
friend class query_select_finish;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<query_result_impl> call_fetch(const std::string &sql) const;
|
||||
|
||||
private:
|
||||
connection_pool<connection> &pool_;
|
||||
query_builder query_;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef QUERY_TABLE_REPOSITORY_HPP
|
||||
#define QUERY_TABLE_REPOSITORY_HPP
|
||||
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
|
@ -20,12 +21,11 @@ class table_repository
|
|||
{
|
||||
public:
|
||||
template<typename Type>
|
||||
const table_info& attach(const std::string &table_name, const record &proto)
|
||||
const table_info& attach(const std::string &table_name)
|
||||
{
|
||||
return attach(std::type_index(typeid(Type)), table_name, proto);
|
||||
return attach(std::type_index(typeid(Type)), table_info{table_name, record{column_generator::generate<Type>(*this)}});
|
||||
}
|
||||
|
||||
const table_info& attach(std::type_index ti, const std::string &table_name, const record &proto);
|
||||
const table_info& attach(std::type_index ti, const table_info& table);
|
||||
|
||||
template<typename Type>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
|
|
|
|||
|
|
@ -63,14 +63,25 @@ const connection_info &connection::info() const
|
|||
return connection_info_;
|
||||
}
|
||||
|
||||
query_result<record> connection::fetch(const std::string &sql)
|
||||
record connection::describe(const std::string &table_name) const
|
||||
{
|
||||
return std::move(connection_->describe(table_name));
|
||||
}
|
||||
|
||||
query_result<record> connection::fetch(const std::string &sql) const
|
||||
{
|
||||
auto rec = connection_->describe("person");
|
||||
return {connection_->fetch(sql), [rec](){ return new record(rec); }};
|
||||
}
|
||||
|
||||
std::pair<size_t, std::string> connection::execute(const std::string &sql)
|
||||
std::pair<size_t, std::string> connection::execute(const std::string &sql) const
|
||||
{
|
||||
return {connection_->execute(sql), sql};
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> connection::call_fetch(const std::string &sql) const
|
||||
{
|
||||
return connection_->fetch(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,13 +108,13 @@ query_builder& query_builder::select(const std::vector<std::string> &column_name
|
|||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::SELECT) + " ");
|
||||
|
||||
prototype_.clear();
|
||||
query_.prototype.clear();
|
||||
|
||||
std::string result;
|
||||
if (column_names.size() < 2) {
|
||||
for (const auto &col : column_names) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
prototype_.append(column{col});
|
||||
query_.prototype.append(column{col});
|
||||
}
|
||||
} else {
|
||||
auto it = column_names.begin();
|
||||
|
|
@ -122,7 +122,7 @@ query_builder& query_builder::select(const std::vector<std::string> &column_name
|
|||
for (; it != column_names.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
prototype_.append(column{*it});
|
||||
query_.prototype.append(column{*it});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,17 +262,20 @@ query_builder& query_builder::values(const std::vector<any_type> &values) {
|
|||
std::string result{"("};
|
||||
if (values.size() < 2) {
|
||||
for (auto val : values) {
|
||||
query_.host_vars.push_back(val);
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
} else {
|
||||
auto it = values.begin();
|
||||
auto val = *it++;
|
||||
query_.host_vars.push_back(val);
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
for (; it != values.end(); ++it) {
|
||||
result.append(", ");
|
||||
val = *it;
|
||||
query_.host_vars.push_back(val);
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
|
|
@ -403,11 +406,6 @@ std::string query_builder::compile() {
|
|||
return result;
|
||||
}
|
||||
|
||||
const record& query_builder::prototype() const
|
||||
{
|
||||
return prototype_;
|
||||
}
|
||||
|
||||
void query_builder::transition_to(query_builder::state_t next)
|
||||
{
|
||||
if (transitions_[state_].count(next) == 0) {
|
||||
|
|
@ -419,6 +417,7 @@ void query_builder::transition_to(query_builder::state_t next)
|
|||
void query_builder::initialize(query_builder::command_t cmd, query_builder::state_t state)
|
||||
{
|
||||
command_ = cmd;
|
||||
query_ = {};
|
||||
state_ = state;
|
||||
query_parts_.clear();
|
||||
}
|
||||
|
|
@ -432,11 +431,9 @@ std::string build_create_column(const column &col, const dialect &d, column_cont
|
|||
result.append(" NOT NULL");
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
|
||||
// result.append(" PRIMARY KEY");
|
||||
context.primary_keys.emplace_back(col.name());
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::FOREIGN_KEY)) {
|
||||
// result.append(" FOREIGN KEY");
|
||||
context.foreign_contexts.push_back({col.name(), col.ref_table(), col.ref_column()});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ record query_select_finish::fetch_one()
|
|||
return *db().fetch(query().compile()).begin().get();
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
||||
{
|
||||
return db().call_fetch(query().compile());
|
||||
}
|
||||
|
||||
query_intermediate::query_intermediate(session &db, query_builder &query)
|
||||
: db_(db), query_(query) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,4 +28,13 @@ query_result_impl::on_attribute(const char *id, any_type &value, data_type_t typ
|
|||
read_value(id, column_index_++, value, type, attr.size());
|
||||
}
|
||||
|
||||
const record& query_result_impl::prototype() const
|
||||
{
|
||||
return prototype_;
|
||||
}
|
||||
|
||||
query_result_impl::query_result_impl(record prototype)
|
||||
: prototype_(std::move(prototype))
|
||||
{}
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,11 @@ record::record(const std::vector<column> &columns)
|
|||
init();
|
||||
}
|
||||
|
||||
const std::vector<column> &record::columns() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
||||
bool record::has_primary_key() const
|
||||
{
|
||||
return pk_index_ > -1;
|
||||
|
|
@ -30,11 +35,6 @@ const column &record::primary_key() const
|
|||
return columns_[pk_index_];
|
||||
}
|
||||
|
||||
const std::vector<column> &record::columns() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
||||
const column &record::at(const std::string &name) const
|
||||
{
|
||||
return columns_by_name_.at(name).first;
|
||||
|
|
@ -113,7 +113,6 @@ void record::init()
|
|||
size_t index{0};
|
||||
for(auto &col : columns_) {
|
||||
add_to_map(col, index++);
|
||||
// columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index++});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ query_drop_intermediate session::drop()
|
|||
|
||||
query_select_intermediate session::select(std::initializer_list<std::string> column_names)
|
||||
{
|
||||
|
||||
return query_select_intermediate{*this, query_.select(column_names)};
|
||||
}
|
||||
|
||||
|
|
@ -40,15 +41,14 @@ query_delete_intermediate session::remove()
|
|||
return query_delete_intermediate{*this, query_.remove()};
|
||||
}
|
||||
|
||||
query_result<record> session::fetch(const std::string &sql) {
|
||||
auto c = pool_.acquire();
|
||||
if (!c.valid()) {
|
||||
throw std::logic_error("no database connection available");
|
||||
}
|
||||
return c->fetch(sql);
|
||||
query_result<record> session::fetch(const std::string &sql) const
|
||||
{
|
||||
auto res = call_fetch(sql);
|
||||
auto proto = res->prototype();
|
||||
return query_result<record>{std::move(res), [proto]() { return new record(proto); }};
|
||||
}
|
||||
|
||||
std::pair<size_t, std::string> session::execute(const std::string &sql) {
|
||||
std::pair<size_t, std::string> session::execute(const std::string &sql) const {
|
||||
auto c = pool_.acquire();
|
||||
if (!c.valid()) {
|
||||
throw std::logic_error("no database connection available");
|
||||
|
|
@ -60,4 +60,14 @@ const table_repository& session::tables() const
|
|||
{
|
||||
return table_repository_;
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> session::call_fetch(const std::string &sql) const
|
||||
{
|
||||
auto c = pool_.acquire();
|
||||
if (!c.valid()) {
|
||||
throw std::logic_error("no database connection available");
|
||||
}
|
||||
return c->call_fetch(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,11 +4,6 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
const table_info &table_repository::attach(std::type_index ti, const std::string &table_name, const record &proto)
|
||||
{
|
||||
return attach(ti, table_info{table_name, proto});
|
||||
}
|
||||
|
||||
const table_info& table_repository::attach(const std::type_index ti, const table_info& table)
|
||||
{
|
||||
return repository_.try_emplace(ti, table).first->second;
|
||||
|
|
|
|||
|
|
@ -161,12 +161,13 @@ TEST_CASE("Execute select statement with where clause", "[session]") {
|
|||
.execute();
|
||||
REQUIRE(res.first == 1);
|
||||
|
||||
auto result = s.select<person>()
|
||||
// fetch person as record
|
||||
auto result_record = s.select<person>()
|
||||
.from("person")
|
||||
.where("id"_col == 7)
|
||||
.fetch_all();
|
||||
|
||||
for (const auto& i : result) {
|
||||
for (const auto& i : result_record) {
|
||||
REQUIRE(i.size() == 3);
|
||||
REQUIRE(i.at(0).name() == "id");
|
||||
REQUIRE(i.at(0).type() == data_type_t::type_long_long);
|
||||
|
|
@ -179,10 +180,19 @@ TEST_CASE("Execute select statement with where clause", "[session]") {
|
|||
REQUIRE(i.at(2).value<long long>() == george.age);
|
||||
}
|
||||
|
||||
// REQUIRE(res.str() == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
||||
// fetch person as person
|
||||
auto result_person = s.select<person>()
|
||||
.from("person")
|
||||
.where("id"_col == 7)
|
||||
.fetch_all<person>();
|
||||
|
||||
for (const auto& i : result_person) {
|
||||
REQUIRE(i.id == 7);
|
||||
REQUIRE(i.name == "george");
|
||||
REQUIRE(i.age == 45);
|
||||
}
|
||||
|
||||
s.drop().table("person").execute();
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Execute select statement with order by", "[session]") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue