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.

51 lines
1.8 KiB

  1. import shlex
  2. import re
  3. import csv
  4. import sys
  5. csv.field_size_limit(2**31-1)
  6. dict_params = re.compile(r':([^\ \,\.\\\(\)\=]+)')
  7. list_params = re.compile(r'\?')
  8. class AndroidSQLConn:
  9. def __init__(self,device,filepath,use_root=True):
  10. self.device = device
  11. self.filepath = filepath
  12. self.root = use_root
  13. def _quote_param_(param):
  14. if isinstance(param,str):
  15. return "'{}'".format(param.replace("'","''"))
  16. elif isinstance(param,bool):
  17. return '1' if param else '0'
  18. elif param is None:
  19. return 'NULL'
  20. else:
  21. return str(param)
  22. def _sub_params_(SQL,params):
  23. params = iter(params)
  24. try:
  25. return list_params.sub(lambda match: AndroidSQLConn._quote_param_(next(params)),SQL)
  26. except StopIteration:
  27. raise TypeError("Not enough parameters")
  28. def _sub_params_dict_(SQL,params):
  29. try:
  30. return dict_params.sub(lambda match: AndroidSQLConn._quote_param_(params[match.group(1)]),SQL)
  31. except KeyError:
  32. raise TypeError("Parameter specified but not in mapping")
  33. def execute(self,SQL,params = None):
  34. if params:
  35. if isinstance(params,dict):
  36. SQL = AndroidSQLConn._sub_params_dict_(SQL,params)
  37. else:
  38. SQL = AndroidSQLConn._sub_params_(SQL,params)
  39. SQL = shlex.quote(SQL)
  40. if self.root:
  41. shell = self.device.sudo
  42. else:
  43. shell = self.device.shell
  44. out = shell('sqlite3','-header','-csv',shlex.quote(self.filepath),SQL,output="out")
  45. if out:
  46. return csv.DictReader(out.splitlines())
  47. if __name__ == "__main__":
  48. print(AndroidSQLConn._sub_params_("SELECT * FROM table WHERE name=?,age=?;",["boby;DROP TABLE table",1]))