You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.8 KiB

import shlex
import re
import csv
import sys
csv.field_size_limit(2**31-1)
dict_params = re.compile(r':([^\ \,\.\\\(\)\=]+)')
list_params = re.compile(r'\?')
class AndroidSQLConn:
def __init__(self, device, filepath, use_root=True):
self.device = device
self.filepath = filepath
self.root = use_root
def _quote_param_(param):
if isinstance(param, str):
return "'{}'".format(param.replace("'", "''"))
elif isinstance(param, bool):
return '1' if param else '0'
elif param is None:
return 'NULL'
else:
return str(param)
def _sub_params_(SQL, params):
params = iter(params)
try:
return list_params.sub(lambda match: AndroidSQLConn._quote_param_(next(params)), SQL)
except StopIteration:
raise TypeError("Not enough parameters")
def _sub_params_dict_(SQL, params):
try:
return dict_params.sub(lambda match: AndroidSQLConn._quote_param_(params[match.group(1)]), SQL)
except KeyError:
raise TypeError("Parameter specified but not in mapping")
def execute(self, SQL, params=None):
if params:
if isinstance(params, dict):
SQL = AndroidSQLConn._sub_params_dict_(SQL, params)
else:
SQL = AndroidSQLConn._sub_params_(SQL, params)
SQL = shlex.quote(SQL)
if self.root:
shell = self.device.sudo
else:
shell = self.device.shell
out = shell('sqlite3', '-header', '-csv',
shlex.quote(self.filepath), SQL, output="out")
if out:
return csv.DictReader(out.splitlines())
if __name__ == "__main__":
print(AndroidSQLConn._sub_params_(
"SELECT * FROM table WHERE name=?,age=?;", ["boby;DROP TABLE table", 1]))