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.

47 lines
1.6 KiB

  1. import shlex
  2. import re
  3. import csv
  4. import sys
  5. csv.field_size_limit(2**31-1)
  6. param_str = re.compile(r'(?<=\()[ ,\?]+(?=\))')
  7. validator = re.compile(r'^\?(?: *\, *\?)*$')
  8. param_sep = re.compile(r' *\, *')
  9. class AndroidSQLConn:
  10. def __init__(self,device,filepath,use_root=True):
  11. self.device = device
  12. self.filepath = filepath
  13. self.root = use_root
  14. def _quote_param_(param):
  15. if isinstance(param,str):
  16. return "'{}'".format(param.replace("'","''"))
  17. elif isinstance(param,bool):
  18. return '1' if param else '0'
  19. elif param is None:
  20. return 'NULL'
  21. else:
  22. return str(param)
  23. def _sub_params_(SQL,params):
  24. p_string = param_str.search(SQL).group(0)
  25. if not validator.match(p_string):
  26. raise ValueError('Invalid substitution')
  27. n_params = len(param_sep.split(p_string))
  28. if len(params) < n_params:
  29. raise ValueError('Not enough parameters supplied')
  30. new_str = ','.join(map(
  31. AndroidSQLConn._quote_param_,params[:n_params]
  32. ))
  33. print(*map(repr,(new_str,SQL)))
  34. return param_str.sub(re.escape(new_str),SQL,1)
  35. def execute(self,SQL,params = None):
  36. if params:
  37. SQL = AndroidSQLConn._sub_params_(SQL,params)
  38. SQL = shlex.quote(SQL)
  39. if self.root:
  40. shell = self.device.sudo
  41. else:
  42. shell = self.device.shell
  43. out = shell('sqlite3','-header','-csv',shlex.quote(self.filepath),SQL,output="out")
  44. if out:
  45. return csv.DictReader(out.splitlines())