Advertisement
Guest User

Untitled

a guest
Mar 8th, 2016
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1. from weakref import WeakSet
  2. from collections import OrderedDict, namedtuple
  3. from contextlib import closing
  4. from datetime import date
  5.  
  6. from py4j.java_gateway import JavaGateway, JavaObject
  7.  
  8.  
  9. def python_date(java_date):
  10. """Converts a java.util.Date to a Python datetime.date object."""
  11. return date.fromtimestamp(java_date.getTime() / 1000) if java_date is not None else None
  12.  
  13.  
  14. class JDBCConnection:
  15. def __init__(self, gateway: JavaGateway, url: str, username: str, password: str):
  16. self.url = url
  17. self.username = username
  18. self.password = password
  19. self.gateway = gateway
  20. self.conn = None
  21. self.queries = WeakSet()
  22.  
  23. def query(self, query: str, params=()) -> 'JDBCQuery':
  24. """
  25. Executes a SELECT type SQL query.
  26.  
  27. :param query: the SQL to execute
  28. :param params: parameters for the query
  29. :return: the resulting query object
  30.  
  31. """
  32. stmt = self.conn.prepareStatement(query)
  33. for i, param in enumerate(params, 1):
  34. stmt.setObject(i, param)
  35.  
  36. rs = stmt.executeQuery()
  37. query = JDBCQuery(stmt, rs)
  38. self.queries.add(query)
  39. return query
  40.  
  41. def execute(self, query: str, params=()):
  42. """
  43. Executes an SQL query.
  44.  
  45. The query should be a modifying query (INSERT, UPDATE, DELETE).
  46. For SELECT queries, :meth:`query` should be used instead.
  47.  
  48. :param query: the SQL to execute
  49. :param params: an iterable of same-length tuples
  50.  
  51. """
  52. stmt = self.conn.prepareStatement(query)
  53. with closing(stmt):
  54. for param_tuple in params:
  55. for i, value in enumerate(param_tuple, 1):
  56. stmt.setObject(i, value)
  57.  
  58. stmt.execute()
  59.  
  60. def open(self):
  61. self.conn = self.gateway.jvm.java.sql.DriverManager.getConnection(self.url, self.username,
  62. self.password)
  63.  
  64. def close(self):
  65. if self.conn and not self.conn.isClosed():
  66. for query in self.queries:
  67. query.close()
  68.  
  69. self.conn.close()
  70. self.conn = None
  71.  
  72. def __enter__(self):
  73. self.open()
  74. return self
  75.  
  76. def __exit__(self, exc_type, exc_val, exc_tb):
  77. self.close()
  78.  
  79. def __del__(self):
  80. self.close()
  81.  
  82.  
  83. Column = namedtuple('Column', ['name', 'converter'])
  84.  
  85.  
  86. class JDBCQuery:
  87. CONVERTERS = {
  88. 'date': python_date
  89. }
  90.  
  91. def __init__(self, statement: JavaObject, result_set: JavaObject):
  92. self.statement = statement
  93. self.result_set = result_set
  94.  
  95. self.columns = []
  96. metadata = result_set.getMetaData()
  97. for i in range(metadata.getColumnCount()):
  98. column_name = metadata.getColumnName(i + 1).lower()
  99. column_type = metadata.getColumnTypeName(i + 1).lower()
  100. column = Column(column_name, self.CONVERTERS.get(column_type))
  101. self.columns.append(column)
  102.  
  103. def close(self):
  104. if self.result_set and not self.result_set.isClosed():
  105. self.result_set.close()
  106. self.result_set = None
  107. if self.statement:
  108. self.statement.close()
  109. self.statement = None
  110.  
  111. def __iter__(self):
  112. with closing(self):
  113. while self.result_set.next():
  114. row = OrderedDict()
  115. for i, column in enumerate(self.columns, 1):
  116. value = self.result_set.getObject(i)
  117. value = column.converter(value) if column.converter else value
  118. row[column.name] = value
  119.  
  120. yield row
  121.  
  122. def __del__(self):
  123. self.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement