2017-03-02 14:37:32 +00:00
|
|
|
using Sqlite;
|
|
|
|
|
|
|
|
namespace Qlite {
|
|
|
|
|
|
|
|
public class Table {
|
|
|
|
protected Database db;
|
|
|
|
public string name { get; private set; }
|
2017-04-16 13:11:00 +00:00
|
|
|
protected Column[]? columns;
|
|
|
|
private string constraints = "";
|
2017-04-23 08:23:11 +00:00
|
|
|
private string[] post_statements = {};
|
2017-03-02 14:37:32 +00:00
|
|
|
|
|
|
|
public Table(Database db, string name) {
|
|
|
|
this.db = db;
|
|
|
|
this.name = name;
|
|
|
|
}
|
|
|
|
|
2017-04-16 13:11:00 +00:00
|
|
|
public void init(Column[] columns, string constraints = "") {
|
2017-03-02 14:37:32 +00:00
|
|
|
this.columns = columns;
|
2017-03-09 20:46:16 +00:00
|
|
|
this.constraints = constraints;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void unique(Column[] columns, string? on_conflict = null) {
|
2017-04-16 13:11:00 +00:00
|
|
|
constraints += ", UNIQUE (";
|
2017-03-09 20:46:16 +00:00
|
|
|
bool first = true;
|
2017-03-12 18:33:31 +00:00
|
|
|
foreach (Column c in columns) {
|
2017-03-09 20:46:16 +00:00
|
|
|
if (!first) constraints += ", ";
|
|
|
|
constraints += c.name;
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
constraints += ")";
|
|
|
|
if (on_conflict != null) {
|
2017-05-21 21:30:30 +00:00
|
|
|
constraints += " ON CONFLICT " + (!)on_conflict;
|
2017-03-09 20:46:16 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2017-04-23 08:23:11 +00:00
|
|
|
public void add_post_statement(string stmt) {
|
|
|
|
post_statements += stmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void index(string index_name, Column[] columns, bool unique = false) {
|
|
|
|
string stmt = @"CREATE $(unique ? "UNIQUE" : "") INDEX IF NOT EXISTS $index_name ON $name (";
|
|
|
|
bool first = true;
|
|
|
|
foreach (Column c in columns) {
|
|
|
|
if (!first) stmt += ", ";
|
|
|
|
stmt += c.name;
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
stmt += ")";
|
|
|
|
add_post_statement(stmt);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
private void ensure_init() {
|
|
|
|
if (columns == null) error("Table %s was not initialized, call init()", name);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public QueryBuilder select(Column[]? columns = null) {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
return db.select(columns).from(this);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public InsertBuilder insert() {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
return db.insert().into(this);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public UpdateBuilder update() {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
return db.update(this);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public UpsertBuilder upsert() {
|
2017-08-25 22:05:36 +00:00
|
|
|
ensure_init();
|
|
|
|
return db.upsert(this);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public DeleteBuilder delete() {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
return db.delete().from(this);
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public RowOption row_with<T>(Column<T> column, T value) {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
2017-10-28 21:48:07 +00:00
|
|
|
if (!column.unique && !column.primary_key) error("%s is not suited to identify a row, but used with row_with()", column.name);
|
2017-03-02 14:37:32 +00:00
|
|
|
return select().with(column, "=", value).row();
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public bool is_known_column(string column) {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
foreach (Column c in columns) {
|
|
|
|
if (c.name == column) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public void create_table_at_version(long version) {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
string sql = @"CREATE TABLE IF NOT EXISTS $name (";
|
2017-03-12 18:33:31 +00:00
|
|
|
for (int i = 0; i < columns.length; i++) {
|
2017-03-02 14:37:32 +00:00
|
|
|
Column c = columns[i];
|
|
|
|
if (c.min_version <= version && c.max_version >= version) {
|
|
|
|
sql += @"$(i > 0 ? "," : "") $c";
|
|
|
|
}
|
|
|
|
}
|
2017-04-16 13:11:00 +00:00
|
|
|
sql += @"$constraints)";
|
2017-10-29 14:15:28 +00:00
|
|
|
try {
|
|
|
|
db.exec(sql);
|
|
|
|
} catch (Error e) {
|
|
|
|
error("Qlite Error: Create table at version");
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public void add_columns_for_version(long old_version, long new_version) {
|
2017-03-02 14:37:32 +00:00
|
|
|
ensure_init();
|
|
|
|
foreach (Column c in columns) {
|
2017-04-03 17:20:31 +00:00
|
|
|
if (c.min_version <= new_version && c.max_version >= new_version && c.min_version > old_version) {
|
2017-10-29 14:15:28 +00:00
|
|
|
try {
|
|
|
|
db.exec(@"ALTER TABLE $name ADD COLUMN $c");
|
|
|
|
} catch (Error e) {
|
|
|
|
error("Qlite Error: Add columns for version");
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
public void delete_columns_for_version(long old_version, long new_version) {
|
2017-03-12 18:33:31 +00:00
|
|
|
bool column_deletion_required = false;
|
2017-04-16 13:11:00 +00:00
|
|
|
string column_list = "";
|
2017-03-12 18:33:31 +00:00
|
|
|
foreach (Column c in columns) {
|
|
|
|
if (c.min_version <= new_version && c.max_version >= new_version) {
|
2017-04-16 13:11:00 +00:00
|
|
|
if (column_list == "") {
|
2017-03-12 18:33:31 +00:00
|
|
|
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) {
|
2017-10-29 14:15:28 +00:00
|
|
|
try {
|
|
|
|
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");
|
|
|
|
} catch (Error e) {
|
|
|
|
error("Qlite Error: Delete volumns for version change");
|
|
|
|
}
|
2017-03-12 18:33:31 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
2017-04-23 08:23:11 +00:00
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
internal void post() {
|
2017-04-23 08:23:11 +00:00
|
|
|
foreach (string stmt in post_statements) {
|
2017-10-29 14:15:28 +00:00
|
|
|
try {
|
|
|
|
db.exec(stmt);
|
|
|
|
} catch (Error e) {
|
|
|
|
error("Qlite Error: Post");
|
|
|
|
}
|
2017-04-23 08:23:11 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2017-10-28 21:48:07 +00:00
|
|
|
}
|