aboutsummaryrefslogtreecommitdiff
path: root/qlite/src
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2017-03-12 19:33:31 +0100
committerMarvin W <git@larma.de>2017-03-12 20:55:11 +0100
commitc2643a45b0dc05c4fd82ec7d32577700dae7450e (patch)
treed8a52d8eeee351f8279f9827b7e6d1b8024e7beb /qlite/src
parent4f34e431163ac49e2c41079d44c5dd4a71b362d1 (diff)
downloaddino-c2643a45b0dc05c4fd82ec7d32577700dae7450e.tar.gz
dino-c2643a45b0dc05c4fd82ec7d32577700dae7450e.zip
Qlite: Return OptionalRow instead of Row?, add ability to remove columns on version upgrade
Diffstat (limited to 'qlite/src')
-rw-r--r--qlite/src/database.vala20
-rw-r--r--qlite/src/query_builder.vala18
-rw-r--r--qlite/src/row.vala49
-rw-r--r--qlite/src/table.vala27
4 files changed, 77 insertions, 37 deletions
diff --git a/qlite/src/database.vala b/qlite/src/database.vala
index 6d26b2b4..9fea7708 100644
--- a/qlite/src/database.vala
+++ b/qlite/src/database.vala
@@ -51,15 +51,19 @@ public class Database {
meta_table.create_table_at_version(expected_version);
long old_version = 0;
try {
- Row? row = meta_table.row_with(meta_name, "version");
- old_version = row == null ? -1 : (long) row[meta_int_val];
+ old_version = meta_table.row_with(meta_name, "version")[meta_int_val, -1];
} catch (DatabaseError e) {
old_version = -1;
}
- foreach (Table t in tables) {
- t.create_table_at_version(old_version);
- }
- if (expected_version != old_version) {
+ if (old_version == -1) {
+ foreach (Table t in tables) {
+ t.create_table_at_version(expected_version);
+ }
+ meta_table.insert().value(meta_name, "version").value(meta_int_val, expected_version).perform();
+ } else if (expected_version != old_version) {
+ foreach (Table t in tables) {
+ t.create_table_at_version(old_version);
+ }
foreach (Table t in tables) {
t.add_columns_for_version(old_version, expected_version);
}
@@ -117,9 +121,9 @@ public class Database {
return new DeleteBuilder(this);
}
- public Row.RowIterator query_sql(string sql, string[]? args = null) throws DatabaseError {
+ public RowIterator query_sql(string sql, string[]? args = null) throws DatabaseError {
ensure_init();
- return new Row.RowIterator(this, sql, args);
+ return new RowIterator(this, sql, args);
}
public Statement prepare(string sql) throws DatabaseError {
diff --git a/qlite/src/query_builder.vala b/qlite/src/query_builder.vala
index 65cbb8f6..37f9b261 100644
--- a/qlite/src/query_builder.vala
+++ b/qlite/src/query_builder.vala
@@ -131,20 +131,20 @@ public class QueryBuilder : StatementBuilder {
public int64 count() throws DatabaseError {
this.column_selector = @"COUNT($column_selector) AS count";
this.single_result = true;
- return row().get_integer("count");
+ return row_().get_integer("count");
}
- public Row? row() throws DatabaseError {
+ private Row? row_() throws DatabaseError {
if (!single_result) throw new DatabaseError.NON_UNIQUE("query is not suited to return a single row, but row() was called.");
return iterator().next_value();
}
+ public RowOption row() throws DatabaseError {
+ return new RowOption(row_());
+ }
+
public T get<T>(Column<T> field) throws DatabaseError {
- Row row = row();
- if (row != null) {
- return row[field];
- }
- return null;
+ return row()[field];
}
public override Statement prepare() throws DatabaseError {
@@ -155,8 +155,8 @@ public class QueryBuilder : StatementBuilder {
return stmt;
}
- public Row.RowIterator iterator() throws DatabaseError {
- return new Row.RowIterator.from_query_builder(this);
+ public RowIterator iterator() throws DatabaseError {
+ return new RowIterator.from_query_builder(this);
}
class OrderingTerm {
diff --git a/qlite/src/row.vala b/qlite/src/row.vala
index ff98405f..de10751f 100644
--- a/qlite/src/row.vala
+++ b/qlite/src/row.vala
@@ -50,29 +50,46 @@ public class Row {
public bool has_real(string field) {
return real_map.has_key(field) && real_map[field] != null;
}
+}
- public class RowIterator {
- private Statement stmt;
+public class RowIterator {
+ private Statement stmt;
- public RowIterator.from_query_builder(QueryBuilder query) throws DatabaseError {
- this.stmt = query.prepare();
- }
+ public RowIterator.from_query_builder(QueryBuilder query) throws DatabaseError {
+ this.stmt = query.prepare();
+ }
- public RowIterator(Database db, string sql, string[]? args = null) throws DatabaseError {
- this.stmt = db.prepare(sql);
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- stmt.bind_text(i, sql, sql.length);
- }
+ public RowIterator(Database db, string sql, string[]? args = null) throws DatabaseError {
+ this.stmt = db.prepare(sql);
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ stmt.bind_text(i, sql, sql.length);
}
}
+ }
- public Row? next_value() {
- if (stmt.step() == Sqlite.ROW) {
- return new Row(stmt);
- }
- return null;
+ public Row? next_value() {
+ if (stmt.step() == Sqlite.ROW) {
+ return new Row(stmt);
}
+ 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];
}
}
diff --git a/qlite/src/table.vala b/qlite/src/table.vala
index 7396136e..357e18d4 100644
--- a/qlite/src/table.vala
+++ b/qlite/src/table.vala
@@ -22,7 +22,7 @@ public class Table {
if (constraints == null) constraints = ""; else constraints += ", ";
constraints += "UNIQUE (";
bool first = true;
- foreach(Column c in columns) {
+ foreach (Column c in columns) {
if (!first) constraints += ", ";
constraints += c.name;
first = false;
@@ -57,7 +57,7 @@ public class Table {
return db.delete().from(this);
}
- public Row? row_with<T>(Column<T> column, T value) throws DatabaseError {
+ public RowOption row_with<T>(Column<T> column, T value) throws DatabaseError {
ensure_init();
if (!column.unique && !column.primary_key) throw new DatabaseError.NON_UNIQUE(@"$(column.name) is not suited to identify a row, but used with row_with()");
return select().with(column, "=", value).row();
@@ -74,7 +74,7 @@ public class Table {
public void create_table_at_version(long version) throws DatabaseError {
ensure_init();
string sql = @"CREATE TABLE IF NOT EXISTS $name (";
- for(int i = 0; i < columns.length; i++) {
+ for (int i = 0; i < columns.length; i++) {
Column c = columns[i];
if (c.min_version <= version && c.max_version >= version) {
sql += @"$(i > 0 ? "," : "") $c";
@@ -97,7 +97,26 @@ public class Table {
}
public void delete_columns_for_version(long old_version, long new_version) throws DatabaseError {
- // TODO: Rename old table, create table at new_version, transfer data
+ bool column_deletion_required = false;
+ string column_list = null;
+ foreach (Column c in columns) {
+ if (c.min_version <= new_version && c.max_version >= new_version) {
+ if (column_list == null) {
+ column_list = c.name;
+ } else {
+ column_list += ", " + c.name;
+ }
+ }
+ if (!(c.min_version <= new_version && c.max_version >= new_version) && c.min_version <= old_version && c.max_version >= old_version) {
+ column_deletion_required = true;
+ }
+ }
+ if (column_deletion_required) {
+ db.exec(@"ALTER TABLE $name RENAME TO _$(name)_$old_version");
+ create_table_at_version(new_version);
+ db.exec(@"INSERT INTO $name ($column_list) SELECT $column_list FROM _$(name)_$old_version");
+ db.exec(@"DROP TABLE _$(name)_$old_version");
+ }
}
}