aboutsummaryrefslogtreecommitdiffstats
path: root/queryparse.py
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2021-07-26 22:12:29 -0400
committerGravatar - 2021-07-26 22:56:50 -0400
commit9fda89f559c217d825ce1c94c5942529fa314d9d (patch)
treeaf1be9f767b737e75180f58b3c2da253f0336a4c /queryparse.py
parentnatargs: 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.
Diffstat (limited to 'queryparse.py')
-rw-r--r--queryparse.py31
1 files changed, 19 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])