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