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
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]))
|