mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-04 08:30:30 -06:00
Added more formal support for create table
This commit is contained in:
@@ -103,14 +103,14 @@ if (PROJECT_IS_TOP_LEVEL)
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/sqlgen"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE RFL_HEADERS RELATIVE ${CMAKE_CURRENT_LIST_DIR} "${CMAKE_CURRENT_LIST_DIR}/include/*" )
|
||||
file(GLOB_RECURSE SQLGEN_HEADERS RELATIVE ${CMAKE_CURRENT_LIST_DIR} "${CMAKE_CURRENT_LIST_DIR}/include/*" )
|
||||
|
||||
target_sources(sqlgen
|
||||
PUBLIC
|
||||
FILE_SET sqlgen_headers
|
||||
TYPE HEADERS
|
||||
BASE_DIRS $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
|
||||
FILES ${RFL_HEADERS})
|
||||
FILES ${SQLGEN_HEADERS})
|
||||
|
||||
install(
|
||||
TARGETS sqlgen
|
||||
|
||||
@@ -14,6 +14,7 @@ Welcome to the sqlgen documentation. This guide provides detailed information ab
|
||||
|
||||
- [sqlgen::read](reading.md) - How to read data from a database
|
||||
- [sqlgen::write](writing.md) - How to write data to a database
|
||||
- [sqlgen::create_table](create_table.md) - How to create a new table
|
||||
- [sqlgen::update](update.md) - How to update data in a table
|
||||
- [sqlgen::delete_from](delete_from.md) - How to delete data from a table
|
||||
- [sqlgen::drop](drop.md) - How to drop a table
|
||||
@@ -30,4 +31,4 @@ Welcome to the sqlgen documentation. This guide provides detailed information ab
|
||||
- [PostgreSQL](postgres.md) - How to interact with PostgreSQL and compatible databases (Redshift, Aurora, Greenplum)
|
||||
- [SQLite](sqlite.md) - How to interact with SQLite3
|
||||
|
||||
For installation instructions, quick start guide, and usage examples, please refer to the [main README](../README.md).
|
||||
For installation instructions, quick start guide, and usage examples, please refer to the [main README](../README.md).
|
||||
|
||||
@@ -91,7 +91,7 @@ struct TestTable {
|
||||
};
|
||||
|
||||
// Create table query
|
||||
const auto create_query = sqlgen::CreateTable<TestTable>{};
|
||||
const auto create_query = create_table<TestTable> | if_not_exists;
|
||||
const auto sql = postgres::to_sql(create_query);
|
||||
```
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define SQLGEN_HPP_
|
||||
|
||||
#include "sqlgen/Connection.hpp"
|
||||
#include "sqlgen/CreateTable.hpp"
|
||||
#include "sqlgen/Flatten.hpp"
|
||||
#include "sqlgen/Insert.hpp"
|
||||
#include "sqlgen/Iterator.hpp"
|
||||
@@ -18,9 +17,11 @@
|
||||
#include "sqlgen/begin_transaction.hpp"
|
||||
#include "sqlgen/col.hpp"
|
||||
#include "sqlgen/commit.hpp"
|
||||
#include "sqlgen/create_table.hpp"
|
||||
#include "sqlgen/delete_from.hpp"
|
||||
#include "sqlgen/drop.hpp"
|
||||
#include "sqlgen/if_exists.hpp"
|
||||
#include "sqlgen/if_not_exists.hpp"
|
||||
#include "sqlgen/limit.hpp"
|
||||
#include "sqlgen/order_by.hpp"
|
||||
#include "sqlgen/patterns.hpp"
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef SQLGEN_CREATETABLE_HPP_
|
||||
#define SQLGEN_CREATETABLE_HPP_
|
||||
|
||||
#include <rfl.hpp>
|
||||
|
||||
namespace sqlgen {
|
||||
|
||||
/// Helper class for to_sql.
|
||||
template <class T>
|
||||
struct CreateTable {};
|
||||
|
||||
}; // namespace sqlgen
|
||||
|
||||
#endif
|
||||
|
||||
46
include/sqlgen/create_table.hpp
Normal file
46
include/sqlgen/create_table.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef SQLGEN_CREATETABLE_HPP_
|
||||
#define SQLGEN_CREATETABLE_HPP_
|
||||
|
||||
#include <rfl.hpp>
|
||||
|
||||
#include "transpilation/to_create_table.hpp"
|
||||
|
||||
namespace sqlgen {
|
||||
|
||||
template <class ValueType>
|
||||
Result<Ref<Connection>> create_table_impl(const Ref<Connection>& _conn,
|
||||
const bool _if_not_exists) {
|
||||
const auto query = transpilation::to_create_table<ValueType>(_if_not_exists);
|
||||
return _conn->execute(_conn->to_sql(query)).transform([&](const auto&) {
|
||||
return _conn;
|
||||
});
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
Result<Ref<Connection>> create_table_impl(const Result<Ref<Connection>>& _res,
|
||||
const bool _if_not_exists) {
|
||||
return _res.and_then([&](const auto& _conn) {
|
||||
return create_table_impl<ValueType>(_conn, _if_not_exists);
|
||||
});
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
struct CreateTable {
|
||||
Result<Ref<Connection>> operator()(const auto& _conn) const noexcept {
|
||||
try {
|
||||
return create_table_impl<ValueType>(_conn, if_not_exists_);
|
||||
} catch (std::exception& e) {
|
||||
return error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool if_not_exists_;
|
||||
};
|
||||
|
||||
template <class ContainerType>
|
||||
const auto create_table = CreateTable<ContainerType>{};
|
||||
|
||||
}; // namespace sqlgen
|
||||
|
||||
#endif
|
||||
|
||||
19
include/sqlgen/if_not_exists.hpp
Normal file
19
include/sqlgen/if_not_exists.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef SQLGEN_IF_NOT_EXISTS_HPP_
|
||||
#define SQLGEN_IF_NOT_EXISTS_HPP_
|
||||
|
||||
namespace sqlgen {
|
||||
|
||||
struct IfNotExists {};
|
||||
|
||||
template <class OtherType>
|
||||
auto operator|(const OtherType& _o, const IfNotExists&) {
|
||||
auto o = _o;
|
||||
o.if_not_exists_ = true;
|
||||
return o;
|
||||
}
|
||||
|
||||
inline const auto if_not_exists = IfNotExists{};
|
||||
|
||||
} // namespace sqlgen
|
||||
|
||||
#endif
|
||||
@@ -18,7 +18,7 @@ namespace sqlgen::transpilation {
|
||||
template <class T>
|
||||
requires std::is_class_v<std::remove_cvref_t<T>> &&
|
||||
std::is_aggregate_v<std::remove_cvref_t<T>>
|
||||
dynamic::CreateTable to_create_table() {
|
||||
dynamic::CreateTable to_create_table(const bool _if_not_exists = true) {
|
||||
using NamedTupleType = rfl::named_tuple_t<std::remove_cvref_t<T>>;
|
||||
using Fields = typename NamedTupleType::Fields;
|
||||
return dynamic::CreateTable{
|
||||
@@ -26,7 +26,7 @@ dynamic::CreateTable to_create_table() {
|
||||
dynamic::Table{.name = get_tablename<T>(), .schema = get_schema<T>()},
|
||||
.columns = make_columns<Fields>(
|
||||
std::make_integer_sequence<int, rfl::tuple_size_v<Fields>>()),
|
||||
.if_not_exists = true};
|
||||
.if_not_exists = _if_not_exists};
|
||||
}
|
||||
|
||||
} // namespace sqlgen::transpilation
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../CreateTable.hpp"
|
||||
#include "../Insert.hpp"
|
||||
#include "../create_table.hpp"
|
||||
#include "../delete_from.hpp"
|
||||
#include "../drop.hpp"
|
||||
#include "../dynamic/Statement.hpp"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(SQLGEN_POSTGRES @SQLGEN_POSTGRES@)
|
||||
set(SQLGEN_SQLITE3 @SQLGEN_SQLITE3@)
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
@@ -8,8 +9,12 @@ include(${CMAKE_CURRENT_LIST_DIR}/sqlgen-exports.cmake)
|
||||
|
||||
find_dependency(reflectcpp)
|
||||
|
||||
if(SQLGEN_POSTGRES)
|
||||
find_dependency(PostgreSQL)
|
||||
endif()
|
||||
|
||||
if(SQLGEN_SQLITE3)
|
||||
find_dependency(sqlite3)
|
||||
find_dependency(unofficial-sqlite3)
|
||||
endif()
|
||||
|
||||
check_required_components(sqlgen)
|
||||
|
||||
30
tests/sqlite/test_create_table.cpp
Normal file
30
tests/sqlite/test_create_table.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/sqlite.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_create_table {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(sqlite, test_create_table) {
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto people = sqlgen::sqlite::connect()
|
||||
.and_then(create_table<Person> | if_not_exists)
|
||||
.and_then(sqlgen::read<std::vector<Person>>);
|
||||
|
||||
const std::string expected = R"([])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people), expected);
|
||||
}
|
||||
|
||||
} // namespace test_create_table
|
||||
Reference in New Issue
Block a user