QtSqlDB.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. """
  2. /***************************************************************************
  3. Name : QtSqlDB
  4. Description : DB API 2.0 interface for QtSql
  5. Date : June 6, 2015
  6. Copyright : (C) 2015 by Jürgen E. Fischer
  7. email : jef at norbit dot de
  8. ***************************************************************************/
  9. /***************************************************************************
  10. * *
  11. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. ***************************************************************************/
  17. """
  18. from qgis.PyQt.QtCore import QVariant, QDate, QTime, QDateTime, QByteArray
  19. from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery, QSqlField
  20. paramstyle = "qmark"
  21. threadsafety = 1
  22. apilevel = "2.0"
  23. import time
  24. import datetime
  25. def Date(year, month, day):
  26. return datetime.date(year, month, day)
  27. def Time(hour, minute, second):
  28. return datetime.time(hour, minute, second)
  29. def Timestamp(year, month, day, hour, minute, second):
  30. return datetime.datetime(year, month, day, hour, minute, second)
  31. def DateFromTicks(ticks):
  32. return Date(*time.localtime(ticks)[:3])
  33. def TimeFromTicks(ticks):
  34. return Time(*time.localtime(ticks)[3:6])
  35. def TimestampFromTicks(ticks):
  36. return Timestamp(*time.localtime(ticks)[:6])
  37. class ConnectionError(Exception):
  38. def __init__(self, *args, **kwargs):
  39. super().__init__(*args, **kwargs)
  40. class ExecError(Exception):
  41. def __init__(self, *args, **kwargs):
  42. super().__init__(*args, **kwargs)
  43. class QtSqlDBCursor:
  44. def __init__(self, conn):
  45. self.qry = QSqlQuery(conn)
  46. self.description = None
  47. self.rowcount = -1
  48. self.arraysize = 1
  49. def close(self):
  50. self.qry.finish()
  51. def execute(self, operation, parameters=[]):
  52. if len(parameters) == 0:
  53. if not self.qry.exec_(operation):
  54. raise ExecError(self.qry.lastError().databaseText())
  55. else:
  56. if not self.qry.prepare(operation):
  57. raise ExecError(self.qry.lastError().databaseText())
  58. for i in range(len(parameters)):
  59. self.qry.bindValue(i, parameters[i])
  60. if not self.qry.exec_():
  61. raise ExecError(self.qry.lastError().databaseText())
  62. self.rowcount = self.qry.size()
  63. self.description = []
  64. for c in range(self.qry.record().count()):
  65. f = self.qry.record().field(c)
  66. if f.type() == QVariant.Date:
  67. t = Date
  68. elif f.type() == QVariant.Time:
  69. t = Time
  70. elif f.type() == QVariant.DateTime:
  71. t = Timestamp
  72. elif f.type() == QVariant.Double:
  73. t = float
  74. elif f.type() == QVariant.Int:
  75. t = int
  76. elif f.type() == QVariant.String:
  77. t = str
  78. elif f.type() == QVariant.ByteArray:
  79. t = str
  80. else:
  81. continue
  82. self.description.append([
  83. f.name(), # name
  84. t, # type_code
  85. f.length(), # display_size
  86. f.length(), # internal_size
  87. f.precision(), # precision
  88. None, # scale
  89. f.requiredStatus() != QSqlField.Required # null_ok
  90. ])
  91. def executemany(self, operation, seq_of_parameters):
  92. if len(seq_of_parameters) == 0:
  93. return
  94. if not self.qry.prepare(operation):
  95. raise ExecError(self.qry.lastError().databaseText())
  96. for r in seq_of_parameters:
  97. for i in range(len(r)):
  98. self.qry.bindValue(i, r[i])
  99. if not self.qry.exec_():
  100. raise ExecError(self.qry.lastError().databaseText())
  101. def scroll(self, row):
  102. return self.qry.seek(row)
  103. def fetchone(self):
  104. if not self.qry.next():
  105. return None
  106. row = []
  107. for i in range(len(self.description)):
  108. value = self.qry.value(i)
  109. if (isinstance(value, QDate) or
  110. isinstance(value, QTime) or
  111. isinstance(value, QDateTime)):
  112. value = value.toString()
  113. elif isinstance(value, QByteArray):
  114. value = "GEOMETRY"
  115. # value = value.toHex()
  116. row.append(value)
  117. return row
  118. def fetchmany(self, size=10):
  119. rows = []
  120. while len(rows) < size:
  121. row = self.fetchone()
  122. if row is None:
  123. break
  124. rows.append(row)
  125. return rows
  126. def fetchall(self):
  127. rows = []
  128. while True:
  129. row = self.fetchone()
  130. if row is None:
  131. break
  132. rows.append(row)
  133. return rows
  134. def setinputsize(self, sizes):
  135. raise ExecError("nyi")
  136. def setoutputsize(self, size, column=None):
  137. raise ExecError("nyi")
  138. class QtSqlDBConnection:
  139. connections = 0
  140. def __init__(self, driver, dbname, user, passwd):
  141. self.conn = QSqlDatabase.addDatabase(
  142. driver, "qtsql_%d" % QtSqlDBConnection.connections)
  143. QtSqlDBConnection.connections += 1
  144. self.conn.setDatabaseName(dbname)
  145. self.conn.setUserName(user)
  146. self.conn.setPassword(passwd)
  147. if not self.conn.open():
  148. raise ConnectionError(self.conn.lastError().databaseText())
  149. def close(self):
  150. self.conn.close()
  151. def commit(self):
  152. self.conn.commit()
  153. def rollback(self):
  154. self.conn.rollback()
  155. def cursor(self):
  156. return QtSqlDBCursor(self.conn)
  157. def connect(driver, dbname, user, passwd):
  158. return QtSqlDBConnection(driver, dbname, user, passwd)