Serenity Operating System
at master 240 lines 6.2 kB view raw
1/* 2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <cstring> 8 9#include <AK/DeprecatedString.h> 10#include <AK/StringBuilder.h> 11#include <LibSQL/Serializer.h> 12#include <LibSQL/Tuple.h> 13#include <LibSQL/TupleDescriptor.h> 14#include <LibSQL/Value.h> 15 16namespace SQL { 17 18Tuple::Tuple() 19 : m_descriptor(adopt_ref(*new TupleDescriptor)) 20 , m_data() 21{ 22} 23 24Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, u32 pointer) 25 : m_descriptor(descriptor) 26 , m_data() 27 , m_pointer(pointer) 28{ 29 for (auto& element : *descriptor) { 30 m_data.empend(element.type); 31 } 32} 33 34Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, Serializer& serializer) 35 : Tuple(descriptor) 36{ 37 deserialize(serializer); 38} 39 40void Tuple::deserialize(Serializer& serializer) 41{ 42 dbgln_if(SQL_DEBUG, "deserialize tuple at offset {}", serializer.offset()); 43 serializer.deserialize_to<u32>(m_pointer); 44 dbgln_if(SQL_DEBUG, "pointer: {}", m_pointer); 45 auto sz = serializer.deserialize<u32>(); 46 m_data.clear(); 47 m_descriptor->clear(); 48 for (auto ix = 0u; ix < sz; ++ix) { 49 m_descriptor->append(serializer.deserialize<TupleElementDescriptor>()); 50 m_data.append(serializer.deserialize<Value>()); 51 } 52} 53 54void Tuple::serialize(Serializer& serializer) const 55{ 56 VERIFY(m_descriptor->size() == m_data.size()); 57 dbgln_if(SQL_DEBUG, "Serializing tuple pointer {}", pointer()); 58 serializer.serialize<u32>(pointer()); 59 serializer.serialize<u32>((u32)m_descriptor->size()); 60 for (auto ix = 0u; ix < m_descriptor->size(); ix++) { 61 auto& key_part = m_data[ix]; 62 serializer.serialize<TupleElementDescriptor>((*m_descriptor)[ix]); 63 serializer.serialize<Value>(key_part); 64 } 65} 66 67Tuple::Tuple(Tuple const& other) 68 : m_descriptor(other.m_descriptor) 69 , m_data() 70{ 71 copy_from(other); 72} 73 74Tuple& Tuple::operator=(Tuple const& other) 75{ 76 if (this != &other) { 77 copy_from(other); 78 } 79 return *this; 80} 81 82Optional<size_t> Tuple::index_of(StringView name) const 83{ 84 for (auto ix = 0u; ix < m_descriptor->size(); ix++) { 85 auto& part = (*m_descriptor)[ix]; 86 if (part.name == name) { 87 return ix; 88 } 89 } 90 return {}; 91} 92 93Value const& Tuple::operator[](DeprecatedString const& name) const 94{ 95 auto index = index_of(name); 96 VERIFY(index.has_value()); 97 return (*this)[index.value()]; 98} 99 100Value& Tuple::operator[](DeprecatedString const& name) 101{ 102 auto index = index_of(name); 103 VERIFY(index.has_value()); 104 return (*this)[index.value()]; 105} 106 107void Tuple::append(Value const& value) 108{ 109 VERIFY(descriptor()->size() >= size()); 110 if (descriptor()->size() == size()) { 111 descriptor()->append(value.descriptor()); 112 } 113 m_data.append(value); 114} 115 116Tuple& Tuple::operator+=(Value const& value) 117{ 118 append(value); 119 return *this; 120} 121 122void Tuple::extend(Tuple const& other) 123{ 124 VERIFY((descriptor()->size() == size()) || (descriptor()->size() >= size() + other.size())); 125 if (descriptor()->size() == size()) { 126 descriptor()->extend(other.descriptor()); 127 } 128 m_data.extend(other.m_data); 129} 130 131bool Tuple::is_compatible(Tuple const& other) const 132{ 133 if ((m_descriptor->size() == 0) && (other.m_descriptor->size() == 0)) { 134 return true; 135 } 136 if (m_descriptor->size() != other.m_descriptor->size()) { 137 return false; 138 } 139 for (auto ix = 0u; ix < m_descriptor->size(); ix++) { 140 auto& my_part = (*m_descriptor)[ix]; 141 auto& other_part = (*other.m_descriptor)[ix]; 142 if (my_part.type != other_part.type) { 143 return false; 144 } 145 if (my_part.order != other_part.order) { 146 return false; 147 } 148 } 149 return true; 150} 151 152size_t Tuple::length() const 153{ 154 size_t len = 2 * sizeof(u32); 155 for (auto ix = 0u; ix < m_descriptor->size(); ix++) { 156 auto& descriptor = (*m_descriptor)[ix]; 157 auto& value = m_data[ix]; 158 len += descriptor.length(); 159 len += value.length(); 160 } 161 return len; 162} 163 164DeprecatedString Tuple::to_deprecated_string() const 165{ 166 StringBuilder builder; 167 for (auto& part : m_data) { 168 if (!builder.is_empty()) { 169 builder.append('|'); 170 } 171 builder.append(part.to_deprecated_string()); 172 } 173 if (pointer() != 0) { 174 builder.appendff(":{}", pointer()); 175 } 176 return builder.to_deprecated_string(); 177} 178 179void Tuple::copy_from(Tuple const& other) 180{ 181 if (*m_descriptor != *other.m_descriptor) { 182 m_descriptor->clear(); 183 for (TupleElementDescriptor const& part : *other.m_descriptor) { 184 m_descriptor->append(part); 185 } 186 } 187 m_data.clear(); 188 for (auto& part : other.m_data) { 189 m_data.append(part); 190 } 191 m_pointer = other.pointer(); 192} 193 194int Tuple::compare(Tuple const& other) const 195{ 196 auto num_values = min(m_data.size(), other.m_data.size()); 197 VERIFY(num_values > 0); 198 for (auto ix = 0u; ix < num_values; ix++) { 199 auto ret = m_data[ix].compare(other.m_data[ix]); 200 if (ret != 0) { 201 if ((ix < m_descriptor->size()) && (*m_descriptor)[ix].order == Order::Descending) 202 ret = -ret; 203 return ret; 204 } 205 } 206 return 0; 207} 208 209int Tuple::match(Tuple const& other) const 210{ 211 auto other_index = 0u; 212 for (auto const& part : *other.descriptor()) { 213 auto const& other_value = other[other_index]; 214 if (other_value.is_null()) 215 return 0; 216 auto my_index = index_of(part.name); 217 if (!my_index.has_value()) 218 return -1; 219 auto ret = m_data[my_index.value()].compare(other_value); 220 if (ret != 0) 221 return ((*m_descriptor)[my_index.value()].order == Order::Descending) ? -ret : ret; 222 other_index++; 223 } 224 return 0; 225} 226 227u32 Tuple::hash() const 228{ 229 u32 ret = 0u; 230 for (auto& value : m_data) { 231 // This is an extension of the pair_int_hash function from AK/HashFunctions.h: 232 if (!ret) 233 ret = value.hash(); 234 else 235 ret = int_hash((ret * 209) ^ (value.hash() * 413)); 236 } 237 return ret; 238} 239 240}