Serenity Operating System
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
11namespace SQL {
12
13u32 Relation::hash() const
14{
15 return key().hash();
16}
17
18SchemaDef::SchemaDef(DeprecatedString name)
19 : Relation(move(name))
20{
21}
22
23SchemaDef::SchemaDef(Key const& key)
24 : Relation(key["schema_name"].to_deprecated_string())
25{
26}
27
28Key SchemaDef::key() const
29{
30 auto key = Key(index_def()->to_tuple_descriptor());
31 key["schema_name"] = name();
32 key.set_pointer(pointer());
33 return key;
34}
35
36Key SchemaDef::make_key()
37{
38 return Key(index_def());
39}
40
41NonnullRefPtr<IndexDef> SchemaDef::index_def()
42{
43 NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$schema", true, 0);
44 if (!s_index_def->size()) {
45 s_index_def->append_column("schema_name", SQLType::Text, Order::Ascending);
46 }
47 return s_index_def;
48}
49
50ColumnDef::ColumnDef(Relation* parent, size_t column_number, DeprecatedString name, SQLType sql_type)
51 : Relation(move(name), parent)
52 , m_index(column_number)
53 , m_type(sql_type)
54 , m_default(Value(sql_type))
55{
56}
57
58Key ColumnDef::key() const
59{
60 auto key = Key(index_def());
61 key["table_hash"] = parent_relation()->hash();
62 key["column_number"] = column_number();
63 key["column_name"] = name();
64 key["column_type"] = to_underlying(type());
65 return key;
66}
67
68void ColumnDef::set_default_value(Value const& default_value)
69{
70 VERIFY(default_value.type() == type());
71 m_default = default_value;
72}
73
74Key ColumnDef::make_key(TableDef const& table_def)
75{
76 Key key(index_def());
77 key["table_hash"] = table_def.key().hash();
78 return key;
79}
80
81NonnullRefPtr<IndexDef> ColumnDef::index_def()
82{
83 NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$column", true, 0);
84 if (!s_index_def->size()) {
85 s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending);
86 s_index_def->append_column("column_number", SQLType::Integer, Order::Ascending);
87 s_index_def->append_column("column_name", SQLType::Text, Order::Ascending);
88 s_index_def->append_column("column_type", SQLType::Integer, Order::Ascending);
89 }
90 return s_index_def;
91}
92
93KeyPartDef::KeyPartDef(IndexDef* index, DeprecatedString name, SQLType sql_type, Order sort_order)
94 : ColumnDef(index, index->size(), move(name), sql_type)
95 , m_sort_order(sort_order)
96{
97}
98
99IndexDef::IndexDef(TableDef* table, DeprecatedString name, bool unique, u32 pointer)
100 : Relation(move(name), pointer, table)
101 , m_key_definition()
102 , m_unique(unique)
103{
104}
105
106IndexDef::IndexDef(DeprecatedString name, bool unique, u32 pointer)
107 : IndexDef(nullptr, move(name), unique, pointer)
108{
109}
110
111void IndexDef::append_column(DeprecatedString name, SQLType sql_type, Order sort_order)
112{
113 auto part = KeyPartDef::construct(this, move(name), sql_type, sort_order);
114 m_key_definition.append(part);
115}
116
117NonnullRefPtr<TupleDescriptor> IndexDef::to_tuple_descriptor() const
118{
119 NonnullRefPtr<TupleDescriptor> ret = adopt_ref(*new TupleDescriptor);
120 for (auto& part : m_key_definition) {
121 ret->append({ "", "", part->name(), part->type(), part->sort_order() });
122 }
123 return ret;
124}
125
126Key IndexDef::key() const
127{
128 auto key = Key(index_def()->to_tuple_descriptor());
129 key["table_hash"] = parent_relation()->key().hash();
130 key["index_name"] = name();
131 key["unique"] = unique() ? 1 : 0;
132 return key;
133}
134
135Key IndexDef::make_key(TableDef const& table_def)
136{
137 Key key(index_def());
138 key["table_hash"] = table_def.key().hash();
139 return key;
140}
141
142NonnullRefPtr<IndexDef> IndexDef::index_def()
143{
144 NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$index", true, 0);
145 if (!s_index_def->size()) {
146 s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending);
147 s_index_def->append_column("index_name", SQLType::Text, Order::Ascending);
148 s_index_def->append_column("unique", SQLType::Integer, Order::Ascending);
149 }
150 return s_index_def;
151}
152
153TableDef::TableDef(SchemaDef* schema, DeprecatedString name)
154 : Relation(move(name), schema)
155 , m_columns()
156 , m_indexes()
157{
158}
159
160NonnullRefPtr<TupleDescriptor> TableDef::to_tuple_descriptor() const
161{
162 NonnullRefPtr<TupleDescriptor> ret = adopt_ref(*new TupleDescriptor);
163 for (auto& part : m_columns) {
164 ret->append({ parent()->name(), name(), part->name(), part->type(), Order::Ascending });
165 }
166 return ret;
167}
168
169Key TableDef::key() const
170{
171 auto key = Key(index_def()->to_tuple_descriptor());
172 key["schema_hash"] = parent_relation()->key().hash();
173 key["table_name"] = name();
174 key.set_pointer(pointer());
175 return key;
176}
177
178void TableDef::append_column(DeprecatedString name, SQLType sql_type)
179{
180 auto column = ColumnDef::construct(this, num_columns(), move(name), sql_type);
181 m_columns.append(column);
182}
183
184void TableDef::append_column(Key const& column)
185{
186 auto column_type = column["column_type"].to_int<UnderlyingType<SQLType>>();
187 VERIFY(column_type.has_value());
188
189 append_column(column["column_name"].to_deprecated_string(), static_cast<SQLType>(*column_type));
190}
191
192Key TableDef::make_key(SchemaDef const& schema_def)
193{
194 return TableDef::make_key(schema_def.key());
195}
196
197Key TableDef::make_key(Key const& schema_key)
198{
199 Key key(index_def());
200 key["schema_hash"] = schema_key.hash();
201 return key;
202}
203
204NonnullRefPtr<IndexDef> TableDef::index_def()
205{
206 NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$table", true, 0);
207 if (!s_index_def->size()) {
208 s_index_def->append_column("schema_hash", SQLType::Integer, Order::Ascending);
209 s_index_def->append_column("table_name", SQLType::Text, Order::Ascending);
210 }
211 return s_index_def;
212}
213
214}