diff --git a/Userland/Libraries/LibSQL/Value.cpp b/Userland/Libraries/LibSQL/Value.cpp index c7657cc145..ab3ab0c2b3 100644 --- a/Userland/Libraries/LibSQL/Value.cpp +++ b/Userland/Libraries/LibSQL/Value.cpp @@ -6,6 +6,8 @@ */ #include +#include +#include #include #include #include @@ -667,3 +669,91 @@ ResultOr> Value::infer_tuple_descriptor(Vector +bool IPC::encode(Encoder& encoder, SQL::Value const& value) +{ + auto type_flags = to_underlying(value.type()); + if (value.is_null()) + type_flags |= SQL::sql_type_null_as_flag; + + encoder << type_flags; + if (value.is_null()) + return true; + + switch (value.type()) { + case SQL::SQLType::Null: + break; + case SQL::SQLType::Text: + encoder << value.to_deprecated_string(); + break; + case SQL::SQLType::Integer: + encoder << value.to_int().value(); + break; + case SQL::SQLType::Float: + encoder << value.to_double().value(); + break; + case SQL::SQLType::Boolean: + encoder << value.to_bool().value(); + break; + case SQL::SQLType::Tuple: + encoder << value.to_vector().value(); + break; + } + + return true; +} + +template<> +ErrorOr IPC::decode(Decoder& decoder, SQL::Value& value) +{ + UnderlyingType type_flags; + TRY(decoder.decode(type_flags)); + + if ((type_flags & SQL::sql_type_null_as_flag) && (type_flags != SQL::sql_type_null_as_flag)) { + type_flags &= ~SQL::sql_type_null_as_flag; + + value = SQL::Value(static_cast(type_flags)); + return {}; + } + + switch (static_cast(type_flags)) { + case SQL::SQLType::Null: + break; + case SQL::SQLType::Text: { + DeprecatedString text; + TRY(decoder.decode(text)); + value = move(text); + break; + } + case SQL::SQLType::Integer: { + int number { 0 }; + TRY(decoder.decode(number)); + value = number; + break; + } + case SQL::SQLType::Float: { + double number { 0.0 }; + TRY(decoder.decode(number)); + value = number; + break; + } + case SQL::SQLType::Boolean: { + bool boolean { false }; + TRY(decoder.decode(boolean)); + value = boolean; + break; + } + case SQL::SQLType::Tuple: { + Vector tuple; + TRY(decoder.decode(tuple)); + + if (auto result = value.assign_tuple(move(tuple)); result.is_error()) + return Error::from_errno(to_underlying(result.error().error())); + + break; + } + } + + return {}; +} diff --git a/Userland/Libraries/LibSQL/Value.h b/Userland/Libraries/LibSQL/Value.h index 0cc5d3658b..83d2ae03f9 100644 --- a/Userland/Libraries/LibSQL/Value.h +++ b/Userland/Libraries/LibSQL/Value.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -129,3 +130,13 @@ struct AK::Formatter : Formatter { return Formatter::format(builder, value.to_deprecated_string()); } }; + +namespace IPC { + +template<> +bool encode(Encoder&, SQL::Value const&); + +template<> +ErrorOr decode(Decoder&, SQL::Value&); + +}