Serenity Operating System
at master 199 lines 5.7 kB view raw
1/* 2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> 3 * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/Checked.h> 11#include <AK/DeprecatedString.h> 12#include <AK/Format.h> 13#include <AK/Optional.h> 14#include <AK/StringView.h> 15#include <AK/Variant.h> 16#include <AK/Vector.h> 17#include <LibIPC/Forward.h> 18#include <LibSQL/Forward.h> 19#include <LibSQL/Result.h> 20#include <LibSQL/Type.h> 21#include <math.h> 22 23namespace SQL { 24 25template<typename T> 26concept Boolean = SameAs<RemoveCVReference<T>, bool>; 27 28template<typename T> 29concept Integer = (Integral<T> && !Boolean<T>); 30 31/** 32 * A `Value` is an atomic piece of SQL data`. A `Value` has a basic type 33 * (Text/String, Integer, Float, etc). Richer types are implemented in higher 34 * level layers, but the resulting data is stored in these `Value` objects. 35 */ 36class Value { 37 template<Integer T> 38 using IntegerType = Conditional<IsSigned<T>, i64, u64>; 39 40public: 41 explicit Value(SQLType sql_type = SQLType::Null); 42 explicit Value(DeprecatedString); 43 explicit Value(double); 44 Value(Value const&); 45 Value(Value&&); 46 ~Value(); 47 48 explicit Value(Integer auto value) 49 : m_type(SQLType::Integer) 50 , m_value(static_cast<IntegerType<decltype(value)>>(value)) 51 { 52 } 53 54 explicit Value(Boolean auto value) 55 : m_type(SQLType::Boolean) 56 , m_value(value) 57 { 58 } 59 60 static ResultOr<Value> create_tuple(NonnullRefPtr<TupleDescriptor>); 61 static ResultOr<Value> create_tuple(Vector<Value>); 62 63 [[nodiscard]] SQLType type() const; 64 [[nodiscard]] StringView type_name() const; 65 [[nodiscard]] bool is_type_compatible_with(SQLType) const; 66 [[nodiscard]] bool is_null() const; 67 [[nodiscard]] bool is_int() const; 68 69 [[nodiscard]] auto const& value() const 70 { 71 VERIFY(m_value.has_value()); 72 return *m_value; 73 } 74 75 [[nodiscard]] DeprecatedString to_deprecated_string() const; 76 [[nodiscard]] Optional<double> to_double() const; 77 [[nodiscard]] Optional<bool> to_bool() const; 78 [[nodiscard]] Optional<Vector<Value>> to_vector() const; 79 80 template<Integer T> 81 [[nodiscard]] Optional<T> to_int() const 82 { 83 if (is_null()) 84 return {}; 85 86 return m_value->visit( 87 [](DeprecatedString const& value) -> Optional<T> { 88 if constexpr (IsSigned<T>) 89 return value.to_int<T>(); 90 else 91 return value.to_uint<T>(); 92 }, 93 [](Integer auto value) -> Optional<T> { 94 if (!AK::is_within_range<T>(value)) 95 return {}; 96 return static_cast<T>(value); 97 }, 98 [](double value) -> Optional<T> { 99 if (!AK::is_within_range<T>(value)) 100 return {}; 101 return static_cast<T>(round(value)); 102 }, 103 [](bool value) -> Optional<T> { return static_cast<T>(value); }, 104 [](TupleValue const&) -> Optional<T> { return {}; }); 105 } 106 107 Value& operator=(Value); 108 Value& operator=(DeprecatedString); 109 Value& operator=(double); 110 111 Value& operator=(Integer auto value) 112 { 113 m_type = SQLType::Integer; 114 m_value = static_cast<IntegerType<decltype(value)>>(value); 115 return *this; 116 } 117 118 ResultOr<void> assign_tuple(NonnullRefPtr<TupleDescriptor>); 119 ResultOr<void> assign_tuple(Vector<Value>); 120 121 Value& operator=(Boolean auto value) 122 { 123 m_type = SQLType::Boolean; 124 m_value = value; 125 return *this; 126 } 127 128 [[nodiscard]] size_t length() const; 129 [[nodiscard]] u32 hash() const; 130 void serialize(Serializer&) const; 131 void deserialize(Serializer&); 132 133 [[nodiscard]] int compare(Value const&) const; 134 bool operator==(Value const&) const; 135 bool operator==(StringView) const; 136 bool operator==(double) const; 137 138 template<Integer T> 139 bool operator==(T value) 140 { 141 return to_int<T>() == value; 142 } 143 144 bool operator!=(Value const&) const; 145 bool operator<(Value const&) const; 146 bool operator<=(Value const&) const; 147 bool operator>(Value const&) const; 148 bool operator>=(Value const&) const; 149 150 ResultOr<Value> add(Value const&) const; 151 ResultOr<Value> subtract(Value const&) const; 152 ResultOr<Value> multiply(Value const&) const; 153 ResultOr<Value> divide(Value const&) const; 154 ResultOr<Value> modulo(Value const&) const; 155 ResultOr<Value> negate() const; 156 ResultOr<Value> shift_left(Value const&) const; 157 ResultOr<Value> shift_right(Value const&) const; 158 ResultOr<Value> bitwise_or(Value const&) const; 159 ResultOr<Value> bitwise_and(Value const&) const; 160 ResultOr<Value> bitwise_not() const; 161 162 [[nodiscard]] TupleElementDescriptor descriptor() const; 163 164private: 165 friend Serializer; 166 167 struct TupleValue { 168 NonnullRefPtr<TupleDescriptor> descriptor; 169 Vector<Value> values; 170 }; 171 172 using ValueType = Variant<DeprecatedString, i64, u64, double, bool, TupleValue>; 173 174 static ResultOr<NonnullRefPtr<TupleDescriptor>> infer_tuple_descriptor(Vector<Value> const& values); 175 Value(NonnullRefPtr<TupleDescriptor> descriptor, Vector<Value> values); 176 177 SQLType m_type { SQLType::Null }; 178 Optional<ValueType> m_value; 179}; 180 181} 182 183template<> 184struct AK::Formatter<SQL::Value> : Formatter<StringView> { 185 ErrorOr<void> format(FormatBuilder& builder, SQL::Value const& value) 186 { 187 return Formatter<StringView>::format(builder, value.to_deprecated_string()); 188 } 189}; 190 191namespace IPC { 192 193template<> 194ErrorOr<void> encode(Encoder&, SQL::Value const&); 195 196template<> 197ErrorOr<SQL::Value> decode(Decoder&); 198 199}