diff options
| author | 2021-07-26 22:12:29 -0400 | |
|---|---|---|
| committer | 2021-07-26 22:56:50 -0400 | |
| commit | 9fda89f559c217d825ce1c94c5942529fa314d9d (patch) | |
| tree | af1be9f767b737e75180f58b3c2da253f0336a4c | |
| parent | natargs: add missing import (diff) | |
add command line option for search
As of right now NOT queries do not work correctly for cards with more
than one tag.
| -rw-r--r-- | queryparse.py | 31 | ||||
| -rwxr-xr-x | underwriter | 9 |
2 files changed, 28 insertions, 12 deletions
diff --git a/queryparse.py b/queryparse.py index 544e9c4..7ebd0ab 100644 --- a/queryparse.py +++ b/queryparse.py @@ -53,15 +53,16 @@ class ParseTree: self.l = l def query_lit(alist, lit, isNot): + id = len(alist) + 1 if lit.op == LitType.TAGGLOB: - qr = f"""tag in (SELECT id FROM tags - WHERE name GLOB ?{len(alist)})""" + qr = f"""tag in (SELECT DISTINCT id FROM tags + WHERE name GLOB ?{id})""" elif lit.op == LitType.TITLEGLOB: - qr = f"""card in (SELECT id FROM cards - WHERE name GLOB ?{len(alist)})""" + qr = f"""card in (SELECT DISTINCT id FROM cards + WHERE name GLOB ?{id})""" elif lit.op == LitType.TAG: qr = f"""tag in (SELECT id FROM tags - WHERE name = ?{len(alist)} LIMIT 1)""" + WHERE name = ?{id} LIMIT 1)""" else: raise ParseError @@ -69,14 +70,14 @@ def query_lit(alist, lit, isNot): if isNot: qr = f"NOT ({qr})" - return f"SELECT card FROM tagmap WHERE {qr}" + return f"SELECT DISTINCT card FROM tagmap WHERE {qr}" # Returns bl,xpr where bl = True when xpr is for a literal -def build(alist, pt): +def build_r(alist, pt): if pt.op == TokType.OR: conn = "UNION" elif pt.op == TokType.AND: - conn = "INTERSECTION" + conn = "INTERSECT" elif pt.op == TokType.NOT: return True,query_lit(alist, pt.l[0], True) elif pt.op in LitType: @@ -84,16 +85,22 @@ def build(alist, pt): else: raise ParseError - v, r = build(alist, pt.l[0]) + v, r = build_r(alist, pt.l[0]) if not v: - r = f"SELECT card FROM ({r})" + r = f"SELECT DISTINCT card FROM ({r})" for i in pt.l[1:]: - v,exr = build(alist, i) + v,exr = build_r(alist, i) if not v: - exr = f"SELECT card FROM f({exr})" + exr = f"SELECT DISTINCT card FROM f({exr})" r = f"{r} {conn} {exr}" return False,r +def build(l): + lits = [] + _,r = build_r(lits, parse(l)) + return tuple(lits), f"""SELECT DISTINCT name FROM ({r}) + AS tbl INNER JOIN cards ON tbl.card = cards.id""" + def encapsulate(pt, op): if pt.op != op: pt = ParseTree(op, [pt]) diff --git a/underwriter b/underwriter index f54b1fd..63404a8 100755 --- a/underwriter +++ b/underwriter @@ -6,6 +6,7 @@ import sys from datetime import datetime, timezone import base64 from natargs import Arguments +import queryparse def current_time(): return int(datetime.now(timezone.utc).timestamp()) @@ -118,6 +119,13 @@ class Context: self.db.execute("SELECT name FROM tags").fetchall(): print(i) + def query(self, l): + lits,exec = queryparse.build(l) + print(exec) + print(lits) + for (i,) in self.db.execute(exec, lits).fetchall(): + print(i) + def __init__(self, name): if not os.path.isfile(name): self.db = Context.initdb(name) @@ -152,5 +160,6 @@ if __name__ == "__main__": argparse.addarg(["untag"], lambda x:x > 1, ctx.card_remove_tags) argparse.addarg(["list", "tags"], lambda x: x == 0, ctx.list_tags) argparse.addarg(["list", "cards"], lambda x: x == 0, ctx.list_cards) + argparse.addarg(["search"], lambda x: x > 0, ctx.query) argparse.execarg(args) |
