def mana_where(operator: str, term: str) -> str: term = term.upper() try: symbols = mana.parse( term ) # Uppercasing input means you can't search for 1/2 or 1/2 white mana but w should match W. symbols = ['{{{symbol}}}'.format(symbol=symbol) for symbol in symbols] except mana.InvalidManaCostException: symbols = [term] if operator == ':': d = collections.Counter( symbols ) # Group identical symbols so that UU checks for {U}{U} not just {U} twice. clause = ' AND '.join( 'mana_cost LIKE {symbol}'.format(symbol=sqllikeescape(symbol * n)) for symbol, n in d.items()) elif operator == '=': joined = ''.join('{symbol}'.format(symbol=symbol) for symbol in symbols) clause = "mana_cost = '{joined}'".format(joined=joined) else: raise InvalidTokenException( 'mana expects `:` or `=` not `{operator}`. Did you want cmc?'. format(operator=operator)) return '({clause})'.format(clause=clause)
def text_where(column: str, term: str) -> str: q = term if column.endswith('name'): q = card.unaccent(q) if column == 'text': column = 'oracle_text' escaped = sqllikeescape(q) if column == 'oracle_text' and '~' in escaped: parts = [ "'{text}'".format(text=text) for text in escaped.strip("'").split('~') ] escaped = concat(intersperse(parts, 'name')) return '({column} LIKE {q})'.format(column=column, q=escaped)
def text_where(column, term): q = term if column.endswith('name'): column = column.replace('name', 'name_ascii') q = card.unaccent(q) if column == 'text': column = 'search_text' escaped = sqllikeescape(q) if column == 'search_text' and '~' in escaped: parts = [ "'{text}'".format(text=text) for text in escaped.strip("'").split('~') ] escaped = db().concat(intersperse(parts, 'name')) return '({column} LIKE {q})'.format(column=column, q=escaped)
def subtable_where(subtable, value, operator=None): # Specialcase colorless because it has no entry in the color table. if (subtable == 'color' or subtable == 'color_identity') and value == 'c': return '(c.id NOT IN (SELECT card_id FROM card_{subtable}))'.format( subtable=subtable) v = value_lookup(subtable, value) if str(v).isdigit(): column = '{subtable}_id'.format(subtable=subtable).replace( 'color_identity_id', 'color_id') operator = '=' if not operator else operator else: column = subtable v = sqllikeescape(v) operator = 'LIKE' if not operator else operator return '(c.id IN (SELECT card_id FROM card_{subtable} WHERE {column} {operator} {value}))'.format( subtable=subtable, column=column, operator=operator, value=v)
def set_where(name: str) -> str: return '(c.id IN (SELECT card_id FROM printing WHERE set_id IN (SELECT id FROM `set` WHERE name LIKE {name_fuzzy} OR code = {name})))'.format( name_fuzzy=sqllikeescape(name), name=sqlescape(name))
def test_sqllikeescape(): assert sqllikeescape("100%") == "'%%100\\%%%%'"