aboutsummaryrefslogtreecommitdiff
path: root/docs/notes/database.lh
blob: 51d34824dab45a0d2c75182df8d708bbdda95a85 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186


typedef ColumnType = enum int(
    Integer, IntegerNull,
    Float, FloatNull,
    Boolean, BooleanNull,
    String, StringNull,
);
const type[ColumnType] real_types = (
    int, int?,
    bool, bool?,
    string*, string*?,
);

typedef Table = private;

typedef DatabaseColumn(typeof(Table*) Ta) = private;
typedef TypedColumn(ColumnType Ty) = private;
typedef Column(typeof(Table*) Ta, ColumnType Ty) = (
    union(DatabaseColumn(Ta),TypedColumn(Ty)) base,
    private
);

typedef VariantValue = (
    const ColumnType type,
    real_types[type] value,
);

typedef ColumnValue(ColumnType Ty) = (
    const ColumnType type constraint(value = Ty),
    real_types[Ty] value,
);

typedef ColumnValuePair(typeof(Table*) Ta, ColumnType Ty) = (
    Column(typeof(Table*) Ta, ColumnType Ty)) column,
    ColumnValue(Ty) value,
);

-- Expressions
-- TODO typed value expressions?
typedef ExpressionType = enum int(
    -- Boolean
    Not, And, Or, Xor,
    -- Comparison
    Eq, NEq, Less, LessOrEq, Greater, GreaterOrEq, IsNull, IsNotNull,
    -- Values
    ConstantValue, ColumnValue,
    -- Math
    Add, Sub, Mul, Div, Mod,
    -- Aggregates
    -- TODO
);

typedef UnaryBooleanExpression = (
    ExpressionType type constraint(value in (Not)),
    BooleanExpression op1,
);

typedef BinaryBooleanExpression = (
    ExpressionType type constraint(value in (And, Or, Xor)),
    BooleanExpression op1,
    BooleanExpression op2,
);

typedef EqualityExpression = (
    ExpressionType type constraint(value in (Eq, NEq, Less, LessOrEqual,
                                             Greater, GreaterOrEqual)),
    ValueExpression op1,
    ValueExpression op2,
);

typedef NullComparisonExpression = (
    ExpressionType type constraint(value in (IsNull, IsNotNull)),
    NullableExpression op1,
);

typedef ValueExpression = (
    ExpressionType type constraint(value in (ConstantValue, ColumnValue, Add, Sub, Div, Mul, Mod)),
    private
}

typedef ConstantValueExpression = (
    ExpressionType type constraint(value in (ConstantValue)),
    VariantValue value;
);

typedef ColumnValueExpression = (
    ExpressionType type constraint(value in (ConstantValue)),
    Column
);

namespace BooleanExpression {
    
    typedef = (
        union(
            -- Boolean
            BinaryBooleanExpression binary_bool,
            UnaryBooleanExpression unary_bool,
            -- Comparison
            EqualityExpression equality,
            NullComparisonExpression null_compare,
            -- Values
            ConstantValueExprssion constant,
            ColumnValueExpression column,
            -- Math
            -- TODO
            -- Aggregates
            -- TODO
        ) base,
    );
    
    (BooleanExpression) pure not(BooleanExpression op) {
        return (unary_bool: (Not, op));
    }
    
    (BooleanExpression) pure and(BooleanExpression op1, BooleanExpression op2);
    (BooleanExpression) pure or(BooleanExpression op1, BooleanExpression op2);
    (BooleanExpression) pure xor(BooleanExpression op1, BooleanExpression op2);
    
    (BooleanExpression) pure eq(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    (BooleanExpression) pure neq(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    (BooleanExpression) pure less(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    (BooleanExpression) pure less_eq(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    (BooleanExpression) pure greater(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    (BooleanExpression) pure greater_eq(ColumnType T)(ValueExpression(T) a, ValueExpression(T) b);
    
    (BooleanExpression) pure is_null(NullColumnType T)(ValueExpression(T) a);
    (BooleanExpression) pure not_null(NullColumnType T)(ValueExpression(T) a);
    
    (ValueExpression) pure null_const();
    (ValueExpression) pure int_const(int value);
    (ValueExpression) pure float_const(float value);
    (ValueExpression) pure bool_const(bool value);
    (ValueExpression) pure string_const(string value);
}

typedef Driver = private;

namespace Connection {
    
    typedef = private;
    
    (Connection*) new(Driver* driver, string connection_string);
    () close(Connection* this);

    -- TODO data definition:
    --   * create/update/delete table
    --   * automatic table upgrade
    --   * initialization of table types before use (select/update)
    --     (if some connector needs this?)


    -- return type should be statically typed if possible (not variant typed).
    -- shouldn't it return a iterator type?
    (ColumnValuePair(typeof(table), any)[]*?) select(
              Table* table,
              count numColumns,
              Column(typeof(table))[numColumns]* what,
              BooleanExpression* where,
    );

    (bool) update(Connection* this,
              Table* table,
              count numColumns,
              ColumnValuePair(typeof(table), any)[numColumns]* what,
              BooleanExpression* where,   -- how should this be defined?
    );

    (bool) delete(Connection* this,
              Table* table,
              BooleanExpression* where,
    );

}

-- Transactions
(Transaction*) begin(Connection* this);

namespace Transaction {
    
    typedef = private;
    
    (bool) commit(Transaction* this);
    () close(Transaction* this);
}