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
|
namespace SQLHeavyGtk {
/**
* Gtk.TreeModel implementation
*/
public class Model : GLib.Object, Gtk.TreeModel {
private SQLHeavy.Table _table;
/**
* The table that this model is based on
*/
public SQLHeavy.Table table {
get {
return this._table;
}
construct {
this._table = value;
this.queryable = table.queryable;
}
}
/**
* Cache of the table's queryable
*/
private SQLHeavy.Queryable queryable;
private SQLHeavy.Row? get_row_from_iter (Gtk.TreeIter iter) {
if ( iter.user_data != null ) {
return (SQLHeavy.Row) iter.user_data;
} else {
try {
var row = this.table.get (iter.stamp);
iter.user_data = row;
row.ref ();
return row;
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to get row from iterator: %s", e.message);
return null;
}
}
}
// Begin GtkTreeModel methods
public GLib.Type get_column_type (int index) {
try {
if ( index == 0 ) // ROWID
return typeof (int64);
else
return this.table.field_affinity_type (index - 1);
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to determine column affinity (column #%d): %s", index, e.message);
return typeof (void);
}
}
public Gtk.TreeModelFlags get_flags () {
return Gtk.TreeModelFlags.LIST_ONLY;
}
public bool get_iter (out Gtk.TreeIter iter, Gtk.TreePath path) {
int64 offset = 0;
unowned int[] indices = path.get_indices ();
if ( indices.length == -1 )
offset = 0;
else if ( indices.length == 1 )
offset = indices[0];
else
return false;
try {
var res = this.queryable.prepare (@"SELECT `ROWID` FROM `$(SQLHeavy.escape_string (this.table.name))` ORDER BY `ROWID` ASC LIMIT $(indices[0]),1;").execute ();
if ( res.finished )
return false;
iter.stamp = res.fetch_int ();
return true;
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to get row ID for iterator: %s", e.message);
return false;
}
}
public int get_n_columns () {
return this.table.field_count + 1;
}
public Gtk.TreePath? get_path (Gtk.TreeIter iter) {
try {
SQLHeavy.QueryResult res = this.queryable.prepare (@"SELECT COUNT(*) FROM `$(SQLHeavy.escape_string (this.table.name))` WHERE `ROWID` < :rid ORDER BY `ROWID` ASC LIMIT 1").execute (":rid", typeof (int), iter.stamp);
return new Gtk.TreePath.from_indices (res.fetch_int ());
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to get path from iterator: %s", e.message);
return (!) null;
}
}
private int get_value_calls = 0;
public void get_value (Gtk.TreeIter iter, int column, out GLib.Value value) {
try {
SQLHeavy.Row row = this.get_row_from_iter (iter);
value = row.fetch (column - 1);
if ( value.holds (typeof (void*)) )
value = GLib.Value (typeof (string));
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to get value: %s", e.message);
}
}
public bool iter_children (out Gtk.TreeIter iter, Gtk.TreeIter? parent) {
return false;
}
public bool iter_has_child (Gtk.TreeIter iter) {
return false;
}
public int iter_n_children (Gtk.TreeIter? iter) {
return 0;
}
private int next_calls = 0;
public bool iter_next (ref Gtk.TreeIter iter) {
try {
SQLHeavy.QueryResult res = this.queryable.prepare (@"SELECT `ROWID` FROM `$(SQLHeavy.escape_string (this.table.name))` WHERE `ROWID` > $(iter.stamp) ORDER BY `ROWID` ASC LIMIT 1").execute ();
if ( res.finished ) {
return false;
}
else {
iter.stamp = res.fetch_int ();
iter.user_data = null;
return true;
}
} catch ( SQLHeavy.Error e ) {
GLib.critical ("Unable to determine next row id: %s", e.message);
return false;
}
}
public bool iter_nth_child (out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) {
return false;
}
public bool iter_parent (out Gtk.TreeIter iter, Gtk.TreeIter child) {
return false;
}
public virtual void ref_node (Gtk.TreeIter iter) {
if ( iter.user_data != null )
((SQLHeavy.Row) iter.user_data).ref ();
}
public virtual void unref_node (Gtk.TreeIter iter) {
if ( iter.user_data != null )
((SQLHeavy.Row) iter.user_data).unref ();
}
// End GtkTreeModel methods
/**
* Create a new Model
*
* @param table the table this model is based on
* @see table
*/
public Model (SQLHeavy.Table table) {
GLib.Object (table: table);
}
}
}
|