mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-07 18:09:32 -06:00
Added support for varchars
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "sqlgen/Range.hpp"
|
||||
#include "sqlgen/Ref.hpp"
|
||||
#include "sqlgen/Result.hpp"
|
||||
#include "sqlgen/Varchar.hpp"
|
||||
#include "sqlgen/read.hpp"
|
||||
#include "sqlgen/write.hpp"
|
||||
|
||||
|
||||
101
include/sqlgen/Varchar.hpp
Normal file
101
include/sqlgen/Varchar.hpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef SQLGEN_VARCHAR_HPP_
|
||||
#define SQLGEN_VARCHAR_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "Result.hpp"
|
||||
|
||||
namespace sqlgen {
|
||||
|
||||
template <size_t _size>
|
||||
class Varchar {
|
||||
public:
|
||||
using ReflectionType = std::string;
|
||||
|
||||
static constexpr size_t size_ = _size;
|
||||
|
||||
Varchar() : value_("") {}
|
||||
|
||||
Varchar(const std::string& _value) : value_(check_size(_value)) {}
|
||||
|
||||
Varchar(const char* _value) : value_(check_size(_value)) {}
|
||||
|
||||
Varchar(Varchar<_size>&& _other) noexcept = default;
|
||||
|
||||
Varchar(const Varchar<_size>& _other) = default;
|
||||
|
||||
template <size_t _other_size>
|
||||
Varchar(const Varchar<_other_size>& _other)
|
||||
: value_(check_size(_other.get())) {}
|
||||
|
||||
template <size_t _other_size>
|
||||
Varchar(Varchar<_other_size>&& _other) : value_(check_size(_other.get())) {}
|
||||
|
||||
~Varchar() = default;
|
||||
|
||||
static Result<Varchar<size_>> make(const std::string& _value) noexcept {
|
||||
try {
|
||||
return Varchar<size_>(_value);
|
||||
} catch (std::exception& e) {
|
||||
return error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the underlying object.
|
||||
const ReflectionType& get() const { return value_; }
|
||||
|
||||
/// Returns the underlying object.
|
||||
const ReflectionType& operator()() const { return value_; }
|
||||
|
||||
/// Assigns the underlying object.
|
||||
auto& operator=(const char* _value) {
|
||||
value_ = check_size(_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Assigns the underlying object.
|
||||
auto& operator=(const std::string& _value) {
|
||||
value_ = check_size(_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Assigns the underlying object.
|
||||
Varchar<_size>& operator=(const Varchar<_size>& _other) = default;
|
||||
|
||||
/// Assigns the underlying object.
|
||||
Varchar<_size>& operator=(Varchar<_size>&& _other) = default;
|
||||
|
||||
/// Assigns the underlying object.
|
||||
template <size_t _other_size>
|
||||
auto& operator=(const Varchar<_other_size>& _other) {
|
||||
value_ = check_size(_other.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Necessary for the automated transpilation to work.
|
||||
const std::string& reflection() const { return value_; }
|
||||
|
||||
static constexpr size_t size() { return size_; }
|
||||
|
||||
/// Returns the underlying object.
|
||||
const std::string& value() const { return value_; }
|
||||
|
||||
private:
|
||||
static std::string check_size(const std::string& _str) {
|
||||
if (_str.size() > size_) {
|
||||
throw std::runtime_error(
|
||||
"String '" + _str + "' too long: " + std::to_string(_str.size()) +
|
||||
" exceeds the maximum length of " + std::to_string(size_) + ".");
|
||||
}
|
||||
return _str;
|
||||
}
|
||||
|
||||
private:
|
||||
/// The underlying value.
|
||||
std::string value_;
|
||||
};
|
||||
|
||||
} // namespace sqlgen
|
||||
|
||||
#endif
|
||||
@@ -8,5 +8,6 @@
|
||||
#include "Parser_shared_ptr.hpp"
|
||||
#include "Parser_string.hpp"
|
||||
#include "Parser_unique_ptr.hpp"
|
||||
#include "Parser_varchar.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
36
include/sqlgen/parsing/Parser_varchar.hpp
Normal file
36
include/sqlgen/parsing/Parser_varchar.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef SQLGEN_PARSING_PARSER_VARCHAR_HPP_
|
||||
#define SQLGEN_PARSING_PARSER_VARCHAR_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../Result.hpp"
|
||||
#include "../Varchar.hpp"
|
||||
#include "../dynamic/Type.hpp"
|
||||
#include "../dynamic/types.hpp"
|
||||
#include "Parser_base.hpp"
|
||||
|
||||
namespace sqlgen::parsing {
|
||||
|
||||
template <size_t _size>
|
||||
struct Parser<Varchar<_size>> {
|
||||
static Result<Varchar<_size>> read(
|
||||
const std::optional<std::string>& _str) noexcept {
|
||||
return Parser<std::string>::read(_str).and_then(
|
||||
[](auto&& _t) -> Result<Varchar<_size>> {
|
||||
return Varchar<_size>::make(std::move(_t));
|
||||
});
|
||||
}
|
||||
|
||||
static std::optional<std::string> write(const Varchar<_size>& _v) noexcept {
|
||||
return Parser<std::string>::write(_v.value());
|
||||
}
|
||||
|
||||
static dynamic::Type to_type() noexcept {
|
||||
return dynamic::types::VarChar{.length = _size};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sqlgen::parsing
|
||||
|
||||
#endif
|
||||
39
tests/sqlite/test_varchar.cpp
Normal file
39
tests/sqlite/test_varchar.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/sqlite.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_varchar {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
sqlgen::Varchar<6> first_name;
|
||||
sqlgen::Varchar<7> last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(sqlite, test_varchar) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}});
|
||||
|
||||
const auto conn = sqlgen::sqlite::connect();
|
||||
|
||||
sqlgen::write(conn, people1);
|
||||
|
||||
const auto people2 = sqlgen::read<std::vector<Person>>(conn).value();
|
||||
|
||||
const auto json1 = rfl::json::write(people1);
|
||||
const auto json2 = rfl::json::write(people2);
|
||||
|
||||
EXPECT_EQ(json1, json2);
|
||||
}
|
||||
|
||||
} // namespace test_varchar
|
||||
Reference in New Issue
Block a user