From c4928d46486c4117b1bf2738d114297a42cf1940 Mon Sep 17 00:00:00 2001 From: bobufa Date: Mon, 18 Jun 2018 01:47:43 +0200 Subject: add support for fts tables to qlite --- qlite/src/query_builder.vala | 45 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) (limited to 'qlite/src/query_builder.vala') diff --git a/qlite/src/query_builder.vala b/qlite/src/query_builder.vala index 915e2d2d..9ca5bf25 100644 --- a/qlite/src/query_builder.vala +++ b/qlite/src/query_builder.vala @@ -10,12 +10,15 @@ public class QueryBuilder : StatementBuilder { private Column[] columns = {}; // FROM [...] - private Table? table; - private string? table_name; + protected Table? table; + protected string? table_name; + + // JOIN [...] + private string joins = ""; // WHERE [...] - private string selection = "1"; - private StatementBuilder.AbstractField[] selection_args = {}; + protected string selection = "1"; + internal StatementBuilder.AbstractField[] selection_args = {}; // ORDER BY [...] private OrderingTerm[]? order_by_terms = {}; @@ -50,18 +53,23 @@ public class QueryBuilder : StatementBuilder { return this; } - public QueryBuilder from(Table table) { + public virtual QueryBuilder from(Table table) { if (this.table_name != null) error("cannot use from() multiple times."); this.table = table; this.table_name = table.name; return this; } - public QueryBuilder from_name(string table) { + public virtual QueryBuilder from_name(string table) { this.table_name = table; return this; } + public QueryBuilder join(string table, string on) { + joins += @"JOIN $table ON $on"; + return this; + } + public QueryBuilder where(string selection, string[] selection_args = {}) { if (this.selection != "1") error("selection was already done, but where() was called."); this.selection = selection; @@ -74,17 +82,17 @@ public class QueryBuilder : StatementBuilder { public QueryBuilder with(Column column, string comp, T value) { if ((column.unique || column.primary_key) && comp == "=") single_result = true; selection_args += new Field(column, value); - selection = @"($selection) AND $(column.name) $comp ?"; + selection = @"($selection) AND $table_name.$(column.name) $comp ?"; return this; } public QueryBuilder with_null(Column column) { - selection = @"($selection) AND $(column.name) ISNULL"; + selection = @"($selection) AND $table_name.$(column.name) ISNULL"; return this; } public QueryBuilder without_null(Column column) { - selection = @"($selection) AND $(column.name) NOT NULL"; + selection = @"($selection) AND $table_name.$(column.name) NOT NULL"; return this; } @@ -135,7 +143,7 @@ public class QueryBuilder : StatementBuilder { } internal override Statement prepare() { - 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 OFFSET $offset_val" : "")"); + Statement stmt = db.prepare(@"SELECT $column_selector $(table_name == null ? "" : @"FROM $((!) table_name)") $joins WHERE $selection $(OrderingTerm.all_to_string(order_by_terms)) $(limit_val > 0 ? @" LIMIT $limit_val OFFSET $offset_val" : "")"); for (int i = 0; i < selection_args.length; i++) { selection_args[i].bind(stmt, i+1); } @@ -177,4 +185,21 @@ public class QueryBuilder : StatementBuilder { } } +public class MatchQueryBuilder : QueryBuilder { + internal MatchQueryBuilder(Database db, Table table) { + base(db); + if (table.fts_columns == null) error("MATCH query on non FTS table"); + from(table); + join(@"_fts_$table_name", @"_fts_$table_name.docid = $table_name.rowid"); + } + + public MatchQueryBuilder match(Column column, string match) { + if (table == null) error("MATCH must occur after FROM statement"); + if (!(column in table.fts_columns)) error("MATCH selection on non FTS column"); + selection_args += new StatementBuilder.StringField(match); + selection = @"($selection) AND _fts_$table_name.$(column.name) MATCH ?"; + return this; + } +} + } -- cgit v1.2.3-54-g00ecf