Coverage Report

Created: 2026-06-07 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}