commit de2f1be164337b145649c396d5ef9d387bc608af Author: Damian Johnson atagar@torproject.org Date: Sun Aug 27 11:16:03 2017 -0700
Replace query's path with a parameter argument
Parameterized queries are useful. Allowing folks to specify their own sqlite database really isn't. These are incompatable due to the '*params' syntax sugar, though I might re-introduce path as a '**kwargs' in the future if we develop a need for it. --- stem/manual.py | 22 ++++++++-------------- test/unit/manual.py | 4 +--- 2 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/stem/manual.py b/stem/manual.py index 7dd2be63..9537c740 100644 --- a/stem/manual.py +++ b/stem/manual.py @@ -83,7 +83,7 @@ except ImportError: Category = stem.util.enum.Enum('GENERAL', 'CLIENT', 'RELAY', 'DIRECTORY', 'AUTHORITY', 'HIDDEN_SERVICE', 'TESTING', 'UNKNOWN') GITWEB_MANUAL_URL = 'https://gitweb.torproject.org/tor.git/plain/doc/tor.1.txt' CACHE_PATH = os.path.join(os.path.dirname(__file__), 'cached_tor_manual.sqlite') -DATABASE = {} # read-only sqlite database connections +DATABASE = None # cache database connections
CATEGORY_SECTIONS = OrderedDict(( ('GENERAL OPTIONS', Category.GENERAL), @@ -96,7 +96,7 @@ CATEGORY_SECTIONS = OrderedDict(( ))
-def query(query, path = None): +def query(query, *param): """ Performs the given query on our sqlite manual cache. This database should be treated as being read-only. File permissions generally enforce this, and @@ -105,14 +105,11 @@ def query(query, path = None): .. versionadded:: 1.6.0
:param str query: query to run on the cache - :param str path: cached manual content to read, if not provided this uses - the bundled manual information + :param list param: query parameters
:returns: :class:`sqlite3.Cursor` with the query results
- :raises: - * **sqlite3.OperationalError** if query fails - * **IOError** if a **path** was provided and we were unable to read it + :raises: **sqlite3.OperationalError** if query fails """
# The only reason to explicitly close the sqlite connection is to ensure @@ -124,15 +121,12 @@ def query(query, path = None): # # https://docs.python.org/3/library/sqlite3.html#sqlite3.connect
- if path is None: - path = CACHE_PATH - elif not os.path.exists(path): - raise IOError("%s doesn't exist" % path) + global DATABASE
- if path not in DATABASE: - DATABASE[path] = sqlite3.connect(path) + if DATABASE is None: + DATABASE = sqlite3.connect(CACHE_PATH)
- return DATABASE[path].execute(query) + return DATABASE.execute(query, param)
class ConfigOption(object): diff --git a/test/unit/manual.py b/test/unit/manual.py index 20230e88..b7e0adfc 100644 --- a/test/unit/manual.py +++ b/test/unit/manual.py @@ -105,13 +105,11 @@ def _cached_manual(): class TestManual(unittest.TestCase): def test_query(self): self.assertEqual("If set, this option overrides the default location and file name for Tor's cookie file. (See CookieAuthentication above.)", stem.manual.query('SELECT description FROM torrc WHERE name="CookieAuthFile"').fetchone()[0]) + self.assertEqual("If set, this option overrides the default location and file name for Tor's cookie file. (See CookieAuthentication above.)", stem.manual.query('SELECT description FROM torrc WHERE name=?', 'CookieAuthFile').fetchone()[0])
def test_query_on_failure(self): self.assertRaisesRegexp(sqlite3.OperationalError, 'near "hello": syntax error', stem.manual.query, 'hello world')
- def test_query_with_missing_database(self): - self.assertRaisesRegexp(IOError, "/no/such/path doesn't exist", stem.manual.query, 'SELECT * FROM torrc', '/no/such/path') - def test_has_all_summaries(self): """ Check that we have brief, human readable summaries for all of tor's
tor-commits@lists.torproject.org