aboutsummaryrefslogtreecommitdiff
path: root/qlite/src/update_builder.vala
blob: 5f721a32902b29908bef86e53c7e34d7d52aeddf (plain) (blame)
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
using Sqlite;

namespace Qlite {

public class UpdateBuilder : StatementBuilder {

    // UPDATE [OR ...]
    private string or_val;

    // [...]
    private Table table;
    private string table_name;

    // SET [...]
    private StatementBuilder.Field[] fields;

    // WHERE [...]
    private string selection;
    private StatementBuilder.Field[] selection_args;

    protected UpdateBuilder(Database db, Table table) {
        base(db);
        this.table = table;
        this.table_name = table.name;
    }

    internal UpdateBuilder.for_name(Database db, string table) {
        base(db);
        this.table_name = table;
    }

    public UpdateBuilder or(string or) {
        this.or_val = or;
        return this;
    }

    public UpdateBuilder set<T>(Column<T> column, T value) {
        if (fields == null) {
            fields = { new StatementBuilder.Field<T>(column, value) };
        } else {
            StatementBuilder.Field[] fields_new = new StatementBuilder.Field[fields.length+1];
            for (int i = 0; i < fields.length; i++) {
                fields_new[i] = fields[i];
            }
            fields_new[fields.length] = new Field<T>(column, value);
            fields = fields_new;
        }
        return this;
    }

    public UpdateBuilder set_null<T>(Column<T> column) {
        if (column.not_null) throw new DatabaseError.ILLEGAL_QUERY(@"Can't set non-null column $(column.name) to null");
        if (fields == null) {
            fields = { new NullField<T>(column) };
        } else {
            StatementBuilder.Field[] fields_new = new StatementBuilder.Field[fields.length+1];
            for (int i = 0; i < fields.length; i++) {
                fields_new[i] = fields[i];
            }
            fields_new[fields.length] = new NullField<T>(column);
            fields = fields_new;
        }
        return this;
    }

    public UpdateBuilder where(string selection, string[]? selection_args = null) {
        if (selection != null) throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called.");
        this.selection = selection;
        if (selection_args != null) {
            this.selection_args = new StatementBuilder.Field[selection_args.length];
            for (int i = 0; i < selection_args.length; i++) {
                this.selection_args[i] = new StatementBuilder.StringField(selection_args[i]);
            }
        }
        return this;
    }

    public UpdateBuilder with<T>(Column<T> column, string comp, T value) {
        if (selection == null) {
            selection = @"$(column.name) $comp ?";
            selection_args = { new StatementBuilder.Field<T>(column, value) };
        } else {
            selection = @"($selection) AND $(column.name) $comp ?";
            StatementBuilder.Field[] selection_args_new = new StatementBuilder.Field[selection_args.length+1];
            for (int i = 0; i < selection_args.length; i++) {
                selection_args_new[i] = selection_args[i];
            }
            selection_args_new[selection_args.length] = new Field<T>(column, value);
            selection_args = selection_args_new;
        }
        return this;
    }

    public UpdateBuilder with_null<T>(Column<T> column) {
        selection = @"($selection) AND $(column.name) ISNULL";
        return this;
    }

    public UpdateBuilder without_null<T>(Column<T> column) {
        selection = @"($selection) AND $(column.name) NOT NULL";
        return this;
    }

    public override Statement prepare() throws DatabaseError {
        string sql = "UPDATE";
        if (or_val != null) sql += @" OR $or_val";
        sql += @" $table_name SET ";
        for (int i = 0; i < fields.length; i++) {
            if (i != 0) {
                sql += ", ";
            }
            sql += @"$(fields[i].column.name) = ?";
        }
        sql += @" WHERE $selection";
        Statement stmt = db.prepare(sql);
        for (int i = 0; i < fields.length; i++) {
            fields[i].bind(stmt, i+1);
        }
        for (int i = 0; i < selection_args.length; i++) {
            selection_args[i].bind(stmt, i + fields.length + 1);
        }
        return stmt;
    }

    public void perform() throws DatabaseError {
        if (fields == null || fields.length == 0) return;
        if (prepare().step() != DONE) {
            throw new DatabaseError.EXEC_ERROR(@"SQLite error: $(db.errcode()) - $(db.errmsg())");
        }
    }

}

}