mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 01:32:14 -05:00
6e7459322d
Having an alias function that only wraps another one is silly, and keeping the more obvious name should flush out more uses of deprecated strings. No behavior change.
240 lines
6 KiB
C++
240 lines
6 KiB
C++
/*
|
|
* Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
#include <AK/DeprecatedString.h>
|
|
#include <AK/StringBuilder.h>
|
|
#include <LibSQL/Serializer.h>
|
|
#include <LibSQL/Tuple.h>
|
|
#include <LibSQL/TupleDescriptor.h>
|
|
#include <LibSQL/Value.h>
|
|
|
|
namespace SQL {
|
|
|
|
Tuple::Tuple()
|
|
: m_descriptor(adopt_ref(*new TupleDescriptor))
|
|
, m_data()
|
|
{
|
|
}
|
|
|
|
Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, u32 pointer)
|
|
: m_descriptor(descriptor)
|
|
, m_data()
|
|
, m_pointer(pointer)
|
|
{
|
|
for (auto& element : *descriptor) {
|
|
m_data.empend(element.type);
|
|
}
|
|
}
|
|
|
|
Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, Serializer& serializer)
|
|
: Tuple(descriptor)
|
|
{
|
|
deserialize(serializer);
|
|
}
|
|
|
|
void Tuple::deserialize(Serializer& serializer)
|
|
{
|
|
dbgln_if(SQL_DEBUG, "deserialize tuple at offset {}", serializer.offset());
|
|
serializer.deserialize_to<u32>(m_pointer);
|
|
dbgln_if(SQL_DEBUG, "pointer: {}", m_pointer);
|
|
auto sz = serializer.deserialize<u32>();
|
|
m_data.clear();
|
|
m_descriptor->clear();
|
|
for (auto ix = 0u; ix < sz; ++ix) {
|
|
m_descriptor->append(serializer.deserialize<TupleElementDescriptor>());
|
|
m_data.append(serializer.deserialize<Value>());
|
|
}
|
|
}
|
|
|
|
void Tuple::serialize(Serializer& serializer) const
|
|
{
|
|
VERIFY(m_descriptor->size() == m_data.size());
|
|
dbgln_if(SQL_DEBUG, "Serializing tuple pointer {}", pointer());
|
|
serializer.serialize<u32>(pointer());
|
|
serializer.serialize<u32>((u32)m_descriptor->size());
|
|
for (auto ix = 0u; ix < m_descriptor->size(); ix++) {
|
|
auto& key_part = m_data[ix];
|
|
serializer.serialize<TupleElementDescriptor>((*m_descriptor)[ix]);
|
|
serializer.serialize<Value>(key_part);
|
|
}
|
|
}
|
|
|
|
Tuple::Tuple(Tuple const& other)
|
|
: m_descriptor(other.m_descriptor)
|
|
, m_data()
|
|
{
|
|
copy_from(other);
|
|
}
|
|
|
|
Tuple& Tuple::operator=(Tuple const& other)
|
|
{
|
|
if (this != &other) {
|
|
copy_from(other);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
Optional<size_t> Tuple::index_of(StringView name) const
|
|
{
|
|
for (auto ix = 0u; ix < m_descriptor->size(); ix++) {
|
|
auto& part = (*m_descriptor)[ix];
|
|
if (part.name == name) {
|
|
return ix;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
Value const& Tuple::operator[](DeprecatedString const& name) const
|
|
{
|
|
auto index = index_of(name);
|
|
VERIFY(index.has_value());
|
|
return (*this)[index.value()];
|
|
}
|
|
|
|
Value& Tuple::operator[](DeprecatedString const& name)
|
|
{
|
|
auto index = index_of(name);
|
|
VERIFY(index.has_value());
|
|
return (*this)[index.value()];
|
|
}
|
|
|
|
void Tuple::append(Value const& value)
|
|
{
|
|
VERIFY(descriptor()->size() >= size());
|
|
if (descriptor()->size() == size()) {
|
|
descriptor()->append(value.descriptor());
|
|
}
|
|
m_data.append(value);
|
|
}
|
|
|
|
Tuple& Tuple::operator+=(Value const& value)
|
|
{
|
|
append(value);
|
|
return *this;
|
|
}
|
|
|
|
void Tuple::extend(Tuple const& other)
|
|
{
|
|
VERIFY((descriptor()->size() == size()) || (descriptor()->size() >= size() + other.size()));
|
|
if (descriptor()->size() == size()) {
|
|
descriptor()->extend(other.descriptor());
|
|
}
|
|
m_data.extend(other.m_data);
|
|
}
|
|
|
|
bool Tuple::is_compatible(Tuple const& other) const
|
|
{
|
|
if ((m_descriptor->size() == 0) && (other.m_descriptor->size() == 0)) {
|
|
return true;
|
|
}
|
|
if (m_descriptor->size() != other.m_descriptor->size()) {
|
|
return false;
|
|
}
|
|
for (auto ix = 0u; ix < m_descriptor->size(); ix++) {
|
|
auto& my_part = (*m_descriptor)[ix];
|
|
auto& other_part = (*other.m_descriptor)[ix];
|
|
if (my_part.type != other_part.type) {
|
|
return false;
|
|
}
|
|
if (my_part.order != other_part.order) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
size_t Tuple::length() const
|
|
{
|
|
size_t len = 2 * sizeof(u32);
|
|
for (auto ix = 0u; ix < m_descriptor->size(); ix++) {
|
|
auto& descriptor = (*m_descriptor)[ix];
|
|
auto& value = m_data[ix];
|
|
len += descriptor.length();
|
|
len += value.length();
|
|
}
|
|
return len;
|
|
}
|
|
|
|
DeprecatedString Tuple::to_deprecated_string() const
|
|
{
|
|
StringBuilder builder;
|
|
for (auto& part : m_data) {
|
|
if (!builder.is_empty()) {
|
|
builder.append('|');
|
|
}
|
|
builder.append(part.to_deprecated_string());
|
|
}
|
|
if (pointer() != 0) {
|
|
builder.appendff(":{}", pointer());
|
|
}
|
|
return builder.to_deprecated_string();
|
|
}
|
|
|
|
void Tuple::copy_from(Tuple const& other)
|
|
{
|
|
if (*m_descriptor != *other.m_descriptor) {
|
|
m_descriptor->clear();
|
|
for (TupleElementDescriptor const& part : *other.m_descriptor) {
|
|
m_descriptor->append(part);
|
|
}
|
|
}
|
|
m_data.clear();
|
|
for (auto& part : other.m_data) {
|
|
m_data.append(part);
|
|
}
|
|
m_pointer = other.pointer();
|
|
}
|
|
|
|
int Tuple::compare(Tuple const& other) const
|
|
{
|
|
auto num_values = min(m_data.size(), other.m_data.size());
|
|
VERIFY(num_values > 0);
|
|
for (auto ix = 0u; ix < num_values; ix++) {
|
|
auto ret = m_data[ix].compare(other.m_data[ix]);
|
|
if (ret != 0) {
|
|
if ((ix < m_descriptor->size()) && (*m_descriptor)[ix].order == Order::Descending)
|
|
ret = -ret;
|
|
return ret;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Tuple::match(Tuple const& other) const
|
|
{
|
|
auto other_index = 0u;
|
|
for (auto const& part : *other.descriptor()) {
|
|
auto const& other_value = other[other_index];
|
|
if (other_value.is_null())
|
|
return 0;
|
|
auto my_index = index_of(part.name);
|
|
if (!my_index.has_value())
|
|
return -1;
|
|
auto ret = m_data[my_index.value()].compare(other_value);
|
|
if (ret != 0)
|
|
return ((*m_descriptor)[my_index.value()].order == Order::Descending) ? -ret : ret;
|
|
other_index++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
u32 Tuple::hash() const
|
|
{
|
|
u32 ret = 0u;
|
|
for (auto& value : m_data) {
|
|
// This is an extension of the pair_int_hash function from AK/HashFunctions.h:
|
|
if (!ret)
|
|
ret = value.hash();
|
|
else
|
|
ret = int_hash((ret * 209) ^ (value.hash() * 413));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
}
|