mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Replaced numeric by integral and floating_point
This commit is contained in:
parent
aa5c2c90a6
commit
aae910671e
@ -22,6 +22,8 @@ This results in several benefits, e.g.
|
||||
|
||||
The library supports both static and dynamic queries. The former offers greater benefit in terms of type and consistency checking. The latter makes it easier to construct queries on the flight.
|
||||
|
||||
Specific traits of databases (e.g. unsupported or non-standard features) are known at compile time as well. This way, the compiler can tell the developer at compile time if a query is not accepted by the database (e.g. if a feature is missing). And the library can form the query in the correct manner, for instance if the engine uses concat instead of operator|| to concatenate strings.
|
||||
|
||||
|
||||
Your help is needed:
|
||||
--------------------
|
||||
|
@ -28,7 +28,8 @@
|
||||
#define SQLPP_COLUMN_TYPES_H
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/numeric.h>
|
||||
#include <sqlpp11/integral.h>
|
||||
#include <sqlpp11/floating_point.h>
|
||||
#include <sqlpp11/text.h>
|
||||
|
||||
#endif
|
||||
|
@ -28,18 +28,18 @@
|
||||
#define SQLPP_COUNT_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/numeric.h>
|
||||
#include <sqlpp11/integral.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Expr>
|
||||
struct count_t: public numeric::template operators<count_t<Expr>>
|
||||
struct count_t: public integral::template operators<count_t<Expr>>
|
||||
{
|
||||
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
|
||||
|
||||
struct _value_type: public numeric
|
||||
struct _value_type: public integral
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
|
@ -35,7 +35,8 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
struct boolean;
|
||||
struct numeric;
|
||||
struct integral;
|
||||
struct floating_point;
|
||||
struct text;
|
||||
|
||||
struct bool_operand
|
||||
@ -62,17 +63,41 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct numeric_operand
|
||||
struct integral_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = numeric;
|
||||
using _value_type = integral;
|
||||
|
||||
numeric_operand(T t): _t(t) {}
|
||||
numeric_operand(const numeric_operand&) = default;
|
||||
numeric_operand(numeric_operand&&) = default;
|
||||
numeric_operand& operator=(const numeric_operand&) = default;
|
||||
numeric_operand& operator=(numeric_operand&&) = default;
|
||||
~numeric_operand() = default;
|
||||
integral_operand(T t): _t(t) {}
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct floating_point_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = floating_point;
|
||||
|
||||
floating_point_operand(T t): _t(t) {}
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
@ -124,7 +149,13 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = numeric_operand<T>;
|
||||
using type = integral_operand<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -24,8 +24,8 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_NUMERIC_H
|
||||
#define SQLPP_NUMERIC_H
|
||||
#ifndef SQLPP_FLOATING_POINT_H
|
||||
#define SQLPP_FLOATING_POINT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
@ -38,29 +38,30 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// numeric value type
|
||||
struct numeric
|
||||
// floating_point value type
|
||||
struct floating_point
|
||||
{
|
||||
using _base_value_type = numeric;
|
||||
using _base_value_type = floating_point;
|
||||
using _is_numeric = std::true_type;
|
||||
using _is_floating_point = std::true_type;
|
||||
using _is_value = std::true_type;
|
||||
using _is_expression = std::true_type;
|
||||
|
||||
template<size_t index>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = numeric;
|
||||
using _value_type = floating_point;
|
||||
_result_entry_t(const raw_result_row_t& row):
|
||||
_is_valid(row.data != nullptr),
|
||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(row.data[index], nullptr, 10))
|
||||
_value(_is_null ? 0 : std::strtod(row.data[index], nullptr))
|
||||
{}
|
||||
|
||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
||||
{
|
||||
_is_valid = (row.data != nullptr);
|
||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(row.data[index], nullptr, 10);
|
||||
_value = _is_null ? 0 : std::strtod(row.data[index], nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -79,42 +80,42 @@ namespace sqlpp
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
int64_t value() const
|
||||
double value() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator int64_t() const { return value(); }
|
||||
operator double() const { return value(); }
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
int64_t _value;
|
||||
double _value;
|
||||
};
|
||||
|
||||
struct plus_
|
||||
{
|
||||
using _value_type = numeric;
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
struct minus_
|
||||
{
|
||||
using _value_type = numeric;
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
struct multiplies_
|
||||
{
|
||||
using _value_type = numeric;
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides_
|
||||
{
|
||||
using _value_type = numeric;
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
@ -177,16 +178,13 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<size_t index>
|
||||
std::ostream& operator<<(std::ostream& os, const numeric::_result_entry_t<index>& e)
|
||||
std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<index>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using tinyint = detail::numeric;
|
||||
using smallint = detail::numeric;
|
||||
using integer = detail::numeric;
|
||||
using bigint = detail::numeric;
|
||||
using floating_point = detail::floating_point;
|
||||
|
||||
}
|
||||
#endif
|
196
include/sqlpp11/integral.h
Normal file
196
include/sqlpp11/integral.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_INTEGRAL_H
|
||||
#define SQLPP_INTEGRAL_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/raw_result_row.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// integral value type
|
||||
struct integral
|
||||
{
|
||||
using _base_value_type = integral;
|
||||
using _is_numeric = std::true_type;
|
||||
using _is_floating_point = std::true_type;
|
||||
using _is_value = std::true_type;
|
||||
using _is_expression = std::true_type;
|
||||
|
||||
template<size_t index>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
_result_entry_t(const raw_result_row_t& row):
|
||||
_is_valid(row.data != nullptr),
|
||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(row.data[index], nullptr, 10))
|
||||
{}
|
||||
|
||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
||||
{
|
||||
_is_valid = (row.data != nullptr);
|
||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(row.data[index], nullptr, 10);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == 0; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
int64_t value() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator int64_t() const { return value(); }
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
int64_t _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct plus_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct minus_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct multiplies_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using _constraint = operand_t<T, is_numeric_t>;
|
||||
|
||||
template<typename Base>
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
binary_expression_t<Base, plus_<T>, typename _constraint<T>::type> operator +(T&& t) const
|
||||
{
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, minus_<T>, typename _constraint<T>::type> operator -(T&& t) const
|
||||
{
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, multiplies_<T>, typename _constraint<T>::type> operator *(T&& t) const
|
||||
{
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
|
||||
{
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() + std::forward<T>(t))
|
||||
{
|
||||
return *static_cast<const Base*>(this) = operator +(std::forward<T>(t));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator -=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() - std::forward<T>(t))
|
||||
{
|
||||
return *static_cast<const Base*>(this) = operator -(std::forward<T>(t));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator /=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() / std::forward<T>(t))
|
||||
{
|
||||
return *static_cast<const Base*>(this) = operator /(std::forward<T>(t));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator *=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() * std::forward<T>(t))
|
||||
{
|
||||
return *static_cast<const Base*>(this) = operator *(std::forward<T>(t));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template<size_t index>
|
||||
std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<index>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using tinyint = detail::integral;
|
||||
using smallint = detail::integral;
|
||||
using integer = detail::integral;
|
||||
using bigint = detail::integral;
|
||||
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user