mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-01 11:43:41 +00:00
728 lines
18 KiB
C++
728 lines
18 KiB
C++
#pragma once
|
|
#include "../Global.h"
|
|
#include "Types.h"
|
|
|
|
#pragma region AnyConversion
|
|
|
|
namespace DB
|
|
{
|
|
// Declare Any class
|
|
class Any;
|
|
} // namespace DB
|
|
|
|
/**
|
|
* @brief Function to convert Any to T.
|
|
*
|
|
* @tparam T The type to convert to
|
|
* @param v The Any object
|
|
* @return T The converted value
|
|
*/
|
|
template <typename T>
|
|
inline T any_to(const DB::Any& v)
|
|
{
|
|
throw std::bad_cast();
|
|
}
|
|
|
|
template <typename T>
|
|
inline std::vector<DB::Any> to_any_container(const std::vector<T>& v)
|
|
{
|
|
std::vector<DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.push_back(DB::Any(i));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
inline std::set<DB::Any> to_any_container(const std::set<T>& v)
|
|
{
|
|
std::set<DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.insert(DB::Any(i));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
inline std::list<DB::Any> to_any_container(const std::list<T>& v)
|
|
{
|
|
std::list<DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.push_back(DB::Any(i));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
inline std::unordered_set<DB::Any> to_any_container(const std::unordered_set<T>& v)
|
|
{
|
|
std::unordered_set<DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.insert(DB::Any(i));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename K, typename V>
|
|
inline std::map<K, DB::Any> to_any_container(const std::map<K, V>& v)
|
|
{
|
|
std::map<K, DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.insert(std::make_pair(i.first, DB::Any(i.second)));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename K, typename V>
|
|
inline std::unordered_map<K, DB::Any> to_any_unordered_map(const std::unordered_map<K, V>& v)
|
|
{
|
|
std::unordered_map<K, DB::Any> result;
|
|
for (auto& i : v)
|
|
{
|
|
result.insert(std::make_pair(i.first, DB::Any(i.second)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
namespace DB
|
|
{
|
|
|
|
/**
|
|
* @brief Any class to store some SQL basic types
|
|
*
|
|
*/
|
|
class Any
|
|
{
|
|
|
|
public:
|
|
union Value
|
|
{
|
|
bool boolean;
|
|
int64_t integer;
|
|
uint64_t uinteger;
|
|
double floating;
|
|
std::string* string;
|
|
Date* date;
|
|
Time* time;
|
|
DateTime* datetime;
|
|
ByteArray* blob;
|
|
} value; ///< Value
|
|
|
|
enum class Type : char
|
|
{
|
|
Null = 0,
|
|
Boolean = 1,
|
|
Integer = 2,
|
|
UInteger = 3,
|
|
Floating = 4,
|
|
String = 5,
|
|
Date = 6,
|
|
Time = 7,
|
|
DateTime = 8,
|
|
Blob = 9
|
|
} type = Type::Null; ///< Type of the value
|
|
|
|
/**
|
|
* @brief Construct a new Any object with null value.
|
|
*
|
|
*/
|
|
LIAPI Any();
|
|
/**
|
|
* @brief Construct a new Any object with boolean value.
|
|
*
|
|
* @param v The boolean value
|
|
*/
|
|
LIAPI Any(bool v);
|
|
/**
|
|
* @brief Construct a new Any object with int64 value.
|
|
*
|
|
* @param v The integer value
|
|
*/
|
|
LIAPI Any(int64_t v);
|
|
/**
|
|
* @brief Construct a new Any object with uint64 value.
|
|
*
|
|
* @param v The unsigned integer value
|
|
*/
|
|
LIAPI Any(uint64_t v);
|
|
/**
|
|
* @brief Construct a new Any object with double value.
|
|
*
|
|
* @param v The floating value
|
|
*/
|
|
LIAPI Any(double v);
|
|
/**
|
|
* @brief Construct a new Any object with string value.
|
|
*
|
|
* @param v The string value
|
|
*/
|
|
LIAPI Any(const std::string& v);
|
|
/**
|
|
* @brief Construct a new Any object with const char* value.
|
|
*
|
|
* @param v The const char* value
|
|
*/
|
|
LIAPI Any(const char* v);
|
|
/**
|
|
* @brief Construct a new Any object with char* value.
|
|
*
|
|
* @param v The char* value
|
|
* @param len The length of the char* value
|
|
*/
|
|
LIAPI Any(char* v, size_t len);
|
|
/**
|
|
* @brief Construct a new Any object with date value.
|
|
*
|
|
* @param v The Date object
|
|
*/
|
|
LIAPI Any(const Date& v);
|
|
/**
|
|
* @brief Construct a new Any object with time value.
|
|
*
|
|
* @param v The Time object
|
|
*/
|
|
LIAPI Any(const Time& v);
|
|
/**
|
|
* @brief Construct a new Any object with date time value.
|
|
*
|
|
* @param v The DateTime object
|
|
*/
|
|
LIAPI Any(const DateTime& v);
|
|
/**
|
|
* @brief Construct a new Any object with int8(char) value.
|
|
*
|
|
* @param v The char value
|
|
*/
|
|
LIAPI Any(char v);
|
|
/**
|
|
* @brief Construct a new Any object with uint8(unsigned char) value.
|
|
*
|
|
* @param v The unsigned char value
|
|
*/
|
|
LIAPI Any(unsigned char v);
|
|
/**
|
|
* @brief Construct a new Any object with int16(short) value.
|
|
*
|
|
* @param v The short value
|
|
*/
|
|
LIAPI Any(short v);
|
|
/**
|
|
* @brief Construct a new Any object with uint16(unsigned short) value.
|
|
*
|
|
* @param v The unsigned short value
|
|
*/
|
|
LIAPI Any(unsigned short v);
|
|
/**
|
|
* @brief Construct a new Any object with int32(int) value.
|
|
*
|
|
* @param v The int value
|
|
*/
|
|
LIAPI Any(int v);
|
|
/**
|
|
* @brief Construct a new Any object with uint32(unsigned int) value.
|
|
*
|
|
* @param v The unsigned int value
|
|
*/
|
|
LIAPI Any(unsigned int v);
|
|
/**
|
|
* @brief Construct a new Any object with long value.
|
|
*
|
|
* @param v The long value
|
|
*/
|
|
LIAPI Any(long v);
|
|
/**
|
|
* @brief Construct a new Any object with unsigned long value.
|
|
*
|
|
* @param v The unsigned long value
|
|
*/
|
|
LIAPI Any(unsigned long v);
|
|
/**
|
|
* @brief Construct a new Any object with float value.
|
|
*
|
|
* @param v The float value
|
|
*/
|
|
LIAPI Any(float v);
|
|
/**
|
|
* @brief Construct a new Any object with byte array value.
|
|
*
|
|
* @param v The byte array value
|
|
*/
|
|
LIAPI Any(const ByteArray& v);
|
|
/// Copy constructor
|
|
LIAPI Any(const Any& v);
|
|
/// Copy assignment operator
|
|
LIAPI Any& operator=(const Any& v);
|
|
|
|
/// Destructor
|
|
LIAPI ~Any();
|
|
|
|
/**
|
|
* @brief Get if the value is null.
|
|
*
|
|
*/
|
|
LIAPI bool is_null() const;
|
|
/**
|
|
* @brief Get if the value is boolean.
|
|
*
|
|
*/
|
|
LIAPI bool is_boolean() const;
|
|
/**
|
|
* @brief Get if the value is (unsigned) integer.
|
|
*
|
|
*/
|
|
LIAPI bool is_integer() const;
|
|
/**
|
|
* @brief Get if the value is unsigned integer.
|
|
*
|
|
*/
|
|
LIAPI bool is_uinteger() const;
|
|
/**
|
|
* @brief Get if the value is floating.
|
|
*
|
|
*/
|
|
LIAPI bool is_floating() const;
|
|
/**
|
|
* @brief Get if the value is string.
|
|
*
|
|
*/
|
|
LIAPI bool is_string() const;
|
|
/**
|
|
* @brief Get if the value is date.
|
|
*
|
|
*/
|
|
LIAPI bool is_date() const;
|
|
/**
|
|
* @brief Get if the value is time.
|
|
*
|
|
*/
|
|
LIAPI bool is_time() const;
|
|
/**
|
|
* @brief Get if the value is date time.
|
|
*
|
|
*/
|
|
LIAPI bool is_datetime() const;
|
|
/**
|
|
* @brief Get if the value is blob.
|
|
*
|
|
*/
|
|
LIAPI bool is_blob() const;
|
|
/**
|
|
* @brief Get if the value is floating or (unsigned) integer.
|
|
*
|
|
*/
|
|
LIAPI bool is_number() const;
|
|
|
|
/**
|
|
* @brief Get the number value as T
|
|
*
|
|
* @tparam T The C++ basic number type to convert to, such as int, long, double, etc.
|
|
* @return T The value
|
|
* @throws std::bad_cast If the value cannot be converted to T or the value is not a number
|
|
* @note You can use Any::is_number() to check if the value is a number before calling this function.
|
|
* @see is_number()
|
|
*/
|
|
template <typename T>
|
|
inline T get_number() const
|
|
{
|
|
switch (type)
|
|
{
|
|
#if !defined(DBANY_NO_NULL_CONVERSION)
|
|
case Type::Null:
|
|
return 0;
|
|
#endif
|
|
case Type::Boolean:
|
|
return static_cast<T>(value.boolean);
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
return static_cast<T>(value.integer);
|
|
case Type::Floating:
|
|
return static_cast<T>(value.floating);
|
|
case Type::String:
|
|
case Type::Date:
|
|
case Type::Time:
|
|
case Type::DateTime:
|
|
case Type::Blob:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Get the value as T.
|
|
*
|
|
* @tparam T The type of the value
|
|
* @return T The value
|
|
* @throws std::bad_cast If the value cannot be converted to T
|
|
* @par Custom Type Conversion
|
|
* Define a custom type conversion function for the type T
|
|
* @code
|
|
* template <>
|
|
* MyClass any_to(const Any& v) {
|
|
* MyClass result;
|
|
* switch (v.type) {
|
|
* case Any::Type::String:
|
|
* result.a = *v.value.string;
|
|
* default:
|
|
* throw std::bad_cast();
|
|
* }
|
|
* return result;
|
|
* }
|
|
* @endcode
|
|
* @note You can use `#define DBANY_NO_NULL_CONVERSION` to disable null conversion.
|
|
* (throw an exception when trying converting from a null type value)
|
|
* @see any_to
|
|
*/
|
|
template <typename T>
|
|
inline T get() const
|
|
{
|
|
return any_to<T>(*this);
|
|
}
|
|
/**
|
|
* @brief Get the value as string
|
|
*
|
|
* @tparam T = bool
|
|
* @return bool The value
|
|
* @throws std::bad_cast If the value cannot be converted to string
|
|
*/
|
|
template <>
|
|
inline bool get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
#if !defined(DBANY_NO_NULL_CONVERSION)
|
|
case Type::Null:
|
|
return false;
|
|
#endif
|
|
case Type::Boolean:
|
|
return value.boolean;
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
case Type::Floating:
|
|
return (bool)value.integer;
|
|
case Type::String:
|
|
case Type::Date:
|
|
case Type::Time:
|
|
case Type::DateTime:
|
|
case Type::Blob:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Get the value as char
|
|
*
|
|
* @tparam T = char
|
|
* @return char The value
|
|
* @throws std::bad_cast If the value cannot be converted to char
|
|
*/
|
|
template <>
|
|
inline char get() const
|
|
{
|
|
return get_number<char>();
|
|
}
|
|
/**
|
|
* @brief Get the value as unsigned char
|
|
*
|
|
* @tparam T = unsigned char
|
|
* @return unsigned char The value
|
|
* @throws std::bad_cast If the value cannot be converted to unsigned char
|
|
*/
|
|
template <>
|
|
inline unsigned char get() const
|
|
{
|
|
return get_number<unsigned char>();
|
|
}
|
|
/**
|
|
* @brief Get the value as short
|
|
*
|
|
* @tparam T = short
|
|
* @return short The value
|
|
* @throws std::bad_cast If the value cannot be converted to short
|
|
*/
|
|
template <>
|
|
inline short get() const
|
|
{
|
|
return get_number<short>();
|
|
}
|
|
/**
|
|
* @brief Get the value as unsigned short
|
|
*
|
|
* @tparam T = unsigned short
|
|
* @return unsigned short The value
|
|
* @throws std::bad_cast If the value cannot be converted to unsigned short
|
|
*/
|
|
template <>
|
|
inline unsigned short get() const
|
|
{
|
|
return get_number<unsigned short>();
|
|
}
|
|
/**
|
|
* @brief Get the value as int
|
|
*
|
|
* @tparam T = int
|
|
* @return int The value
|
|
* @throws std::bad_cast If the value cannot be converted to int
|
|
*/
|
|
template <>
|
|
inline int get() const
|
|
{
|
|
return get_number<int>();
|
|
}
|
|
/**
|
|
* @brief Get the value as unsigned int
|
|
*
|
|
* @tparam T = unsigned int
|
|
* @return unsigned int The value
|
|
* @throws std::bad_cast If the value cannot be converted to unsigned int
|
|
*/
|
|
template <>
|
|
inline unsigned int get() const
|
|
{
|
|
return get_number<unsigned int>();
|
|
}
|
|
/**
|
|
* @brief Get the value as long
|
|
*
|
|
* @tparam T = long
|
|
* @return long The value
|
|
* @throws std::bad_cast If the value cannot be converted to long
|
|
*/
|
|
template <>
|
|
inline long get() const
|
|
{
|
|
return get_number<long>();
|
|
}
|
|
/**
|
|
* @brief Get the value as unsigned long
|
|
*
|
|
* @tparam T = unsigned long
|
|
* @return unsigned long The value
|
|
* @throws std::bad_cast If the value cannot be converted to unsigned long
|
|
*/
|
|
template <>
|
|
inline unsigned long get() const
|
|
{
|
|
return get_number<unsigned long>();
|
|
}
|
|
/**
|
|
* @brief Get the value as long long
|
|
*
|
|
* @tparam T = long long
|
|
* @return long long The value
|
|
* @throws std::bad_cast If the value cannot be converted to long long
|
|
*/
|
|
template <>
|
|
inline long long get() const
|
|
{
|
|
return get_number<long long>();
|
|
}
|
|
/**
|
|
* @brief Get the value as unsigned long long
|
|
*
|
|
* @tparam T = unsigned long long
|
|
* @return unsigned long long The value
|
|
* @throws std::bad_cast If the value cannot be converted to unsigned long long
|
|
*/
|
|
template <>
|
|
inline unsigned long long get() const
|
|
{
|
|
return get_number<unsigned long long>();
|
|
}
|
|
/**
|
|
* @brief Get the value as double.
|
|
*
|
|
* @tparam T = double
|
|
* @return double The value
|
|
* @throws std::bad_cast If the value cannot be converted to double
|
|
*/
|
|
template <>
|
|
inline double get() const
|
|
{
|
|
return get_number<double>();
|
|
}
|
|
/**
|
|
* @brief Get the value as float.
|
|
*
|
|
* @tparam T = float
|
|
* @return float The value
|
|
* @throws std::bad_cast If the value cannot be converted to float
|
|
*/
|
|
template <>
|
|
inline float get() const
|
|
{
|
|
return get_number<float>();
|
|
}
|
|
/**
|
|
* @brief Get the value as string.
|
|
*
|
|
* @tparam T = std::string
|
|
* @return std::string The value
|
|
* @throws std::bad_cast If the value cannot be converted to string
|
|
*/
|
|
template <>
|
|
std::string get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
#if !defined(DBANY_NO_NULL_CONVERSION)
|
|
case Type::Null:
|
|
return "";
|
|
#endif
|
|
case Type::Boolean:
|
|
return value.boolean ? "true" : "false";
|
|
case Type::Integer:
|
|
return std::to_string(value.integer);
|
|
case Type::UInteger:
|
|
return std::to_string(value.uinteger);
|
|
case Type::Floating:
|
|
return std::to_string(value.floating);
|
|
case Type::String:
|
|
return *value.string;
|
|
case Type::Date:
|
|
return std::to_string(value.date->year) + "-" +
|
|
std::to_string(value.date->month) + "-" +
|
|
std::to_string(value.date->day);
|
|
break;
|
|
case Type::Time:
|
|
return std::to_string(value.time->hour) + ":" +
|
|
std::to_string(value.time->minute) + ":" +
|
|
std::to_string(value.time->second);
|
|
case Type::DateTime:
|
|
return std::to_string(value.datetime->date.year) + "-" +
|
|
std::to_string(value.datetime->date.month) + "-" +
|
|
std::to_string(value.datetime->date.day) + " " +
|
|
std::to_string(value.datetime->time.hour) + ":" +
|
|
std::to_string(value.datetime->time.minute) + ":" +
|
|
std::to_string(value.datetime->time.second);
|
|
case Type::Blob:
|
|
return std::string(value.blob->begin(), value.blob->end());
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Get the value as Date
|
|
*
|
|
* @tparam T = DB::Date
|
|
* @return DB::Date The value
|
|
* @throws std::bad_cast If the value cannot be converted to DB::Date
|
|
*/
|
|
template <>
|
|
Date get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
case Type::Date:
|
|
return *value.date;
|
|
case Type::DateTime:
|
|
return value.datetime->date;
|
|
case Type::String:
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
case Type::Floating:
|
|
case Type::Time:
|
|
case Type::Blob:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Get the value as Time
|
|
*
|
|
* @tparam T = DB::Time
|
|
* @return DB::Time The value
|
|
* @throws std::bad_cast If the value cannot be converted to DB::Time
|
|
*/
|
|
template <>
|
|
Time get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
case Type::Time:
|
|
return *value.time;
|
|
case Type::DateTime:
|
|
return value.datetime->time;
|
|
case Type::String:
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
case Type::Floating:
|
|
case Type::Date:
|
|
case Type::Blob:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Get the value as DateTime
|
|
*
|
|
* @tparam T = DB::DateTime
|
|
* @return DB::DateTime The value
|
|
* @throws std::bad_cast If the value cannot be converted to DB::DateTime
|
|
*/
|
|
template <>
|
|
DateTime get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
case Type::DateTime:
|
|
return *value.datetime;
|
|
case Type::String:
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
case Type::Floating:
|
|
case Type::Date:
|
|
case Type::Time:
|
|
case Type::Blob:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Get the value as ByteArray
|
|
*
|
|
* @tparam T = DB::ByteArray
|
|
* @return DB::ByteArray The value
|
|
* @throws std::bad_cast If the value cannot be converted to DB::ByteArray
|
|
*/
|
|
template <>
|
|
ByteArray get() const
|
|
{
|
|
switch (type)
|
|
{
|
|
case Type::Blob:
|
|
return *value.blob;
|
|
case Type::String:
|
|
return ByteArray((unsigned char*)value.string->data(),
|
|
(unsigned char*)value.string->data() + value.string->size());
|
|
case Type::Integer:
|
|
case Type::UInteger:
|
|
case Type::Floating:
|
|
case Type::Date:
|
|
case Type::Time:
|
|
case Type::DateTime:
|
|
default:
|
|
throw std::bad_cast();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Convert Any::Type to string.
|
|
*
|
|
* @param type The Any::Type value
|
|
* @return std::string The string value
|
|
*/
|
|
LIAPI static std::string type2str(Any::Type type);
|
|
|
|
/**
|
|
* @brief Convert string to Any.
|
|
*
|
|
* @param str The string
|
|
* @return Any The converted value
|
|
*/
|
|
LIAPI static Any str2any(const std::string& str);
|
|
|
|
};
|
|
|
|
} // namespace DB
|