From f670bc43ca2b0e97584bf8a0b918abf4c09f1921 Mon Sep 17 00:00:00 2001 From: Ben Schmidt Date: Tue, 27 Oct 2015 18:57:03 -0400 Subject: [PATCH 1/3] actually fail on foreign characters in keys; also, delete some extra code. --- bookwormDB/SQLAPI.py | 51 ++++---------------------------------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/bookwormDB/SQLAPI.py b/bookwormDB/SQLAPI.py index 315a118..1ee9dc3 100644 --- a/bookwormDB/SQLAPI.py +++ b/bookwormDB/SQLAPI.py @@ -75,21 +75,17 @@ def all_keys(input): Iterates down on list and dict structures to search for more dicts with keys. """ values = [] - print "yo" if isinstance(input,dict): - print "dict" values = input.keys() for key in input.keys(): - print values values = values + all_keys(input[key]) - print "yoo" if isinstance(input,list): for value in input: - values.append(all_keys(value)) - print "yooo" + valleys = all_keys(value) + for val in valleys: + values.append(val) return values - # The basic object here is a 'userquery:' it takes dictionary as input, as defined in the API, and returns a value # via the 'execute' function whose behavior # depends on the mode that is passed to it. @@ -97,52 +93,13 @@ def all_keys(input): # The "Search_limits" array in the passed dictionary determines how many elements it returns; this lets multiple queries be bundled together. # Most functions describe a subquery that might be combined into one big query in various ways. -class userqueries: - #This is a set of userqueries that are bound together; each element in search limits is iterated over, and we're done. - #currently used for various different groups sent in a bundle (multiple lines on a Bookworm chart). - #A sufficiently sophisticated 'group by' search might make this unnecessary. - #But until that day, it's useful to be able to return lists of elements, which happens in here. - - def __init__(self,outside_dictionary = {"counttype":["Percentage_of_Books"],"search_limits":[{"word":["polka dot"],"LCSH":["Fiction"]}]},db = None): - fail_if_nonword_characters_in_columns(outside_dictionary) - try: - self.database = outside_dictionary.setdefault('database', 'default') - prefs = general_prefs[self.database] - except KeyError: #If it's not in the option, use some default preferences and search on localhost. This will work in most cases here on out. - prefs = general_prefs['default'] - prefs['database'] = self.database - self.prefs = prefs - - self.wordsheap = prefs['fastword'] - self.words = prefs['fullword'] - if 'search_limits' not in outside_dictionary.keys(): - outside_dictionary['search_limits'] = [{}] - #coerce one-element dictionaries to an array. - if isinstance(outside_dictionary['search_limits'],dict): - #(allowing passing of just single dictionaries instead of arrays) - outside_dictionary['search_limits'] = [outside_dictionary['search_limits']] - self.returnval = [] - self.queryInstances = [] - db = DbConnect(prefs) - databaseScheme = databaseSchema(db) - for limits in outside_dictionary['search_limits']: - mylimits = copy.deepcopy(outside_dictionary) - mylimits['search_limits'] = limits - localQuery = userquery(mylimits,db=db,databaseScheme=databaseScheme) - self.queryInstances.append(localQuery) - self.returnval.append(localQuery.execute()) - - def execute(self): - - return self.returnval - - class userquery: """ The base class for a bookworm search. """ def __init__(self,outside_dictionary = {"counttype":["Percentage_of_Books"],"search_limits":{"word":["polka dot"],"LCSH":["Fiction"]}},db=None,databaseScheme=None): #Certain constructions require a DB connection already available, so we just start it here, or use the one passed to it. + fail_if_nonword_characters_in_columns(outside_dictionary) try: self.prefs = general_prefs[outside_dictionary['database']] except KeyError: From 3d3ae9ec9631d59b605fa7a96898d77f4b061f01 Mon Sep 17 00:00:00 2001 From: Ben Schmidt Date: Wed, 28 Oct 2015 14:24:51 -0400 Subject: [PATCH 2/3] Incorporating better string interpolation from Peter's commit --- bookwormDB/SQLAPI.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bookwormDB/SQLAPI.py b/bookwormDB/SQLAPI.py index 1ee9dc3..d3ee151 100644 --- a/bookwormDB/SQLAPI.py +++ b/bookwormDB/SQLAPI.py @@ -481,13 +481,13 @@ def make_wordwheres(self): from nltk import PorterStemmer searchingFor = PorterStemmer().stem_word(searchingFor) if self.word_field=="case_insensitive" or self.word_field=="Case_Insensitive": + # That's a little joke. Get it? searchingFor = searchingFor.lower() - - selectString = "SELECT wordid FROM wordsheap WHERE %s = '%s'" %(self.word_field,MySQLdb.escape_string(searchingFor)) + selectString = "SELECT wordid FROM wordsheap WHERE %s = %%s" % self.word_field logging.debug(selectString) cursor = self.db.cursor; - cursor.execute(selectString) + cursor.execute(selectString,(searchingFor)) for row in cursor.fetchall(): wordid = row[0] try: From 262910a6abd5c335d47695ecf8d7e125310963ae Mon Sep 17 00:00:00 2001 From: Ben Schmidt Date: Thu, 29 Oct 2015 10:24:17 -0400 Subject: [PATCH 3/3] numbers are allowed in column names --- bookwormDB/SQLAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwormDB/SQLAPI.py b/bookwormDB/SQLAPI.py index d3ee151..2a3537a 100644 --- a/bookwormDB/SQLAPI.py +++ b/bookwormDB/SQLAPI.py @@ -66,7 +66,7 @@ def __init__(self,prefs=general_prefs['default'],database=None,host="localhost") def fail_if_nonword_characters_in_columns(input): keys = all_keys(input) for key in keys: - if re.search(r"[^A-Za-z_$*]",key): + if re.search(r"[^A-Za-z_$*0-9]",key): raise def all_keys(input):