qlite: cleanup, fix nullity issues

This commit is contained in:
Marvin W 2017-04-16 15:11:00 +02:00
parent c6ff3387fa
commit 765c2605cd
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
9 changed files with 131 additions and 181 deletions

View file

@ -4,12 +4,12 @@ namespace Qlite {
public abstract class Column<T> { public abstract class Column<T> {
public string name { get; private set; } public string name { get; private set; }
public string default { get; set; } public string? default { get; set; }
public int sqlite_type { get; private set; } public int sqlite_type { get; private set; }
public bool primary_key { get; set; } public bool primary_key { get; set; }
public bool auto_increment { get; set; } public bool auto_increment { get; set; }
public bool unique { get; set; } public bool unique { get; set; }
public bool not_null { get; set; } public virtual bool not_null { get; set; }
public long min_version { get; set; default = -1; } public long min_version { get; set; default = -1; }
public long max_version { get; set; default = long.MAX; } public long max_version { get; set; default = long.MAX; }
@ -43,7 +43,7 @@ public abstract class Column<T> {
} }
if (not_null) res += " NOT NULL"; if (not_null) res += " NOT NULL";
if (unique) res += " UNIQUE"; if (unique) res += " UNIQUE";
if (default != null) res += @" DEFAULT $default"; if (default != null) res += @" DEFAULT $((!) default)";
return res; return res;
} }
@ -122,13 +122,33 @@ public abstract class Column<T> {
internal override void bind(Statement stmt, int index, string? value) { internal override void bind(Statement stmt, int index, string? value) {
if (value != null) { if (value != null) {
stmt.bind_text(index, value); stmt.bind_text(index, (!) value);
} else { } else {
stmt.bind_null(index); stmt.bind_null(index);
} }
} }
} }
public class NonNullText : Column<string> {
public NonNullText(string name) {
base(name, TEXT);
}
public override bool not_null { get { return true; } set {} }
public override string get(Row row) {
return (!)row.get_text(name);
}
public override bool is_null(Row row) {
return false;
}
internal override void bind(Statement stmt, int index, string value) {
stmt.bind_text(index, (!) value);
}
}
public class BoolText : Column<bool> { public class BoolText : Column<bool> {
public BoolText(string name) { public BoolText(string name) {
base(name, TEXT); base(name, TEXT);

View file

@ -17,11 +17,11 @@ public class Database {
private string file_name; private string file_name;
private Sqlite.Database db; private Sqlite.Database db;
private long expected_version; private long expected_version;
private Table[] tables; private Table[]? tables;
private Column<string> meta_name = new Column.Text("name") { primary_key = true }; private Column<string?> meta_name = new Column.Text("name") { primary_key = true };
private Column<long> meta_int_val = new Column.Long("int_val"); private Column<long> meta_int_val = new Column.Long("int_val");
private Column<string> meta_text_val = new Column.Text("text_val"); private Column<string?> meta_text_val = new Column.Text("text_val");
private Table meta_table; private Table meta_table;
public bool debug = false; public bool debug = false;

View file

@ -5,12 +5,12 @@ namespace Qlite {
public class DeleteBuilder : StatementBuilder { public class DeleteBuilder : StatementBuilder {
// DELETE FROM [...] // DELETE FROM [...]
private Table table; private Table? table;
private string table_name; private string table_name;
// WHERE [...] // WHERE [...]
private string selection; private string selection = "1";
private StatementBuilder.Field[] selection_args; private StatementBuilder.AbstractField[] selection_args = {};
internal DeleteBuilder(Database db) { internal DeleteBuilder(Database db) {
base(db); base(db);
@ -29,35 +29,22 @@ public class DeleteBuilder : StatementBuilder {
} }
public DeleteBuilder where(string selection, string[]? selection_args = null) throws DatabaseError { public DeleteBuilder where(string selection, string[]? selection_args = null) throws DatabaseError {
if (this.selection != null) throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called."); if (this.selection != "1") throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called.");
this.selection = selection; this.selection = selection;
if (selection_args != null) { foreach (string arg in selection_args) {
this.selection_args = new StatementBuilder.Field[selection_args.length]; this.selection_args += new StatementBuilder.StringField(arg);
for (int i = 0; i < selection_args.length; i++) {
this.selection_args[i] = new StatementBuilder.StringField(selection_args[i]);
}
} }
return this; return this;
} }
public DeleteBuilder with<T>(Column<T> column, string comp, T value) { public DeleteBuilder with<T>(Column<T> column, string comp, T value) {
if (selection == null) { selection_args += new Field<T>(column, value);
selection = @"$(column.name) $comp ?";
selection_args = { new StatementBuilder.Field<T>(column, value) };
} else {
selection = @"($selection) AND $(column.name) $comp ?"; 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; return this;
} }
internal override Statement prepare() throws DatabaseError { internal override Statement prepare() throws DatabaseError {
Statement stmt = db.prepare(@"DELETE FROM $table_name $(selection != null ? @"WHERE $selection": "")"); Statement stmt = db.prepare(@"DELETE FROM $table_name WHERE $selection");
for (int i = 0; i < selection_args.length; i++) { for (int i = 0; i < selection_args.length; i++) {
selection_args[i].bind(stmt, i+1); selection_args[i].bind(stmt, i+1);
} }

View file

@ -6,14 +6,14 @@ public class InsertBuilder : StatementBuilder {
// INSERT [OR ...] // INSERT [OR ...]
private bool replace_val; private bool replace_val;
private string or_val; private string? or_val;
// INTO [...] // INTO [...]
private Table table; private Table table;
private string table_name; private string table_name;
// VALUES [...] // VALUES [...]
private StatementBuilder.Field[] fields; private StatementBuilder.AbstractField[] fields = {};
internal InsertBuilder(Database db) { internal InsertBuilder(Database db) {
base(db); base(db);
@ -41,31 +41,13 @@ public class InsertBuilder : StatementBuilder {
} }
public InsertBuilder value<T>(Column<T> column, T value) { public InsertBuilder value<T>(Column<T> column, T value) {
if (fields == null) { fields += new Field<T>(column, value);
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; return this;
} }
public InsertBuilder value_null<T>(Column<T> column) throws DatabaseError { public InsertBuilder value_null<T>(Column<T> column) throws DatabaseError {
if (column.not_null) throw new DatabaseError.ILLEGAL_QUERY(@"Can't set non-null column $(column.name) to null"); 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);
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; return this;
} }
@ -77,11 +59,11 @@ public class InsertBuilder : StatementBuilder {
value_qs += ", "; value_qs += ", ";
fields_text += ", "; fields_text += ", ";
} }
fields_text += fields[i].column.name; fields_text += ((!)fields[i].column).name;
value_qs += "?"; value_qs += "?";
} }
string sql = replace_val ? "REPLACE" : "INSERT"; string sql = replace_val ? "REPLACE" : "INSERT";
if (!replace_val && or_val != null) sql += @" OR $or_val"; if (!replace_val && or_val != null) sql += @" OR $((!)or_val)";
sql += @" INTO $table_name ( $fields_text ) VALUES ($value_qs)"; sql += @" INTO $table_name ( $fields_text ) VALUES ($value_qs)";
Statement stmt = db.prepare(sql); Statement stmt = db.prepare(sql);
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {

View file

@ -7,18 +7,18 @@ public class QueryBuilder : StatementBuilder {
// SELECT [...] // SELECT [...]
private string column_selector = "*"; private string column_selector = "*";
private Column[] columns; private Column[] columns = {};
// FROM [...] // FROM [...]
private Table table; private Table? table;
private string table_name; private string? table_name;
// WHERE [...] // WHERE [...]
private string selection; private string selection = "1";
private StatementBuilder.Field[] selection_args; private StatementBuilder.AbstractField[] selection_args = {};
// ORDER BY [...] // ORDER BY [...]
private OrderingTerm[] order_by_terms; private OrderingTerm[]? order_by_terms = {};
// LIMIT [...] // LIMIT [...]
private int limit_val; private int limit_val;
@ -27,9 +27,9 @@ public class QueryBuilder : StatementBuilder {
base(db); base(db);
} }
public QueryBuilder select(Column[]? columns = null) { public QueryBuilder select(Column[] columns = {}) {
this.columns = columns; this.columns = columns;
if (columns != null) { if (columns.length == 0) {
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
if (column_selector == "*") { if (column_selector == "*") {
column_selector = columns[0].name; column_selector = columns[0].name;
@ -44,7 +44,7 @@ public class QueryBuilder : StatementBuilder {
} }
public QueryBuilder select_string(string column_selector) { public QueryBuilder select_string(string column_selector) {
this.columns = null; this.columns = {};
this.column_selector = column_selector; this.column_selector = column_selector;
return this; return this;
} }
@ -61,32 +61,19 @@ public class QueryBuilder : StatementBuilder {
return this; return this;
} }
public QueryBuilder where(string selection, string[]? selection_args = null) throws DatabaseError { public QueryBuilder where(string selection, string[] selection_args = {}) throws DatabaseError {
if (this.selection != null) throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called."); if (this.selection != "1") throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called.");
this.selection = selection; this.selection = selection;
if (selection_args != null) { foreach (string arg in selection_args) {
this.selection_args = new StatementBuilder.Field[selection_args.length]; this.selection_args += new StatementBuilder.StringField(arg);
for (int i = 0; i < selection_args.length; i++) {
this.selection_args[i] = new StatementBuilder.StringField(selection_args[i]);
}
} }
return this; return this;
} }
public QueryBuilder with<T>(Column<T> column, string comp, T value) { public QueryBuilder with<T>(Column<T> column, string comp, T value) {
if ((column.unique || column.primary_key) && comp == "=") single_result = true; if ((column.unique || column.primary_key) && comp == "=") single_result = true;
if (selection == null) { selection_args += new Field<T>(column, value);
selection = @"$(column.name) $comp ?";
selection_args = { new StatementBuilder.Field<T>(column, value) };
} else {
selection = @"($selection) AND $(column.name) $comp ?"; 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; return this;
} }
@ -100,26 +87,13 @@ public class QueryBuilder : StatementBuilder {
return this; return this;
} }
private void add_order_by(OrderingTerm term) {
if (order_by_terms == null) {
order_by_terms = { term };
} else {
OrderingTerm[] order_by_terms_new = new OrderingTerm[order_by_terms.length+1];
for (int i = 0; i < order_by_terms.length; i++) {
order_by_terms_new[i] = order_by_terms[i];
}
order_by_terms_new[order_by_terms.length] = term;
order_by_terms = order_by_terms_new;
}
}
public QueryBuilder order_by(Column column, string dir = "ASC") { public QueryBuilder order_by(Column column, string dir = "ASC") {
add_order_by(new OrderingTerm(column, dir)); order_by_terms += new OrderingTerm(column, dir);
return this; return this;
} }
public QueryBuilder order_by_name(string name, string dir) { public QueryBuilder order_by_name(string name, string dir) {
add_order_by(new OrderingTerm.by_name(name, dir)); order_by_terms += new OrderingTerm.by_name(name, dir);
return this; return this;
} }
@ -131,12 +105,12 @@ public class QueryBuilder : StatementBuilder {
public int64 count() throws DatabaseError { public int64 count() throws DatabaseError {
this.column_selector = @"COUNT($column_selector) AS count"; this.column_selector = @"COUNT($column_selector) AS count";
this.single_result = true; this.single_result = true;
return row_().get_integer("count"); return row().get_integer("count");
} }
private 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."); 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(); return iterator().get_next();
} }
public RowOption row() throws DatabaseError { public RowOption row() throws DatabaseError {
@ -148,7 +122,7 @@ public class QueryBuilder : StatementBuilder {
} }
internal override Statement prepare() throws DatabaseError { internal override Statement prepare() throws DatabaseError {
Statement stmt = db.prepare(@"SELECT $column_selector FROM $table_name $(selection != null ? @"WHERE $selection" : "") $(order_by_terms != null ? OrderingTerm.all_to_string(order_by_terms) : "") $(limit_val > 0 ? @" LIMIT $limit_val" : "")"); Statement stmt = db.prepare(@"SELECT $column_selector $(table_name == null ? "" : @"FROM $((!) table_name)") WHERE $selection $(OrderingTerm.all_to_string(order_by_terms)) $(limit_val > 0 ? @" LIMIT $limit_val" : "")");
for (int i = 0; i < selection_args.length; i++) { for (int i = 0; i < selection_args.length; i++) {
selection_args[i].bind(stmt, i+1); selection_args[i].bind(stmt, i+1);
} }
@ -179,8 +153,8 @@ public class QueryBuilder : StatementBuilder {
return @"$column_name $dir"; return @"$column_name $dir";
} }
public static string all_to_string(OrderingTerm[] terms) { public static string all_to_string(OrderingTerm[]? terms) {
if (terms.length == 0) return ""; if (terms == null || terms.length == 0) return "";
string res = "ORDER BY "+terms[0].to_string(); string res = "ORDER BY "+terms[0].to_string();
for (int i = 1; i < terms.length; i++) { for (int i = 1; i < terms.length; i++) {
res += @", $(terms[i])"; res += @", $(terms[i])";

View file

@ -4,7 +4,7 @@ using Sqlite;
namespace Qlite { namespace Qlite {
public class Row { public class Row {
private Map<string, string> text_map = new HashMap<string, string>(); private Map<string, string?> text_map = new HashMap<string, string?>();
private Map<string, long> int_map = new HashMap<string, long>(); private Map<string, long> int_map = new HashMap<string, long>();
private Map<string, double?> real_map = new HashMap<string, double?>(); private Map<string, double?> real_map = new HashMap<string, double?>();
@ -43,8 +43,8 @@ public class Row {
return int_map.has_key(field); return int_map.has_key(field);
} }
public double get_real(string field) { public double get_real(string field, double def = 0) {
return real_map[field]; return real_map[field] ?? def;
} }
public bool has_real(string field) { public bool has_real(string field) {
@ -71,11 +71,21 @@ public class RowIterator {
} }
} }
public Row? next_value() throws DatabaseError { public bool next() {
int r = stmt.step(); int r = stmt.step();
if (r == Sqlite.ROW) return new Row(stmt); if (r == Sqlite.ROW) return true;
if (r == Sqlite.DONE) return null; if (r == Sqlite.DONE) return false;
throw new DatabaseError.EXEC_ERROR(@"SQLite error: $(db.errcode()) - $(db.errmsg())"); print(@"SQLite error: $(db.errcode()) - $(db.errmsg())\n");
return false;
}
public Row get() {
return new Row(stmt);
}
public Row? get_next() {
if (next()) return get();
return null;
} }
} }
@ -91,8 +101,13 @@ public class RowOption {
} }
public T get<T>(Column<T> field, T def = null) { public T get<T>(Column<T> field, T def = null) {
if (inner == null || field.is_null(inner)) return def; if (inner == null || field.is_null((!)inner)) return def;
return field[inner]; 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);
} }
} }

View file

@ -11,25 +11,32 @@ public abstract class StatementBuilder {
internal abstract Statement prepare() throws DatabaseError; internal abstract Statement prepare() throws DatabaseError;
internal class Field<T> { internal abstract class AbstractField<T> {
public T value; public T value;
public Column<T>? column; public Column<T>? column;
public Field(Column<T>? column, T value) { public AbstractField(T value) {
this.column = column;
this.value = value; this.value = value;
} }
internal virtual void bind(Statement stmt, int index) { internal abstract void bind(Statement stmt, int index);
if (column != null) {
column.bind(stmt, index, value);
} }
internal class Field<T> : AbstractField<T> {
public Field(Column<T> column, T value) {
base(value);
this.column = column;
}
internal override void bind(Statement stmt, int index) {
((!)column).bind(stmt, index, value);
} }
} }
internal class NullField<T> : Field<T> { internal class NullField<T> : AbstractField<T> {
public NullField(Column<T>? column) { public NullField(Column<T> column) {
base(column, null); base(null);
this.column = column;
} }
internal override void bind(Statement stmt, int index) { internal override void bind(Statement stmt, int index) {
@ -37,9 +44,9 @@ public abstract class StatementBuilder {
} }
} }
internal class StringField : Field<string> { internal class StringField : AbstractField<string> {
public StringField(string value) { public StringField(string value) {
base(null, value); base(value);
} }
internal override void bind(Statement stmt, int index) { internal override void bind(Statement stmt, int index) {

View file

@ -5,22 +5,21 @@ namespace Qlite {
public class Table { public class Table {
protected Database db; protected Database db;
public string name { get; private set; } public string name { get; private set; }
protected Column[] columns; protected Column[]? columns;
private string constraints; private string constraints = "";
public Table(Database db, string name) { public Table(Database db, string name) {
this.db = db; this.db = db;
this.name = name; this.name = name;
} }
public void init(Column[] columns, string? constraints = null) { public void init(Column[] columns, string constraints = "") {
this.columns = columns; this.columns = columns;
this.constraints = constraints; this.constraints = constraints;
} }
public void unique(Column[] columns, string? on_conflict = null) { public void unique(Column[] columns, string? on_conflict = null) {
if (constraints == null) constraints = ""; else constraints += ", "; constraints += ", UNIQUE (";
constraints += "UNIQUE (";
bool first = true; bool first = true;
foreach (Column c in columns) { foreach (Column c in columns) {
if (!first) constraints += ", "; if (!first) constraints += ", ";
@ -29,7 +28,7 @@ public class Table {
} }
constraints += ")"; constraints += ")";
if (on_conflict != null) { if (on_conflict != null) {
constraints += "ON CONFLICT " + on_conflict; constraints += "ON CONFLICT " + (!)on_conflict;
} }
} }
@ -80,10 +79,7 @@ public class Table {
sql += @"$(i > 0 ? "," : "") $c"; sql += @"$(i > 0 ? "," : "") $c";
} }
} }
if (constraints != null) { sql += @"$constraints)";
sql += ", " + constraints;
}
sql += ")";
db.exec(sql); db.exec(sql);
} }
@ -98,10 +94,10 @@ public class Table {
public void delete_columns_for_version(long old_version, long new_version) throws DatabaseError { public void delete_columns_for_version(long old_version, long new_version) throws DatabaseError {
bool column_deletion_required = false; bool column_deletion_required = false;
string column_list = null; string column_list = "";
foreach (Column c in columns) { foreach (Column c in columns) {
if (c.min_version <= new_version && c.max_version >= new_version) { if (c.min_version <= new_version && c.max_version >= new_version) {
if (column_list == null) { if (column_list == "") {
column_list = c.name; column_list = c.name;
} else { } else {
column_list += ", " + c.name; column_list += ", " + c.name;

View file

@ -5,18 +5,18 @@ namespace Qlite {
public class UpdateBuilder : StatementBuilder { public class UpdateBuilder : StatementBuilder {
// UPDATE [OR ...] // UPDATE [OR ...]
private string or_val; private string? or_val;
// [...] // [...]
private Table table; private Table? table;
private string table_name; private string table_name;
// SET [...] // SET [...]
private StatementBuilder.Field[] fields; private StatementBuilder.AbstractField[] fields = {};
// WHERE [...] // WHERE [...]
private string selection; private string selection = "1";
private StatementBuilder.Field[] selection_args; private StatementBuilder.AbstractField[] selection_args = {};
internal UpdateBuilder(Database db, Table table) { internal UpdateBuilder(Database db, Table table) {
base(db); base(db);
@ -35,59 +35,28 @@ public class UpdateBuilder : StatementBuilder {
} }
public UpdateBuilder set<T>(Column<T> column, T value) { public UpdateBuilder set<T>(Column<T> column, T value) {
if (fields == null) { fields += new Field<T>(column, value);
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; return this;
} }
public UpdateBuilder set_null<T>(Column<T> column) throws DatabaseError { public UpdateBuilder set_null<T>(Column<T> column) throws DatabaseError {
if (column.not_null) throw new DatabaseError.ILLEGAL_QUERY(@"Can't set non-null column $(column.name) to null"); 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);
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; return this;
} }
public UpdateBuilder where(string selection, string[]? selection_args = null) throws DatabaseError { public UpdateBuilder where(string selection, string[] selection_args = {}) throws DatabaseError {
if (this.selection != null) throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called."); if (this.selection != "1") throw new DatabaseError.ILLEGAL_QUERY("selection was already done, but where() was called.");
this.selection = selection; this.selection = selection;
if (selection_args != null) { foreach (string arg in selection_args) {
this.selection_args = new StatementBuilder.Field[selection_args.length]; this.selection_args += new StatementBuilder.StringField(arg);
for (int i = 0; i < selection_args.length; i++) {
this.selection_args[i] = new StatementBuilder.StringField(selection_args[i]);
}
} }
return this; return this;
} }
public UpdateBuilder with<T>(Column<T> column, string comp, T value) { public UpdateBuilder with<T>(Column<T> column, string comp, T value) {
if (selection == null) { selection_args += new Field<T>(column, value);
selection = @"$(column.name) $comp ?";
selection_args = { new StatementBuilder.Field<T>(column, value) };
} else {
selection = @"($selection) AND $(column.name) $comp ?"; 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; return this;
} }
@ -103,13 +72,13 @@ public class UpdateBuilder : StatementBuilder {
internal override Statement prepare() throws DatabaseError { internal override Statement prepare() throws DatabaseError {
string sql = "UPDATE"; string sql = "UPDATE";
if (or_val != null) sql += @" OR $or_val"; if (or_val != null) sql += @" OR $((!)or_val)";
sql += @" $table_name SET "; sql += @" $table_name SET ";
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
if (i != 0) { if (i != 0) {
sql += ", "; sql += ", ";
} }
sql += @"$(fields[i].column.name) = ?"; sql += @"$(((!)fields[i].column).name) = ?";
} }
sql += @" WHERE $selection"; sql += @" WHERE $selection";
Statement stmt = db.prepare(sql); Statement stmt = db.prepare(sql);
@ -123,7 +92,7 @@ public class UpdateBuilder : StatementBuilder {
} }
public void perform() throws DatabaseError { public void perform() throws DatabaseError {
if (fields == null || fields.length == 0) return; if (fields.length == 0) return;
if (prepare().step() != DONE) { if (prepare().step() != DONE) {
throw new DatabaseError.EXEC_ERROR(@"SQLite error: $(db.errcode()) - $(db.errmsg())"); throw new DatabaseError.EXEC_ERROR(@"SQLite error: $(db.errcode()) - $(db.errmsg())");
} }