/src/serenity/Userland/Libraries/LibSQL/Meta.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibSQL/Key.h> |
8 | | #include <LibSQL/Meta.h> |
9 | | #include <LibSQL/Type.h> |
10 | | |
11 | | namespace SQL { |
12 | | |
13 | | u32 Relation::hash() const |
14 | 0 | { |
15 | 0 | return key().hash(); |
16 | 0 | } |
17 | | |
18 | | ErrorOr<NonnullRefPtr<SchemaDef>> SchemaDef::create(ByteString name) |
19 | 0 | { |
20 | 0 | return adopt_nonnull_ref_or_enomem(new (nothrow) SchemaDef(move(name))); |
21 | 0 | } |
22 | | |
23 | | ErrorOr<NonnullRefPtr<SchemaDef>> SchemaDef::create(Key const& key) |
24 | 0 | { |
25 | 0 | return create(key["schema_name"].to_byte_string()); |
26 | 0 | } |
27 | | |
28 | | SchemaDef::SchemaDef(ByteString name) |
29 | 0 | : Relation(move(name)) |
30 | 0 | { |
31 | 0 | } |
32 | | |
33 | | Key SchemaDef::key() const |
34 | 0 | { |
35 | 0 | auto key = Key(index_def()->to_tuple_descriptor()); |
36 | 0 | key["schema_name"] = name(); |
37 | 0 | key.set_block_index(block_index()); |
38 | 0 | return key; |
39 | 0 | } |
40 | | |
41 | | Key SchemaDef::make_key() |
42 | 0 | { |
43 | 0 | return Key(index_def()); |
44 | 0 | } |
45 | | |
46 | | NonnullRefPtr<IndexDef> SchemaDef::index_def() |
47 | 0 | { |
48 | 0 | NonnullRefPtr<IndexDef> s_index_def = IndexDef::create("$schema", true, 0).release_value_but_fixme_should_propagate_errors(); |
49 | 0 | if (!s_index_def->size()) { |
50 | 0 | s_index_def->append_column("schema_name", SQLType::Text, Order::Ascending); |
51 | 0 | } |
52 | 0 | return s_index_def; |
53 | 0 | } |
54 | | |
55 | | ErrorOr<NonnullRefPtr<ColumnDef>> ColumnDef::create(Relation* parent, size_t column_number, ByteString name, SQLType sql_type) |
56 | 0 | { |
57 | 0 | return adopt_nonnull_ref_or_enomem(new (nothrow) ColumnDef(parent, column_number, move(name), sql_type)); |
58 | 0 | } |
59 | | |
60 | | ColumnDef::ColumnDef(Relation* parent, size_t column_number, ByteString name, SQLType sql_type) |
61 | 0 | : Relation(move(name), parent) |
62 | 0 | , m_index(column_number) |
63 | 0 | , m_type(sql_type) |
64 | 0 | , m_default(Value(sql_type)) |
65 | 0 | { |
66 | 0 | } |
67 | | |
68 | | Key ColumnDef::key() const |
69 | 0 | { |
70 | 0 | auto key = Key(index_def()); |
71 | 0 | key["table_hash"] = parent()->hash(); |
72 | 0 | key["column_number"] = column_number(); |
73 | 0 | key["column_name"] = name(); |
74 | 0 | key["column_type"] = to_underlying(type()); |
75 | 0 | return key; |
76 | 0 | } |
77 | | |
78 | | void ColumnDef::set_default_value(Value const& default_value) |
79 | 0 | { |
80 | 0 | VERIFY(default_value.type() == type()); |
81 | 0 | m_default = default_value; |
82 | 0 | } |
83 | | |
84 | | Key ColumnDef::make_key(TableDef const& table_def) |
85 | 0 | { |
86 | 0 | Key key(index_def()); |
87 | 0 | key["table_hash"] = table_def.key().hash(); |
88 | 0 | return key; |
89 | 0 | } |
90 | | |
91 | | NonnullRefPtr<IndexDef> ColumnDef::index_def() |
92 | 0 | { |
93 | 0 | NonnullRefPtr<IndexDef> s_index_def = IndexDef::create("$column", true, 0).release_value_but_fixme_should_propagate_errors(); |
94 | 0 | if (!s_index_def->size()) { |
95 | 0 | s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending); |
96 | 0 | s_index_def->append_column("column_number", SQLType::Integer, Order::Ascending); |
97 | 0 | s_index_def->append_column("column_name", SQLType::Text, Order::Ascending); |
98 | 0 | s_index_def->append_column("column_type", SQLType::Integer, Order::Ascending); |
99 | 0 | } |
100 | 0 | return s_index_def; |
101 | 0 | } |
102 | | |
103 | | ErrorOr<NonnullRefPtr<KeyPartDef>> KeyPartDef::create(IndexDef* index, ByteString name, SQLType sql_type, Order sort_order) |
104 | 0 | { |
105 | 0 | return adopt_nonnull_ref_or_enomem(new (nothrow) KeyPartDef(index, move(name), sql_type, sort_order)); |
106 | 0 | } |
107 | | |
108 | | KeyPartDef::KeyPartDef(IndexDef* index, ByteString name, SQLType sql_type, Order sort_order) |
109 | 0 | : ColumnDef(index, index->size(), move(name), sql_type) |
110 | 0 | , m_sort_order(sort_order) |
111 | 0 | { |
112 | 0 | } |
113 | | |
114 | | ErrorOr<NonnullRefPtr<IndexDef>> IndexDef::create(TableDef* table, ByteString name, bool unique, u32 pointer) |
115 | 0 | { |
116 | 0 | return adopt_nonnull_ref_or_enomem(new (nothrow) IndexDef(table, move(name), unique, pointer)); |
117 | 0 | } |
118 | | |
119 | | ErrorOr<NonnullRefPtr<IndexDef>> IndexDef::create(ByteString name, bool unique, u32 pointer) |
120 | 0 | { |
121 | 0 | return create(nullptr, move(name), unique, pointer); |
122 | 0 | } |
123 | | |
124 | | IndexDef::IndexDef(TableDef* table, ByteString name, bool unique, u32 pointer) |
125 | 0 | : Relation(move(name), pointer, table) |
126 | 0 | , m_key_definition() |
127 | 0 | , m_unique(unique) |
128 | 0 | { |
129 | 0 | } |
130 | | |
131 | | void IndexDef::append_column(ByteString name, SQLType sql_type, Order sort_order) |
132 | 0 | { |
133 | 0 | auto part = KeyPartDef::create(this, move(name), sql_type, sort_order).release_value_but_fixme_should_propagate_errors(); |
134 | 0 | m_key_definition.append(part); |
135 | 0 | } |
136 | | |
137 | | NonnullRefPtr<TupleDescriptor> IndexDef::to_tuple_descriptor() const |
138 | 0 | { |
139 | 0 | NonnullRefPtr<TupleDescriptor> ret = adopt_ref(*new TupleDescriptor); |
140 | 0 | for (auto& part : m_key_definition) { |
141 | 0 | ret->append({ "", "", part->name(), part->type(), part->sort_order() }); |
142 | 0 | } |
143 | 0 | return ret; |
144 | 0 | } |
145 | | |
146 | | Key IndexDef::key() const |
147 | 0 | { |
148 | 0 | auto key = Key(index_def()->to_tuple_descriptor()); |
149 | 0 | key["table_hash"] = parent()->key().hash(); |
150 | 0 | key["index_name"] = name(); |
151 | 0 | key["unique"] = unique() ? 1 : 0; |
152 | 0 | return key; |
153 | 0 | } |
154 | | |
155 | | Key IndexDef::make_key(TableDef const& table_def) |
156 | 0 | { |
157 | 0 | Key key(index_def()); |
158 | 0 | key["table_hash"] = table_def.key().hash(); |
159 | 0 | return key; |
160 | 0 | } |
161 | | |
162 | | NonnullRefPtr<IndexDef> IndexDef::index_def() |
163 | 0 | { |
164 | 0 | NonnullRefPtr<IndexDef> s_index_def = IndexDef::create("$index", true, 0).release_value_but_fixme_should_propagate_errors(); |
165 | 0 | if (!s_index_def->size()) { |
166 | 0 | s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending); |
167 | 0 | s_index_def->append_column("index_name", SQLType::Text, Order::Ascending); |
168 | 0 | s_index_def->append_column("unique", SQLType::Integer, Order::Ascending); |
169 | 0 | } |
170 | 0 | return s_index_def; |
171 | 0 | } |
172 | | |
173 | | ErrorOr<NonnullRefPtr<TableDef>> TableDef::create(SchemaDef* schema, ByteString name) |
174 | 0 | { |
175 | 0 | return adopt_nonnull_ref_or_enomem(new (nothrow) TableDef(schema, move(name))); |
176 | 0 | } |
177 | | |
178 | | TableDef::TableDef(SchemaDef* schema, ByteString name) |
179 | 0 | : Relation(move(name), schema) |
180 | 0 | , m_columns() |
181 | 0 | , m_indexes() |
182 | 0 | { |
183 | 0 | } |
184 | | |
185 | | NonnullRefPtr<TupleDescriptor> TableDef::to_tuple_descriptor() const |
186 | 0 | { |
187 | 0 | NonnullRefPtr<TupleDescriptor> ret = adopt_ref(*new TupleDescriptor); |
188 | 0 | for (auto& part : m_columns) { |
189 | 0 | ret->append({ parent()->name(), name(), part->name(), part->type(), Order::Ascending }); |
190 | 0 | } |
191 | 0 | return ret; |
192 | 0 | } |
193 | | |
194 | | Key TableDef::key() const |
195 | 0 | { |
196 | 0 | auto key = Key(index_def()->to_tuple_descriptor()); |
197 | 0 | key["schema_hash"] = parent()->key().hash(); |
198 | 0 | key["table_name"] = name(); |
199 | 0 | key.set_block_index(block_index()); |
200 | 0 | return key; |
201 | 0 | } |
202 | | |
203 | | void TableDef::append_column(ByteString name, SQLType sql_type) |
204 | 0 | { |
205 | 0 | auto column = ColumnDef::create(this, num_columns(), move(name), sql_type).release_value_but_fixme_should_propagate_errors(); |
206 | 0 | m_columns.append(column); |
207 | 0 | } |
208 | | |
209 | | void TableDef::append_column(Key const& column) |
210 | 0 | { |
211 | 0 | auto column_type = column["column_type"].to_int<UnderlyingType<SQLType>>(); |
212 | 0 | VERIFY(column_type.has_value()); |
213 | | |
214 | 0 | append_column(column["column_name"].to_byte_string(), static_cast<SQLType>(*column_type)); |
215 | 0 | } |
216 | | |
217 | | Key TableDef::make_key(SchemaDef const& schema_def) |
218 | 0 | { |
219 | 0 | return TableDef::make_key(schema_def.key()); |
220 | 0 | } |
221 | | |
222 | | Key TableDef::make_key(Key const& schema_key) |
223 | 0 | { |
224 | 0 | Key key(index_def()); |
225 | 0 | key["schema_hash"] = schema_key.hash(); |
226 | 0 | return key; |
227 | 0 | } |
228 | | |
229 | | NonnullRefPtr<IndexDef> TableDef::index_def() |
230 | 0 | { |
231 | 0 | NonnullRefPtr<IndexDef> s_index_def = IndexDef::create("$table", true, 0).release_value_but_fixme_should_propagate_errors(); |
232 | 0 | if (!s_index_def->size()) { |
233 | 0 | s_index_def->append_column("schema_hash", SQLType::Integer, Order::Ascending); |
234 | 0 | s_index_def->append_column("table_name", SQLType::Text, Order::Ascending); |
235 | 0 | } |
236 | 0 | return s_index_def; |
237 | 0 | } |
238 | | |
239 | | } |