Skip to content

Commit 463987c

Browse files
authored
Merge pull request #12 from danlooo/add-query
Add query
2 parents 0f7b3ff + 8979abf commit 463987c

File tree

4 files changed

+99
-22
lines changed

4 files changed

+99
-22
lines changed

pathtraits/access.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def nest_dict(flat_dict, delimiter="/"):
3737
return nested_dict
3838

3939

40-
def get_dict(self, path):
40+
def get_dict(db, path):
4141
"""
4242
Get traits for a path as a Python dictionary
4343
@@ -50,12 +50,12 @@ def get_dict(self, path):
5050

5151
# get traits from path and its parents
5252
dirs_data = []
53-
data = self.get("data", path=abs_path)
53+
data = db.get("data", path=abs_path)
5454
if data:
5555
dirs_data.append(data)
5656
for i in reversed(range(0, len(dirs))):
5757
cur_path = "/".join(dirs[0 : i + 1])
58-
data = self.get("data", path=cur_path)
58+
data = db.get("data", path=cur_path)
5959
if data:
6060
dirs_data.append(data)
6161

@@ -70,6 +70,31 @@ def get_dict(self, path):
7070
return res
7171

7272

73+
def get_paths(db, query_str):
74+
"""
75+
Docstring for get_paths
76+
77+
:param db: Description
78+
:param query_str: Description
79+
"""
80+
query_str = f"SELECT DISTINCT path FROM data where {query_str};"
81+
res = db.execute(query_str, ignore_error=False).fetchall()
82+
res = [x["path"] for x in res]
83+
return res
84+
85+
86+
def get_paths_values(db, query_str):
87+
"""
88+
Docstring for get_paths_values
89+
90+
:param db: Description
91+
:param query_str: Description
92+
"""
93+
query_str = f"SELECT * FROM data where {query_str};"
94+
res = db.execute(query_str, ignore_error=False).fetchall()
95+
return res
96+
97+
7398
def get(path, db_path, verbose):
7499
"""
75100
Docstring for get
@@ -88,3 +113,35 @@ def get(path, db_path, verbose):
88113
else:
89114
logger.error("No traits found for path %s in database %s", path, db_path)
90115
sys.exit(1)
116+
117+
118+
def query(query_str, db_path, show_values):
119+
"""
120+
Docstring for query
121+
122+
:param query_str: Description
123+
:param db_path: Description
124+
"""
125+
db = TraitsDB(db_path)
126+
if show_values:
127+
res = get_paths_values(db, query_str)
128+
if len(res) > 0:
129+
print(yaml.safe_dump(res))
130+
else:
131+
logger.error(
132+
"No paths found for traits matching %s in database %s",
133+
query_str,
134+
db_path,
135+
)
136+
sys.exit(1)
137+
else:
138+
res = get_paths(db, query_str)
139+
if len(res) > 0:
140+
for r in res:
141+
print(r)
142+
else:
143+
logger.error(
144+
"No paths found for traits matching %s in database %s",
145+
query_str,
146+
db_path,
147+
)

pathtraits/cli.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def main():
1919
"""
2020

2121

22-
@main.command(help="Update database once, searches for all directories recursively.")
22+
@main.command()
2323
@click.argument("path", required=True, type=click.Path(exists=True))
2424
@click.option(
2525
"--db-path",
@@ -34,16 +34,11 @@ def main():
3434
def batch(path, db_path, exclude_regex, verbose):
3535
"""
3636
Update database once, searches for all directories recursively.
37-
38-
:param path: path to scan in batch mode recursively
39-
:param db_path: path to the database
40-
:param exclude_regex: exclue file paths matching this regex
41-
:param verbose: enable verbose logging
4237
"""
4338
scan.batch(path, db_path, exclude_regex, verbose)
4439

4540

46-
@main.command(help="Update database continiously, watches for new or changed files.")
41+
@main.command()
4742
@click.argument("path", required=True, type=click.Path(exists=True))
4843
@click.option(
4944
"--db-path",
@@ -54,15 +49,11 @@ def batch(path, db_path, exclude_regex, verbose):
5449
def watch(path, db_path, verbose):
5550
"""
5651
Update database continiously, watches for new or changed files.
57-
58-
:param path: path to watch recursively
59-
:param db_path: path to the database
60-
:param verbose: enable verbose logging
6152
"""
6253
scan.watch(path, db_path, verbose)
6354

6455

65-
@main.command(help="Get traits of a given path")
56+
@main.command()
6657
@click.argument("path", required=True, type=click.Path(exists=True))
6758
@click.option(
6859
"--db-path",
@@ -73,13 +64,29 @@ def watch(path, db_path, verbose):
7364
def get(path, db_path, verbose):
7465
"""
7566
Get traits of a given path
76-
77-
:param path: path to get traits for
78-
:param db_path: path to the database
79-
:param verbose: enable verbose logging
8067
"""
8168
access.get(path, db_path, verbose)
8269

8370

71+
@main.command()
72+
@click.argument("query_str", required=True)
73+
@click.option(
74+
"--db-path",
75+
default=DB_PATH,
76+
type=click.Path(file_okay=True, dir_okay=False),
77+
)
78+
@click.option(
79+
"--show-values", flag_value=True, default=False, help="Also show their trait values"
80+
)
81+
def query(query_str, db_path, show_values):
82+
"""
83+
Get paths of given traits
84+
85+
Enter QUERY_STR in SQLite3 where statement format,
86+
e.g. "[score/REAL]>1" to get all paths having a score >1.
87+
"""
88+
access.query(query_str, db_path, show_values)
89+
90+
8491
if __name__ == "__main__":
8592
main()

pathtraits/db.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import logging
66
import sqlite3
77
import os
8+
import sys
89
from collections.abc import MutableMapping
910
import yaml
1011
from pathtraits.pathpair import PathPair
@@ -104,7 +105,7 @@ def __init__(self, db_path):
104105
self.update_traits()
105106

106107
# pylint: disable=R1710
107-
def execute(self, query):
108+
def execute(self, query, ignore_error=True):
108109
"""
109110
Execute a SQLite query
110111
@@ -114,8 +115,11 @@ def execute(self, query):
114115
try:
115116
res = self.cursor.execute(query)
116117
return res
117-
except sqlite3.DatabaseError:
118-
logger.debug("Ignore failed query %s", query)
118+
except sqlite3.DatabaseError as e:
119+
if ignore_error:
120+
logger.debug("Ignore failed query %s: %s", query, e)
121+
else:
122+
sys.exit(e)
119123

120124
def get(self, table, cols="*", condition=None, **kwargs):
121125
"""

test/test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ def test_data_view(self):
7575
target = 8
7676
self.assertEqual(source, target)
7777

78+
def test_data_query(self):
79+
source = len(pathtraits.access.get_paths(self.db, "[score/REAL] >= 5"))
80+
target = 1
81+
self.assertEqual(source, target)
82+
83+
source = len(pathtraits.access.get_paths(self.db, "TRUE"))
84+
target = 3
85+
self.assertEqual(source, target)
86+
7887

7988
if __name__ == "__main__":
8089
unittest.main()

0 commit comments

Comments
 (0)