123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*
- * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Badge.h>
- #include <AK/ByteBuffer.h>
- #include <AK/ScopeGuard.h>
- #include <AK/String.h>
- #include <AK/Variant.h>
- #include <LibSQL/Forward.h>
- #include <LibSQL/Serializer.h>
- #include <LibSQL/TupleDescriptor.h>
- #include <LibSQL/Type.h>
- #include <string.h>
- namespace SQL {
- class Value;
- class BaseImpl {
- public:
- explicit BaseImpl(SQLType type = SQLType::Null)
- : m_type(type)
- {
- }
- [[nodiscard]] SQLType type() const { return m_type; }
- [[nodiscard]] String type_name() const { return SQLType_name(type()); }
- private:
- SQLType m_type { SQLType::Null };
- };
- class NullImpl : public BaseImpl {
- public:
- explicit NullImpl()
- : BaseImpl(SQLType::Null)
- {
- }
- [[nodiscard]] static bool is_null() { return true; }
- [[nodiscard]] static String to_string() { return "(null)"; }
- [[nodiscard]] static Optional<int> to_int() { return {}; }
- [[nodiscard]] static Optional<double> to_double() { return {}; }
- [[nodiscard]] static Optional<bool> to_bool() { return {}; }
- [[nodiscard]] static bool to_vector(Vector<Value>&) { return false; }
- static void assign(Value const&) { }
- static void assign_string(String const&) { }
- static void assign_int(int) { }
- static void assign_double(double) { }
- static void assign_bool(bool) { }
- static void assign_vector(Vector<Value> const&) { }
- [[nodiscard]] static size_t length() { return 0; }
- [[nodiscard]] static bool can_cast(Value const&);
- [[nodiscard]] static int compare(Value const&);
- static void serialize(Serializer&) { }
- static void deserialize(Serializer&) { }
- [[nodiscard]] static u32 hash() { return 0; }
- };
- template<typename T>
- class Impl : public BaseImpl {
- public:
- [[nodiscard]] bool is_null() const
- {
- return !m_value.has_value();
- }
- [[nodiscard]] T const& value() const
- {
- VERIFY(m_value.has_value());
- return m_value.value();
- }
- [[nodiscard]] size_t length() const
- {
- return sizeof(T);
- }
- void serialize(Serializer& serializer) const
- {
- serializer.serialize(value());
- }
- void deserialize(Serializer& serializer)
- {
- T value;
- serializer.deserialize_to(value);
- m_value = value;
- }
- protected:
- explicit Impl(SQLType sql_type)
- : BaseImpl(sql_type)
- {
- }
- Optional<T> m_value {};
- };
- class TextImpl : public Impl<String> {
- public:
- explicit TextImpl()
- : Impl(SQLType::Text)
- {
- }
- [[nodiscard]] String to_string() const;
- [[nodiscard]] Optional<int> to_int() const;
- [[nodiscard]] Optional<double> to_double() const;
- [[nodiscard]] Optional<bool> to_bool() const;
- [[nodiscard]] static bool to_vector(Vector<Value>&) { return false; }
- void assign(Value const&);
- void assign_string(String const&);
- void assign_int(int);
- void assign_double(double);
- void assign_bool(bool);
- void assign_vector(Vector<Value> const&) { m_value = {}; }
- [[nodiscard]] size_t length() const;
- [[nodiscard]] static bool can_cast(Value const&) { return true; }
- [[nodiscard]] int compare(Value const& other) const;
- [[nodiscard]] u32 hash() const;
- };
- class IntegerImpl : public Impl<int> {
- public:
- IntegerImpl()
- : Impl(SQLType::Integer)
- {
- }
- [[nodiscard]] String to_string() const;
- [[nodiscard]] Optional<int> to_int() const;
- [[nodiscard]] Optional<double> to_double() const;
- [[nodiscard]] Optional<bool> to_bool() const;
- [[nodiscard]] static bool to_vector(Vector<Value>&) { return false; }
- void assign(Value const&);
- void assign_string(String const&);
- void assign_int(int);
- void assign_double(double);
- void assign_bool(bool);
- void assign_vector(Vector<Value> const&) { m_value = {}; }
- [[nodiscard]] static bool can_cast(Value const&);
- [[nodiscard]] int compare(Value const& other) const;
- [[nodiscard]] u32 hash() const;
- };
- class FloatImpl : public Impl<double> {
- public:
- explicit FloatImpl()
- : Impl(SQLType::Float)
- {
- }
- [[nodiscard]] String to_string() const;
- [[nodiscard]] Optional<int> to_int() const;
- [[nodiscard]] Optional<double> to_double() const;
- [[nodiscard]] static Optional<bool> to_bool() { return {}; }
- [[nodiscard]] static bool to_vector(Vector<Value>&) { return false; }
- void assign(Value const&);
- void assign_string(String const&);
- void assign_int(int);
- void assign_double(double);
- void assign_bool(bool) { m_value = {}; }
- void assign_vector(Vector<Value> const&) { m_value = {}; }
- [[nodiscard]] static bool can_cast(Value const&);
- [[nodiscard]] int compare(Value const& other) const;
- // Using floats in hash functions is a bad idea. Let's disable that for now.
- [[nodiscard]] static u32 hash() { VERIFY_NOT_REACHED(); }
- };
- class BooleanImpl : public Impl<bool> {
- public:
- explicit BooleanImpl()
- : Impl(SQLType::Boolean)
- {
- }
- [[nodiscard]] String to_string() const;
- [[nodiscard]] Optional<int> to_int() const;
- [[nodiscard]] static Optional<double> to_double();
- [[nodiscard]] Optional<bool> to_bool() const;
- [[nodiscard]] static bool to_vector(Vector<Value>&) { return false; }
- void assign(Value const&);
- void assign_string(String const&);
- void assign_int(int);
- void assign_double(double);
- void assign_bool(bool);
- void assign_vector(Vector<Value> const&) { m_value = {}; }
- [[nodiscard]] static bool can_cast(Value const&);
- [[nodiscard]] int compare(Value const& other) const;
- [[nodiscard]] u32 hash() const;
- };
- using BaseTypeImpl = Variant<NullImpl, TextImpl, IntegerImpl, FloatImpl, BooleanImpl>;
- class ContainerValueImpl : public Impl<Vector<BaseTypeImpl>> {
- public:
- virtual ~ContainerValueImpl() = default;
- [[nodiscard]] String to_string() const;
- [[nodiscard]] static Optional<int> to_int() { return {}; }
- [[nodiscard]] static Optional<double> to_double() { return {}; }
- [[nodiscard]] static Optional<bool> to_bool() { return {}; }
- [[nodiscard]] bool to_vector(Vector<Value>&) const;
- void assign_string(String const&) { m_value = {}; }
- void assign_int(int) { m_value = {}; }
- void assign_double(double) { m_value = {}; }
- void assign_bool(bool) { m_value = {}; }
- void assign_vector(Vector<Value> const&);
- [[nodiscard]] u32 hash() const;
- virtual bool validate_before_assignment(Vector<Value> const&) { return true; }
- virtual bool validate(BaseTypeImpl const&) { return true; }
- virtual bool validate_after_assignment() { return true; }
- [[nodiscard]] Vector<String> to_string_vector() const;
- [[nodiscard]] size_t length() const;
- [[nodiscard]] size_t size() const { return is_null() ? 0 : value().size(); }
- bool append(Value const&);
- bool append(BaseTypeImpl const& value);
- void serialize_values(Serializer&) const;
- void deserialize_values(Serializer&);
- protected:
- explicit ContainerValueImpl(SQLType sql_type)
- : Impl(sql_type)
- {
- }
- };
- class TupleImpl : public ContainerValueImpl {
- public:
- explicit TupleImpl(NonnullRefPtr<TupleDescriptor> const& descriptor)
- : ContainerValueImpl(SQLType::Tuple)
- , m_descriptor(descriptor)
- {
- }
- explicit TupleImpl()
- : ContainerValueImpl(SQLType::Tuple)
- {
- }
- void assign(Value const&);
- [[nodiscard]] size_t length() const;
- [[nodiscard]] bool can_cast(Value const&) const;
- [[nodiscard]] int compare(Value const& other) const;
- virtual bool validate_before_assignment(Vector<Value> const&) override;
- virtual bool validate(BaseTypeImpl const&) override;
- virtual bool validate_after_assignment() override;
- void serialize(Serializer&) const;
- void deserialize(Serializer&);
- private:
- void infer_descriptor();
- void extend_descriptor(Value const&);
- RefPtr<TupleDescriptor> m_descriptor;
- bool m_descriptor_inferred { false };
- };
- class ArrayImpl : public ContainerValueImpl {
- public:
- explicit ArrayImpl(SQLType element_type, Optional<size_t> const& max_size = {})
- : ContainerValueImpl(SQLType::Array)
- , m_element_type(element_type)
- , m_max_size(max_size)
- {
- }
- explicit ArrayImpl()
- : ContainerValueImpl(SQLType::Array)
- , m_element_type(SQLType::Null)
- {
- }
- void assign(Value const&);
- [[nodiscard]] size_t length() const;
- [[nodiscard]] bool can_cast(Value const&) const;
- [[nodiscard]] int compare(Value const& other) const;
- void serialize(Serializer&) const;
- void deserialize(Serializer&);
- virtual bool validate(BaseTypeImpl const&) override;
- private:
- SQLType m_element_type { SQLType::Text };
- Optional<size_t> m_max_size {};
- };
- using ValueTypeImpl = Variant<NullImpl, TextImpl, IntegerImpl, FloatImpl, BooleanImpl, TupleImpl, ArrayImpl>;
- }
|