summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSQL/Meta.h
blob: ecebf8f2b907c29fcc9c33351bf0701f969770ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/DeprecatedString.h>
#include <AK/NonnullRefPtr.h>
#include <AK/Result.h>
#include <AK/Vector.h>
#include <LibCore/Object.h>
#include <LibSQL/Forward.h>
#include <LibSQL/Heap.h>
#include <LibSQL/Type.h>
#include <LibSQL/Value.h>

namespace SQL {

/**
 * This file declares objects describing tables, indexes, and columns.
 * It remains to be seen if this will survive in it's current form.
 */

class Relation : public Core::Object {
    C_OBJECT_ABSTRACT(Relation);

public:
    u32 hash() const;
    Block::Index block_index() const { return m_block_index; }
    void set_block_index(Block::Index block_index) { m_block_index = block_index; }
    ~Relation() override = default;
    virtual Key key() const = 0;
    Relation const* parent_relation() const { return dynamic_cast<Relation const*>(parent()); }

protected:
    Relation(DeprecatedString name, Block::Index block_index, Relation* parent = nullptr)
        : Core::Object(parent)
        , m_block_index(block_index)
    {
        set_name(move(name));
    }

    explicit Relation(DeprecatedString name, Relation* parent = nullptr)
        : Core::Object(parent)
        , m_block_index(0)
    {
        set_name(move(name));
    }

private:
    Block::Index m_block_index { 0 };
};

class SchemaDef : public Relation {
    C_OBJECT(SchemaDef);

public:
    Key key() const override;
    static NonnullRefPtr<IndexDef> index_def();
    static Key make_key();

private:
    explicit SchemaDef(DeprecatedString);
    explicit SchemaDef(Key const&);
};

class ColumnDef : public Relation {
    C_OBJECT(ColumnDef);

public:
    Key key() const override;
    SQLType type() const { return m_type; }
    size_t column_number() const { return m_index; }
    void set_not_null(bool can_not_be_null) { m_not_null = can_not_be_null; }
    bool not_null() const { return m_not_null; }
    void set_default_value(Value const& default_value);
    Value const& default_value() const { return m_default; }

    static NonnullRefPtr<IndexDef> index_def();
    static Key make_key(TableDef const&);

protected:
    ColumnDef(Relation*, size_t, DeprecatedString, SQLType);

private:
    size_t m_index;
    SQLType m_type { SQLType::Text };
    bool m_not_null { false };
    Value m_default;
};

class KeyPartDef : public ColumnDef {
    C_OBJECT(KeyPartDef);

public:
    Order sort_order() const { return m_sort_order; }

private:
    KeyPartDef(IndexDef*, DeprecatedString, SQLType, Order = Order::Ascending);

    Order m_sort_order { Order::Ascending };
};

class IndexDef : public Relation {
    C_OBJECT(IndexDef);

public:
    ~IndexDef() override = default;

    Vector<NonnullRefPtr<KeyPartDef>> const& key_definition() const { return m_key_definition; }
    bool unique() const { return m_unique; }
    [[nodiscard]] size_t size() const { return m_key_definition.size(); }
    void append_column(DeprecatedString, SQLType, Order = Order::Ascending);
    Key key() const override;
    [[nodiscard]] NonnullRefPtr<TupleDescriptor> to_tuple_descriptor() const;
    static NonnullRefPtr<IndexDef> index_def();
    static Key make_key(TableDef const& table_def);

private:
    IndexDef(TableDef*, DeprecatedString, bool unique = true, u32 pointer = 0);
    explicit IndexDef(DeprecatedString, bool unique = true, u32 pointer = 0);

    Vector<NonnullRefPtr<KeyPartDef>> m_key_definition;
    bool m_unique { false };

    friend TableDef;
};

class TableDef : public Relation {
    C_OBJECT(TableDef);

public:
    Key key() const override;
    void append_column(DeprecatedString, SQLType);
    void append_column(Key const&);
    size_t num_columns() { return m_columns.size(); }
    size_t num_indexes() { return m_indexes.size(); }
    Vector<NonnullRefPtr<ColumnDef>> const& columns() const { return m_columns; }
    Vector<NonnullRefPtr<IndexDef>> const& indexes() const { return m_indexes; }
    [[nodiscard]] NonnullRefPtr<TupleDescriptor> to_tuple_descriptor() const;

    static NonnullRefPtr<IndexDef> index_def();
    static Key make_key(SchemaDef const& schema_def);
    static Key make_key(Key const& schema_key);

private:
    explicit TableDef(SchemaDef*, DeprecatedString);

    Vector<NonnullRefPtr<ColumnDef>> m_columns;
    Vector<NonnullRefPtr<IndexDef>> m_indexes;
};

}