aboutsummaryrefslogtreecommitdiff
path: root/qlite/src/row.vala
blob: 4671db204325493609c3689f698d00277dab8338 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
using Gee;
using Sqlite;

namespace Qlite {

public class Row {
    private Map<string, string?> text_map = new HashMap<string, string?>();
    private Map<string, long> int_map = new HashMap<string, long>();
    private Map<string, double?> real_map = new HashMap<string, double?>();

    internal Row(Statement stmt) {
        for (int i = 0; i < stmt.column_count(); i++) {
            string column_name;
            if (stmt.column_origin_name(i) != null) {
                column_name = @"$(stmt.column_table_name(i)).$(stmt.column_origin_name(i))";
            } else {
                column_name = stmt.column_name(i);
            }
            switch(stmt.column_type(i)) {
                case TEXT:
                    text_map[column_name] = stmt.column_text(i);
                    break;
                case INTEGER:
                    int_map[column_name] = (long) stmt.column_int64(i);
                    break;
                case FLOAT:
                    real_map[column_name] = stmt.column_double(i);
                    break;
            }
        }
    }

    public T get<T>(Column<T> field) {
        return field[this];
    }

    private string field_name(string field, string? table) {
        if (table != null) {
            return @"$table.$field";
        } else {
            return field;
        }
    }

    public string? get_text(string field, string? table = null) {
        if (text_map.has_key(field_name(field, table))) {
            return text_map[field_name(field, table)];
        }
        return null;
    }

    public long get_integer(string field, string? table = null) {
        return int_map[field_name(field, table)];
    }

    public bool has_integer(string field, string? table = null) {
        return int_map.has_key(field_name(field, table));
    }

    public double get_real(string field, string? table = null, double def = 0) {
        return real_map[field_name(field, table)] ?? def;
    }

    public bool has_real(string field, string? table = null) {
        return real_map.has_key(field_name(field, table)) && real_map[field_name(field, table)] != null;
    }

    public string to_string() {
        string ret = "{";

        foreach (string key in text_map.keys) {
            if (ret.length > 1) ret += ", ";
            ret = @"$ret$key: \"$(text_map[key])\"";
        }
        foreach (string key in int_map.keys) {
            if (ret.length > 1) ret += ", ";
            ret = @"$ret$key: $(int_map[key])";
        }
        foreach (string key in real_map.keys) {
            if (ret.length > 1) ret += ", ";
            ret = @"$ret$key: $(real_map[key])";
        }

        return ret + "}";
    }
}

public class RowIterator {
    private Database db;
    private Statement stmt;

    public RowIterator.from_query_builder(Database db, QueryBuilder query) {
        this.db = db;
        this.stmt = query.prepare();
    }

    public RowIterator(Database db, string sql, string[]? args = null) {
        this.db = db;
        this.stmt = db.prepare(sql);
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                stmt.bind_text(i, sql, sql.length);
            }
        }
    }

    public bool next() {
        int r = stmt.step();
        if (r == Sqlite.ROW) return true;
        if (r == Sqlite.DONE) return false;
        warning(@"SQLite error: $(db.errcode()) - $(db.errmsg())");
        return false;
    }

    public Row get() {
        return new Row(stmt);
    }

    public Row? get_next() {
        if (next()) return get();
        return null;
    }
}

public class RowOption {
    public Row? inner { get; private set; }

    public RowOption(Row? row) {
        this.inner = row;
    }

    public bool is_present() {
        return inner != null;
    }

    public T get<T>(Column<T> field, T def = null) {
        if (inner == null || field.is_null((!)inner)) return def;
        return field[(!)inner];
    }

    internal long get_integer(string field, long def = 0) {
        if (inner == null || !((!)inner).has_integer(field)) return def;
        return ((!)inner).get_integer(field);
    }
}

}