Files
Android-pyApi/android_pyapi/java/sql.py
T
shuiyu1123 a51854455b feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等)
- java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等)
- javax/ 4个模块 (net/crypto/security/sql)
- org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http)
- dalvik/ 1个模块 (system)
- ~3053个类/接口,方法签名完全对齐Android SDK
- 桌面跨平台运行 (Windows/macOS/Linux)
- 修复所有导入错误和Python关键字冲突
2026-06-24 14:15:56 +00:00

2242 lines
55 KiB
Python

"""
Java SQL standard library APIs implemented in Python.
java.sql package - Connection, Statement, ResultSet, Types, etc.
"""
from __future__ import annotations
from .._core import Stub, AndroidOnlyError
from .lang import RuntimeException, Exception as _JavaException
import datetime as _datetime
import typing as _typing
__all__ = [
"Connection", "Statement", "PreparedStatement", "CallableStatement",
"ResultSet", "ResultSetMetaData", "DatabaseMetaData",
"Driver", "DriverManager", "DriverPropertyInfo",
"SQLException", "SQLWarning", "SQLData", "SQLInput", "SQLOutput",
"BatchUpdateException", "DataTruncation",
"Date", "Time", "Timestamp", "Savepoint",
"Blob", "Clob", "NClob", "Ref", "RowId", "Struct", "SQLXML", "Array",
"Types", "JDBCType", "Wrapper",
"FETCH_FORWARD", "FETCH_REVERSE", "FETCH_UNKNOWN",
"TYPE_FORWARD_ONLY", "TYPE_SCROLL_INSENSITIVE", "TYPE_SCROLL_SENSITIVE",
"HOLD_CURSORS_OVER_COMMIT", "CLOSE_CURSORS_AT_COMMIT",
"CLOSE_ALL_RESULTS", "KEEP_CURRENT_RESULT",
"NO_GENERATED_KEYS", "RETURN_GENERATED_KEYS",
"CLOSE_CURRENT_RESULT",
]
# ============================================================
# Constants
# ============================================================
FETCH_FORWARD = 1000
FETCH_REVERSE = 1001
FETCH_UNKNOWN = 1002
TYPE_FORWARD_ONLY = 1003
TYPE_SCROLL_INSENSITIVE = 1004
TYPE_SCROLL_SENSITIVE = 1005
HOLD_CURSORS_OVER_COMMIT = 1
CLOSE_CURSORS_AT_COMMIT = 2
CLOSE_ALL_RESULTS = 1
KEEP_CURRENT_RESULT = 2
CLOSE_CURRENT_RESULT = 3
NO_GENERATED_KEYS = 1
RETURN_GENERATED_KEYS = 2
# ============================================================
# SQLException hierarchy
# ============================================================
class SQLException(_JavaException):
"""java.sql.SQLException"""
def __init__(self, reason=None, sql_state=None, vendor_code=0, cause=None):
msg = reason or ""
super().__init__(msg)
self._reason = reason
self._sql_state = sql_state
self._vendor_code = vendor_code
self._cause = cause
self._next_exception = None
def getMessage(self):
return self._reason or ""
def getSQLState(self):
return self._sql_state
def getErrorCode(self):
return self._vendor_code
def getNextException(self):
return self._next_exception
def setNextException(self, ex):
self._next_exception = ex
def getCause(self):
return self._cause
class SQLWarning(SQLException):
"""java.sql.SQLWarning"""
def __init__(self, reason=None, sql_state=None, vendor_code=0):
super().__init__(reason, sql_state, vendor_code)
self._next_warning = None
def getNextWarning(self):
return self._next_warning
def setNextWarning(self, warning):
self._next_warning = warning
class BatchUpdateException(SQLException):
"""java.sql.BatchUpdateException"""
def __init__(self, reason=None, sql_state=None, vendor_code=0,
update_counts=None, cause=None):
super().__init__(reason, sql_state, vendor_code, cause)
self._update_counts = update_counts or []
def getUpdateCounts(self):
return self._update_counts
def getLargeUpdateCounts(self):
return [int(c) for c in self._update_counts]
class DataTruncation(SQLWarning):
"""java.sql.DataTruncation"""
def __init__(self, index, parameter, read, data_size, transfer_size):
super().__init__("Data truncation")
self._index = index
self._parameter = parameter
self._read = read
self._data_size = data_size
self._transfer_size = transfer_size
def getIndex(self):
return self._index
def getParameter(self):
return self._parameter
def getRead(self):
return self._read
def getDataSize(self):
return self._data_size
def getTransferSize(self):
return self._transfer_size
# ============================================================
# Wrapper
# ============================================================
class Wrapper(Stub):
"""java.sql.Wrapper"""
def unwrap(self, iface):
if iface is None:
raise SQLException("iface is null")
return self
def isWrapperFor(self, iface):
return iface is not None and isinstance(self, iface)
# ============================================================
# Types Constants
# ============================================================
class Types:
"""java.sql.Types"""
ARRAY = 2003
BIGINT = -5
BINARY = -2
BIT = -7
BLOB = 2004
BOOLEAN = 16
CHAR = 1
CLOB = 2005
DATALINK = 70
DATE = 91
DECIMAL = 3
DISTINCT = 2001
DOUBLE = 8
FLOAT = 6
INTEGER = 4
JAVA_OBJECT = 2000
LONGNVARCHAR = -16
LONGVARBINARY = -4
LONGVARCHAR = -1
NCHAR = -15
NCLOB = 2011
NULL = 0
NUMERIC = 2
NVARCHAR = -9
OTHER = 1111
REAL = 7
REF = 2006
REF_CURSOR = 2012
ROWID = -8
SMALLINT = 5
SQLXML = 2009
STRUCT = 2002
TIME = 92
TIMESTAMP = 93
TINYINT = -6
VARBINARY = -3
VARCHAR = 12
class JDBCType(Stub):
"""java.sql.JDBCType"""
_type_map = {}
def __init__(self, vendor_type_number):
super().__init__()
self._vendor_type_number = vendor_type_number
def getVendorTypeNumber(self):
return self._vendor_type_number
def getName(self):
for name, val in vars(Types).items():
if isinstance(val, int) and val == self._vendor_type_number:
return name
return "UNKNOWN"
@staticmethod
def valueOf(name):
val = getattr(Types, name, None)
if val is None:
raise IllegalArgumentException(f"No JDBC type: {name}")
return JDBCType(val)
@staticmethod
def values():
return [JDBCType(v) for v in set(
v for v in vars(Types).values() if isinstance(v, int)
)]
# ============================================================
# Date / Time / Timestamp
# ============================================================
class Date(_datetime.date):
"""java.sql.Date"""
def __init__(self, *args):
if len(args) == 1:
ms = args[0]
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.year, dt.month, dt.day)
elif len(args) == 3:
super().__init__(args[0], args[1], args[2])
else:
super().__init__()
def getTime(self):
dt = _datetime.datetime.combine(self, _datetime.time.min)
return int(dt.timestamp() * 1000)
def setTime(self, ms):
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.year, dt.month, dt.day)
def toString(self):
return self.strftime("%Y-%m-%d")
@staticmethod
def valueOf(s):
parts = s.split("-")
return Date(int(parts[0]), int(parts[1]), int(parts[2]))
class Time(_datetime.time):
"""java.sql.Time"""
def __init__(self, *args):
if len(args) == 1:
ms = args[0]
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.hour, dt.minute, dt.second)
elif len(args) == 3:
super().__init__(args[0], args[1], args[2])
else:
super().__init__()
def getTime(self):
dt = _datetime.datetime.combine(_datetime.date.today(), self)
return int(dt.timestamp() * 1000)
def setTime(self, ms):
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.hour, dt.minute, dt.second)
def toString(self):
return self.strftime("%H:%M:%S")
@staticmethod
def valueOf(s):
parts = s.split(":")
return Time(int(parts[0]), int(parts[1]), int(parts[2]))
class Timestamp(_datetime.datetime):
"""java.sql.Timestamp"""
def __init__(self, *args):
if len(args) == 1:
ms = args[0]
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second, dt.microsecond)
self._nanos = (ms % 1000) * 1000000
else:
super().__init__(*args)
self._nanos = 0
def getTime(self):
return int(self.timestamp() * 1000)
def setTime(self, ms):
dt = _datetime.datetime.fromtimestamp(ms / 1000.0)
super().__init__(dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second, dt.microsecond)
self._nanos = (ms % 1000) * 1000000
def getNanos(self):
return self._nanos
def setNanos(self, n):
self._nanos = n
def toString(self):
return self.strftime("%Y-%m-%d %H:%M:%S")
@staticmethod
def valueOf(s):
parts = s.split(" ")
date_part = parts[0].split("-")
time_part = parts[1].split(":")
return Timestamp(int(date_part[0]), int(date_part[1]), int(date_part[2]),
int(time_part[0]), int(time_part[1]), int(time_part[2]))
# ============================================================
# Savepoint
# ============================================================
class Savepoint(Stub):
"""java.sql.Savepoint"""
def __init__(self, name=None):
super().__init__()
self._savepoint_id = id(self)
self._savepoint_name = name
def getSavepointId(self):
if self._savepoint_name is not None:
raise SQLException("Named savepoint")
return self._savepoint_id
def getSavepointName(self):
if self._savepoint_name is None:
raise SQLException("Unnamed savepoint")
return self._savepoint_name
# ============================================================
# Blob / Clob / NClob / Ref / RowId / Struct / SQLXML / Array
# ============================================================
class Blob(Stub):
"""java.sql.Blob"""
def __init__(self, data=b""):
super().__init__()
self._data = bytearray(data)
self._length = len(data)
def length(self):
return self._length
def getBytes(self, pos, length):
start = pos - 1
return bytes(self._data[start:start + length])
def setBytes(self, pos, bytes_data, offset=0, length=None):
start = pos - 1
if length is None:
length = len(bytes_data) - offset
self._data[start:start + length] = bytearray(bytes_data[offset:offset + length])
return length
def position(self, pattern, start):
return -1
def truncate(self, length):
self._data = self._data[:length]
self._length = length
def free(self):
self._data = bytearray()
self._length = 0
def getBinaryStream(self, pos=None, length=None):
import io
return io.BytesIO(bytes(self._data))
class Clob(Stub):
"""java.sql.Clob"""
def __init__(self, data=""):
super().__init__()
self._data = data
self._length = len(data)
def length(self):
return self._length
def getSubString(self, pos, length):
start = pos - 1
return self._data[start:start + length]
def setString(self, pos, val, offset=0, length=None):
start = pos - 1
if length is None:
length = len(val) - offset
self._data = self._data[:start] + val[offset:offset + length] + self._data[start + length:]
return length
def position(self, search_str, start):
return self._data.find(search_str, start - 1)
def truncate(self, length):
self._data = self._data[:length]
self._length = length
def free(self):
self._data = ""
self._length = 0
def getAsciiStream(self):
import io
return io.BytesIO(self._data.encode())
def getCharacterStream(self, pos=None, length=None):
import io
if pos is not None and length is not None:
return io.StringIO(self._data[pos - 1:pos - 1 + length])
return io.StringIO(self._data)
def setAsciiStream(self, pos, stream, length=None):
data = stream.read() if length is None else stream.read(length)
if isinstance(data, bytes):
data = data.decode()
self._data = self._data[:pos - 1] + data + self._data[pos - 1 + len(data):]
class NClob(Clob):
"""java.sql.NClob"""
pass
class Ref(Stub):
"""java.sql.Ref"""
def __init__(self, base_type_name=None, obj=None):
super().__init__()
self._base_type_name = base_type_name
self._object = obj
def getBaseTypeName(self):
return self._base_type_name
def getObject(self, type_map=None):
return self._object
def setObject(self, obj):
self._object = obj
class RowId(Stub):
"""java.sql.RowId"""
def __init__(self, data=b""):
super().__init__()
self._data = bytes(data)
def getBytes(self):
return self._data
def toString(self):
return self._data.hex()
def equals(self, other):
if not isinstance(other, RowId):
return False
return self._data == other._data
def hashCode(self):
return hash(self._data)
class Struct(Stub):
"""java.sql.Struct"""
def __init__(self, sql_type_name, attributes):
super().__init__()
self._sql_type_name = sql_type_name
self._attributes = list(attributes)
def getSQLTypeName(self):
return self._sql_type_name
def getAttributes(self, type_map=None):
return self._attributes
class SQLXML(Stub):
"""java.sql.SQLXML"""
def __init__(self, xml_string=""):
super().__init__()
self._xml = xml_string
def getString(self):
return self._xml
def setString(self, value):
self._xml = value
def free(self):
self._xml = ""
def getBinaryStream(self):
import io
return io.BytesIO(self._xml.encode())
def setBinaryStream(self):
import io
buf = io.BytesIO()
return buf
def getCharacterStream(self):
import io
return io.StringIO(self._xml)
def setCharacterStream(self):
import io
buf = io.StringIO()
return buf
def getSource(self, source_class=None):
return None
def getResult(self, result_class=None):
return None
class Array(Stub):
"""java.sql.Array"""
def __init__(self, type_name=None, elements=None):
super().__init__()
self._type_name = type_name
self._elements = list(elements) if elements else []
def getBaseTypeName(self):
return self._type_name or "VARCHAR"
def getBaseType(self):
return Types.VARCHAR
def getArray(self, index=None, count=None):
if index is None:
return self._elements
start = index - 1
if count is None:
return self._elements[start:]
return self._elements[start:start + count]
def getResultSet(self, index=None, count=None):
raise SQLException("Not implemented")
# ============================================================
# SQLData / SQLInput / SQLOutput
# ============================================================
class SQLData(Stub):
"""java.sql.SQLData"""
def getSQLTypeName(self):
raise SQLException("Not implemented")
def readSQL(self, stream, type_name):
pass
def writeSQL(self, stream):
pass
class SQLInput(Stub):
"""java.sql.SQLInput"""
def __init__(self, data=None):
super().__init__()
self._data = list(data) if data else []
self._pos = 0
def readString(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return str(val) if val is not None else None
def readBoolean(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return bool(val)
def readByte(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return int(val) if val is not None else 0
def readShort(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return int(val) if val is not None else 0
def readInt(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return int(val) if val is not None else 0
def readLong(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return int(val) if val is not None else 0
def readFloat(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return float(val) if val is not None else 0.0
def readDouble(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return float(val) if val is not None else 0.0
def readBigDecimal(self):
return self.readDouble()
def readBytes(self):
return b""
def readDate(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
if isinstance(val, Date):
return val
return Date()
def readTime(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
if isinstance(val, Time):
return val
return Time()
def readTimestamp(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
if isinstance(val, Timestamp):
return val
return Timestamp()
def readCharacterStream(self):
import io
return io.StringIO("")
def readBinaryStream(self):
import io
return io.BytesIO(b"")
def readObject(self):
val = self._data[self._pos] if self._pos < len(self._data) else None
self._pos += 1
return val
def readRef(self):
return Ref()
def readBlob(self):
return Blob()
def readClob(self):
return Clob()
def readArray(self):
return Array()
def readURL(self):
return None
def readNClob(self):
return NClob()
def readNString(self):
return self.readString()
def readSQLXML(self):
return SQLXML()
def readRowId(self):
return RowId()
def wasNull(self):
return False
class SQLOutput(Stub):
"""java.sql.SQLOutput"""
def __init__(self):
super().__init__()
self._data = []
def writeString(self, x):
self._data.append(x)
def writeBoolean(self, x):
self._data.append(x)
def writeByte(self, x):
self._data.append(x)
def writeShort(self, x):
self._data.append(x)
def writeInt(self, x):
self._data.append(x)
def writeLong(self, x):
self._data.append(x)
def writeFloat(self, x):
self._data.append(x)
def writeDouble(self, x):
self._data.append(x)
def writeBigDecimal(self, x):
self._data.append(x)
def writeBytes(self, x):
self._data.append(x)
def writeDate(self, x):
self._data.append(x)
def writeTime(self, x):
self._data.append(x)
def writeTimestamp(self, x):
self._data.append(x)
def writeCharacterStream(self, x):
self._data.append(x.read() if hasattr(x, 'read') else x)
def writeBinaryStream(self, x):
self._data.append(x.read() if hasattr(x, 'read') else x)
def writeObject(self, x):
self._data.append(x)
def writeRef(self, x):
self._data.append(x)
def writeBlob(self, x):
self._data.append(x)
def writeClob(self, x):
self._data.append(x)
def writeStruct(self, x):
self._data.append(x)
def writeArray(self, x):
self._data.append(x)
def writeURL(self, x):
self._data.append(x)
def writeNClob(self, x):
self._data.append(x)
def writeNString(self, x):
self._data.append(x)
def writeSQLXML(self, x):
self._data.append(x)
def writeRowId(self, x):
self._data.append(x)
# ============================================================
# Driver / DriverManager / DriverPropertyInfo
# ============================================================
class Driver(Stub):
"""java.sql.Driver"""
def connect(self, url, info):
raise SQLException("No suitable driver")
def acceptsURL(self, url):
return False
def getPropertyInfo(self, url, info):
return []
def getMajorVersion(self):
return 1
def getMinorVersion(self):
return 0
def jdbcCompliant(self):
return False
def getParentLogger(self):
return None
class DriverPropertyInfo(Stub):
"""java.sql.DriverPropertyInfo"""
def __init__(self, name, value=None):
super().__init__()
self.name = name
self.description = None
self.required = False
self.value = value
self.choices = None
class DriverManager(Stub):
"""java.sql.DriverManager"""
_registered_drivers = []
_log_stream = None
_log_writer = None
_login_timeout = 0
@staticmethod
def getConnection(url, user=None, password=None):
for driver in DriverManager._registered_drivers:
if driver.acceptsURL(url):
props = {}
if user is not None:
props["user"] = user
if password is not None:
props["password"] = password
return driver.connect(url, props)
raise SQLException(f"No suitable driver found for {url}")
@staticmethod
def registerDriver(driver):
DriverManager._registered_drivers.append(driver)
@staticmethod
def deregisterDriver(driver):
if driver in DriverManager._registered_drivers:
DriverManager._registered_drivers.remove(driver)
@staticmethod
def getDrivers():
return DriverManager._registered_drivers
@staticmethod
def getLoginTimeout():
return DriverManager._login_timeout
@staticmethod
def setLoginTimeout(seconds):
DriverManager._login_timeout = seconds
@staticmethod
def getLogWriter():
return DriverManager._log_writer
@staticmethod
def setLogWriter(writer):
DriverManager._log_writer = writer
@staticmethod
def println(message):
if DriverManager._log_writer is not None:
DriverManager._log_writer.write(str(message) + "\n")
# ============================================================
# Connection
# ============================================================
class Connection(Stub):
"""java.sql.Connection"""
def createStatement(self):
return Statement()
def prepareStatement(self, sql):
return PreparedStatement(sql)
def prepareCall(self, sql):
return CallableStatement(sql)
def nativeSQL(self, sql):
return sql
def setAutoCommit(self, auto_commit):
pass
def getAutoCommit(self):
return True
def commit(self):
pass
def rollback(self, savepoint=None):
pass
def close(self):
pass
def isClosed(self):
return False
def getMetaData(self):
return DatabaseMetaData()
def setReadOnly(self, read_only):
pass
def isReadOnly(self):
return False
def setCatalog(self, catalog):
pass
def getCatalog(self):
return ""
def setTransactionIsolation(self, level):
pass
def getTransactionIsolation(self):
return Connection.TRANSACTION_READ_COMMITTED
def getWarnings(self):
return None
def clearWarnings(self):
pass
def setSavepoint(self, name=None):
return Savepoint(name)
def releaseSavepoint(self, savepoint):
pass
def createStatement(self, result_set_type, result_set_concurrency):
return Statement()
def prepareStatement(self, sql, *args):
return PreparedStatement(sql)
def prepareCall(self, sql, result_set_type, result_set_concurrency):
return CallableStatement(sql)
def setTypeMap(self, type_map):
pass
def getTypeMap(self):
return {}
def setHoldability(self, holdability):
pass
def getHoldability(self):
return HOLD_CURSORS_OVER_COMMIT
def setSchema(self, schema):
pass
def getSchema(self):
return ""
def abort(self, executor):
pass
def getNetworkTimeout(self):
return 0
def setNetworkTimeout(self, executor, milliseconds):
pass
def createArrayOf(self, type_name, elements):
return Array(type_name, elements)
def createBlob(self):
return Blob()
def createClob(self):
return Clob()
def createNClob(self):
return NClob()
def createSQLXML(self):
return SQLXML()
def createStruct(self, type_name, attributes):
return Struct(type_name, attributes)
def isValid(self, timeout):
return not self.isClosed()
# Transaction isolation constants
TRANSACTION_NONE = 0
TRANSACTION_READ_COMMITTED = 2
TRANSACTION_READ_UNCOMMITTED = 1
TRANSACTION_REPEATABLE_READ = 4
TRANSACTION_SERIALIZABLE = 8
# ============================================================
# Statement
# ============================================================
class Statement(Stub):
"""java.sql.Statement"""
def __init__(self):
super().__init__()
self._max_rows = 0
self._query_timeout = 0
self._fetch_direction = FETCH_FORWARD
self._fetch_size = 0
self._max_field_size = 0
self._poolable = True
self._close_on_completion = False
self._result_set_type = TYPE_FORWARD_ONLY
self._result_set_concurrency = 0
self._result_set_holdability = HOLD_CURSORS_OVER_COMMIT
self._generated_keys = None
self._update_count = -1
self._result_set = None
self._more_results = False
self._closed = False
self._warnings = None
self._poolable = True
def executeQuery(self, sql):
return ResultSet()
def executeUpdate(self, sql):
return 0
def close(self):
self._closed = True
def getMaxFieldSize(self):
return self._max_field_size
def setMaxFieldSize(self, max_size):
self._max_field_size = max_size
def getMaxRows(self):
return self._max_rows
def setMaxRows(self, max_rows):
self._max_rows = max_rows
def setEscapeProcessing(self, enable):
pass
def getQueryTimeout(self):
return self._query_timeout
def setQueryTimeout(self, seconds):
self._query_timeout = seconds
def cancel(self):
pass
def getWarnings(self):
return self._warnings
def clearWarnings(self):
self._warnings = None
def setCursorName(self, name):
pass
def execute(self, sql):
return False
def getResultSet(self):
return self._result_set
def getUpdateCount(self):
return self._update_count
def getMoreResults(self, current=None):
return False
def setFetchDirection(self, direction):
self._fetch_direction = direction
def getFetchDirection(self):
return self._fetch_direction
def setFetchSize(self, rows):
self._fetch_size = rows
def getFetchSize(self):
return self._fetch_size
def getResultSetConcurrency(self):
return self._result_set_concurrency
def getResultSetType(self):
return self._result_set_type
def addBatch(self, sql):
pass
def clearBatch(self):
pass
def executeBatch(self):
return []
def getConnection(self):
return Connection()
def getMoreResults(self, current):
return False
def getGeneratedKeys(self):
return self._generated_keys or ResultSet()
def getResultSetHoldability(self):
return self._result_set_holdability
def isClosed(self):
return self._closed
def setPoolable(self, poolable):
self._poolable = poolable
def isPoolable(self):
return self._poolable
def closeOnCompletion(self):
self._close_on_completion = True
def isCloseOnCompletion(self):
return self._close_on_completion
def executeLargeUpdate(self, sql):
return 0
def getLargeUpdateCount(self):
return self._update_count
def getLargeMaxRows(self):
return self._max_rows
def setLargeMaxRows(self, max_rows):
self._max_rows = max_rows
def executeLargeBatch(self):
return []
def unwrap(self, iface):
return self
def isWrapperFor(self, iface):
return isinstance(self, iface)
SUCCESS_NO_INFO = -2
EXECUTE_FAILED = -3
RETURN_GENERATED_KEYS = 1
NO_GENERATED_KEYS = 2
CLOSE_ALL_RESULTS = 3
KEEP_CURRENT_RESULT = 2
CLOSE_CURRENT_RESULT = 1
NO_GENERATED_KEYS = 2
RETURN_GENERATED_KEYS = 1
# ============================================================
# PreparedStatement
# ============================================================
class PreparedStatement(Statement):
"""java.sql.PreparedStatement"""
def __init__(self, sql=""):
super().__init__()
self._sql = sql
self._parameters = []
def setNull(self, parameter_index, sql_type, type_name=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = None
def setBoolean(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setByte(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setShort(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setInt(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setLong(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setFloat(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setDouble(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setBigDecimal(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setString(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setBytes(self, parameter_index, x):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = bytes(x) if x else None
def setDate(self, parameter_index, x, calendar=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setTime(self, parameter_index, x, calendar=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setTimestamp(self, parameter_index, x, calendar=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setAsciiStream(self, parameter_index, stream, length=None):
self._ensure_params(parameter_index)
data = stream.read() if hasattr(stream, 'read') else stream
if isinstance(data, bytes):
data = data.decode()
self._parameters[parameter_index - 1] = data
def setBinaryStream(self, parameter_index, stream, length=None):
self._ensure_params(parameter_index)
data = stream.read() if hasattr(stream, 'read') else stream
self._parameters[parameter_index - 1] = data
def setObject(self, parameter_index, x, target_sql_type=None, scale_or_length=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = x
def setCharacterStream(self, parameter_index, reader, length=None):
self._ensure_params(parameter_index)
data = reader.read() if hasattr(reader, 'read') else reader
self._parameters[parameter_index - 1] = data
def setBlob(self, parameter_index, blob):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = blob
def setClob(self, parameter_index, clob):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = clob
def setArray(self, parameter_index, array):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = array
def setRef(self, parameter_index, ref):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = ref
def setNString(self, parameter_index, value):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = value
def setNClob(self, parameter_index, nclob):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = nclob
def setNCharacterStream(self, parameter_index, reader, length=None):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = reader
def setRowId(self, parameter_index, row_id):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = row_id
def setSQLXML(self, parameter_index, xml):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = xml
def setURL(self, parameter_index, url):
self._ensure_params(parameter_index)
self._parameters[parameter_index - 1] = url
def clearParameters(self):
self._parameters = []
def executeQuery(self):
return ResultSet()
def executeUpdate(self):
return 0
def execute(self):
return False
def addBatch(self):
pass
def getParameterMetaData(self):
return ResultSetMetaData()
def getMetaData(self):
return ResultSetMetaData()
def _ensure_params(self, idx):
while len(self._parameters) < idx:
self._parameters.append(None)
# ============================================================
# CallableStatement
# ============================================================
class CallableStatement(PreparedStatement):
"""java.sql.CallableStatement"""
def __init__(self, sql=""):
super().__init__(sql)
self._output_params = {}
def registerOutParameter(self, parameter_index, sql_type, scale_or_type_name=None):
pass
def wasNull(self):
return False
def getString(self, parameter_index):
return self._output_params.get(parameter_index)
def getBoolean(self, parameter_index):
return bool(self._output_params.get(parameter_index))
def getByte(self, parameter_index):
return self._output_params.get(parameter_index, 0)
def getShort(self, parameter_index):
return self._output_params.get(parameter_index, 0)
def getInt(self, parameter_index):
return self._output_params.get(parameter_index, 0)
def getLong(self, parameter_index):
return self._output_params.get(parameter_index, 0)
def getFloat(self, parameter_index):
return float(self._output_params.get(parameter_index, 0.0))
def getDouble(self, parameter_index):
return float(self._output_params.get(parameter_index, 0.0))
def getBigDecimal(self, parameter_index):
return self._output_params.get(parameter_index)
def getBytes(self, parameter_index):
return b""
def getDate(self, parameter_index):
return Date()
def getTime(self, parameter_index):
return Time()
def getTimestamp(self, parameter_index):
return Timestamp()
def getObject(self, parameter_index, type_map=None):
return self._output_params.get(parameter_index)
def getRef(self, parameter_index):
return Ref()
def getBlob(self, parameter_index):
return Blob()
def getClob(self, parameter_index):
return Clob()
def getArray(self, parameter_index):
return Array()
def getURL(self, parameter_index):
return None
def getNClob(self, parameter_index):
return NClob()
def getNString(self, parameter_index):
return self.getString(parameter_index)
def getNCharacterStream(self, parameter_index):
import io
return io.StringIO("")
def getRowId(self, parameter_index):
return RowId()
def getSQLXML(self, parameter_index):
return SQLXML()
# ============================================================
# ResultSet
# ============================================================
class ResultSet(Stub):
"""java.sql.ResultSet"""
def __init__(self):
super().__init__()
self._rows = []
self._row_index = -1
self._closed = False
self._warnings = None
self._fetch_direction = FETCH_FORWARD
self._fetch_size = 0
self._type = TYPE_FORWARD_ONLY
self._concurrency = 0
self._holdability = HOLD_CURSORS_OVER_COMMIT
self._meta_data = ResultSetMetaData()
def next(self):
if self._row_index + 1 < len(self._rows):
self._row_index += 1
return True
return False
def close(self):
self._closed = True
def wasNull(self):
return False
def getString(self, column_index_or_label):
return str(self._get_value(column_index_or_label) or "")
def getBoolean(self, column_index_or_label):
return bool(self._get_value(column_index_or_label))
def getByte(self, column_index_or_label):
return int(self._get_value(column_index_or_label) or 0)
def getShort(self, column_index_or_label):
return int(self._get_value(column_index_or_label) or 0)
def getInt(self, column_index_or_label):
return int(self._get_value(column_index_or_label) or 0)
def getLong(self, column_index_or_label):
return int(self._get_value(column_index_or_label) or 0)
def getFloat(self, column_index_or_label):
return float(self._get_value(column_index_or_label) or 0.0)
def getDouble(self, column_index_or_label):
return float(self._get_value(column_index_or_label) or 0.0)
def getBytes(self, column_index_or_label):
val = self._get_value(column_index_or_label)
if isinstance(val, bytes):
return val
if isinstance(val, str):
return val.encode()
return b""
def getDate(self, column_index_or_label):
val = self._get_value(column_index_or_label)
if isinstance(val, Date):
return val
return Date()
def getTime(self, column_index_or_label):
val = self._get_value(column_index_or_label)
if isinstance(val, Time):
return val
return Time()
def getTimestamp(self, column_index_or_label):
val = self._get_value(column_index_or_label)
if isinstance(val, Timestamp):
return val
return Timestamp()
def getObject(self, column_index_or_label, type_map=None):
return self._get_value(column_index_or_label)
def findColumn(self, column_label):
return 1
def getMetaData(self):
return self._meta_data
def getWarnings(self):
return self._warnings
def clearWarnings(self):
self._warnings = None
def setFetchDirection(self, direction):
self._fetch_direction = direction
def getFetchDirection(self):
return self._fetch_direction
def setFetchSize(self, rows):
self._fetch_size = rows
def getFetchSize(self):
return self._fetch_size
def getType(self):
return self._type
def getConcurrency(self):
return self._concurrency
def rowUpdated(self):
return False
def rowInserted(self):
return False
def rowDeleted(self):
return False
def updateNull(self, column_index_or_label):
pass
def updateBoolean(self, column_index_or_label, x):
pass
def updateByte(self, column_index_or_label, x):
pass
def updateShort(self, column_index_or_label, x):
pass
def updateInt(self, column_index_or_label, x):
pass
def updateLong(self, column_index_or_label, x):
pass
def updateFloat(self, column_index_or_label, x):
pass
def updateDouble(self, column_index_or_label, x):
pass
def updateString(self, column_index_or_label, x):
pass
def updateBytes(self, column_index_or_label, x):
pass
def updateDate(self, column_index_or_label, x):
pass
def updateTime(self, column_index_or_label, x):
pass
def updateTimestamp(self, column_index_or_label, x):
pass
def updateRow(self):
pass
def insertRow(self):
pass
def deleteRow(self):
pass
def refreshRow(self):
pass
def cancelRowUpdates(self):
pass
def moveToInsertRow(self):
pass
def moveToCurrentRow(self):
pass
def isClosed(self):
return self._closed
def getHoldability(self):
return self._holdability
def getStatement(self):
return None
def getArray(self, column_index_or_label):
return Array()
def getBlob(self, column_index_or_label):
return Blob()
def getClob(self, column_index_or_label):
return Clob()
def getRef(self, column_index_or_label):
return Ref()
def getURL(self, column_index_or_label):
return None
def getNClob(self, column_index_or_label):
return NClob()
def getNString(self, column_index_or_label):
return self.getString(column_index_or_label)
def getNCharacterStream(self, column_index_or_label):
import io
return io.StringIO("")
def getRowId(self, column_index_or_label):
return RowId()
def getSQLXML(self, column_index_or_label):
return SQLXML()
def getBinaryStream(self, column_index_or_label):
import io
return io.BytesIO(b"")
def getCharacterStream(self, column_index_or_label):
import io
return io.StringIO("")
def getAsciiStream(self, column_index_or_label):
import io
return io.BytesIO(b"")
def updateObject(self, column_index_or_label, x, scale_or_target=None):
pass
def beforeFirst(self):
self._row_index = -1
def afterLast(self):
self._row_index = len(self._rows)
def first(self):
if self._rows:
self._row_index = 0
return True
return False
def last(self):
if self._rows:
self._row_index = len(self._rows) - 1
return True
return False
def absolute(self, row):
if row == 0:
self._row_index = -1
return False
idx = row - 1 if row > 0 else len(self._rows) + row
if 0 <= idx < len(self._rows):
self._row_index = idx
return True
return False
def relative(self, rows):
new_idx = self._row_index + rows
if 0 <= new_idx < len(self._rows):
self._row_index = new_idx
return True
return False
def previous(self):
if self._row_index > 0:
self._row_index -= 1
return True
return False
def isBeforeFirst(self):
return self._row_index < 0 and len(self._rows) > 0
def isAfterLast(self):
return self._row_index >= len(self._rows) and len(self._rows) > 0
def isFirst(self):
return self._row_index == 0
def isLast(self):
return self._row_index == len(self._rows) - 1
def getRow(self):
return self._row_index + 1 if 0 <= self._row_index < len(self._rows) else 0
def _get_value(self, col):
if 0 <= self._row_index < len(self._rows):
row = self._rows[self._row_index]
if isinstance(col, int) and col - 1 < len(row):
return row[col - 1]
return None
# Constants
FETCH_FORWARD = 1000
FETCH_REVERSE = 1001
FETCH_UNKNOWN = 1002
TYPE_FORWARD_ONLY = 1003
TYPE_SCROLL_INSENSITIVE = 1004
TYPE_SCROLL_SENSITIVE = 1005
CONCUR_READ_ONLY = 1007
CONCUR_UPDATABLE = 1008
HOLD_CURSORS_OVER_COMMIT = 1
CLOSE_CURSORS_AT_COMMIT = 2
# ============================================================
# ResultSetMetaData
# ============================================================
class ResultSetMetaData(Stub):
"""java.sql.ResultSetMetaData"""
def __init__(self):
super().__init__()
self._column_count = 0
self._column_names = []
self._column_types = []
def getColumnCount(self):
return self._column_count
def isAutoIncrement(self, column):
return False
def isCaseSensitive(self, column):
return True
def isSearchable(self, column):
return True
def isCurrency(self, column):
return False
def isNullable(self, column):
return ResultSetMetaData.columnNullable
def isSigned(self, column):
return True
def getColumnDisplaySize(self, column):
return 255
def getColumnLabel(self, column):
return self.getColumnName(column)
def getColumnName(self, column):
if column - 1 < len(self._column_names):
return self._column_names[column - 1]
return f"COLUMN_{column}"
def getSchemaName(self, column):
return ""
def getPrecision(self, column):
return 0
def getScale(self, column):
return 0
def getTableName(self, column):
return ""
def getCatalogName(self, column):
return ""
def getColumnType(self, column):
if column - 1 < len(self._column_types):
return self._column_types[column - 1]
return Types.VARCHAR
def getColumnTypeName(self, column):
return "VARCHAR"
def isReadOnly(self, column):
return False
def isWritable(self, column):
return True
def isDefinitelyWritable(self, column):
return True
def getColumnClassName(self, column):
return "java.lang.String"
columnNoNulls = 0
columnNullable = 1
columnNullableUnknown = 2
# ============================================================
# DatabaseMetaData
# ============================================================
class DatabaseMetaData(Stub):
"""java.sql.DatabaseMetaData"""
def getDatabaseProductName(self):
return "Android-pyApi SQL"
def getDatabaseProductVersion(self):
return "1.0"
def getDriverName(self):
return "Android-pyApi JDBC Driver"
def getDriverVersion(self):
return "1.0"
def getDriverMajorVersion(self):
return 1
def getDriverMinorVersion(self):
return 0
def getURL(self):
return ""
def getUserName(self):
return ""
def isReadOnly(self):
return False
def nullsAreSortedHigh(self):
return True
def nullsAreSortedLow(self):
return False
def nullsAreSortedAtStart(self):
return False
def nullsAreSortedAtEnd(self):
return False
def getDatabaseMajorVersion(self):
return 1
def getDatabaseMinorVersion(self):
return 0
def getJDBCMajorVersion(self):
return 4
def getJDBCMinorVersion(self):
return 2
def getDefaultTransactionIsolation(self):
return Connection.TRANSACTION_READ_COMMITTED
def supportsTransactions(self):
return True
def supportsTransactionIsolationLevel(self, level):
return True
def supportsResultSetType(self, type_):
return True
def supportsResultSetConcurrency(self, type_, concurrency):
return True
def getTables(self, catalog, schema_pattern, table_name_pattern, types):
return ResultSet()
def getColumns(self, catalog, schema_pattern, table_name_pattern, column_name_pattern):
return ResultSet()
def getPrimaryKeys(self, catalog, schema, table):
return ResultSet()
def getImportedKeys(self, catalog, schema, table):
return ResultSet()
def getExportedKeys(self, catalog, schema, table):
return ResultSet()
def getSchemas(self):
return ResultSet()
def getCatalogs(self):
return ResultSet()
def getTableTypes(self):
return ResultSet()
def getTypeInfo(self):
return ResultSet()
def getIndexInfo(self, catalog, schema, table, unique, approximate):
return ResultSet()
def getProcedures(self, catalog, schema_pattern, procedure_name_pattern):
return ResultSet()
def getProcedureColumns(self, catalog, schema_pattern, procedure_name_pattern, column_name_pattern):
return ResultSet()
def supportsSavepoints(self):
return True
def supportsBatchUpdates(self):
return True
def supportsStoredProcedures(self):
return True
def allProceduresAreCallable(self):
return True
def allTablesAreSelectable(self):
return True
def dataDefinitionCausesTransactionCommit(self):
return False
def dataDefinitionIgnoredInTransactions(self):
return False
def doesMaxRowSizeIncludeBlobs(self):
return False
def getMaxBinaryLiteralLength(self):
return 0
def getMaxCharLiteralLength(self):
return 0
def getMaxColumnNameLength(self):
return 128
def getMaxColumnsInGroupBy(self):
return 0
def getMaxColumnsInIndex(self):
return 0
def getMaxColumnsInOrderBy(self):
return 0
def getMaxColumnsInSelect(self):
return 0
def getMaxColumnsInTable(self):
return 0
def getMaxConnections(self):
return 0
def getMaxCursorNameLength(self):
return 0
def getMaxIndexLength(self):
return 0
def getMaxSchemaNameLength(self):
return 0
def getMaxProcedureNameLength(self):
return 0
def getMaxRowSize(self):
return 0
def getMaxStatementLength(self):
return 0
def getMaxStatements(self):
return 0
def getMaxTableNameLength(self):
return 0
def getMaxTablesInSelect(self):
return 0
def getMaxUserNameLength(self):
return 0
def getNumericFunctions(self):
return ""
def getSQLKeywords(self):
return ""
def getStringFunctions(self):
return ""
def getSystemFunctions(self):
return ""
def getTimeDateFunctions(self):
return ""
def getSearchStringEscape(self):
return "\\"
def getExtraNameCharacters(self):
return ""
def getSchemaTerm(self):
return "schema"
def getCatalogTerm(self):
return "catalog"
def getProcedureTerm(self):
return "procedure"
def getCatalogSeparator(self):
return "."
def isCatalogAtStart(self):
return True
def autoCommitFailureClosesAllResultSets(self):
return False
def generatedKeyAlwaysReturned(self):
return True
def getSQLStateType(self):
return DatabaseMetaData.sqlStateSQL
def locatorsUpdateCopy(self):
return False
def supportsDifferentTableCorrelationNames(self):
return True
def supportsANSI92EntryLevelSQL(self):
return True
def supportsANSI92IntermediateSQL(self):
return True
def supportsANSI92FullSQL(self):
return False
def supportsIntegrityEnhancementFacility(self):
return False
def supportsOuterJoins(self):
return True
def supportsFullOuterJoins(self):
return True
def supportsLimitedOuterJoins(self):
return True
def supportsSchemasInDataManipulation(self):
return True
def supportsSchemasInProcedureCalls(self):
return True
def supportsSchemasInTableDefinitions(self):
return True
def supportsSchemasInIndexDefinitions(self):
return True
def supportsSchemasInPrivilegeDefinitions(self):
return True
def supportsCatalogsInDataManipulation(self):
return True
def supportsCatalogsInProcedureCalls(self):
return True
def supportsCatalogsInTableDefinitions(self):
return True
def supportsCatalogsInIndexDefinitions(self):
return True
def supportsCatalogsInPrivilegeDefinitions(self):
return True
def supportsPositionedDelete(self):
return False
def supportsPositionedUpdate(self):
return False
def supportsSelectForUpdate(self):
return True
def supportsSubqueriesInComparisons(self):
return True
def supportsSubqueriesInExists(self):
return True
def supportsSubqueriesInIns(self):
return True
def supportsSubqueriesInQuantifieds(self):
return True
def supportsCorrelatedSubqueries(self):
return True
def supportsUnion(self):
return True
def supportsUnionAll(self):
return True
def supportsOpenCursorsAcrossCommit(self):
return True
def supportsOpenCursorsAcrossRollback(self):
return True
def supportsOpenStatementsAcrossCommit(self):
return True
def supportsOpenStatementsAcrossRollback(self):
return True
def supportsMixedCaseIdentifiers(self):
return True
def storesMixedCaseIdentifiers(self):
return True
def supportsMixedCaseQuotedIdentifiers(self):
return True
def storesMixedCaseQuotedIdentifiers(self):
return True
def supportsAlterTableWithAddColumn(self):
return True
def supportsAlterTableWithDropColumn(self):
return True
def supportsColumnAliasing(self):
return True
def supportsConvert(self):
return True
def supportsTableCorrelationNames(self):
return True
def getConnection(self):
return Connection()
# Constants
attributeNoNulls = 0
attributeNullable = 1
attributeNullableUnknown = 2
bestRowTemporary = 0
bestRowTransaction = 1
bestRowSession = 2
bestRowUnknown = 0
bestRowNotPseudo = 1
bestRowPseudo = 2
columnNoNulls = 0
columnNullable = 1
columnNullableUnknown = 2
functionColumnIn = 1
functionColumnInOut = 2
functionColumnOut = 3
functionColumnReturn = 4
functionColumnResult = 5
functionNoNulls = 0
functionNullable = 1
functionNullableUnknown = 2
functionResultUnknown = 0
functionNoTable = 1
functionReturnsTable = 2
importedKeyCascade = 0
importedKeyRestrict = 1
importedKeySetNull = 2
importedKeyNoAction = 3
importedKeySetDefault = 4
importedKeyInitiallyDeferred = 5
importedKeyInitiallyImmediate = 6
importedKeyNotDeferrable = 7
procedureColumnIn = 1
procedureColumnInOut = 2
procedureColumnOut = 4
procedureColumnReturn = 5
procedureColumnResult = 3
procedureNoNulls = 0
procedureNullable = 1
procedureNullableUnknown = 2
procedureResultUnknown = 0
sqlStateSQL = 2
sqlStateXOpen = 1
tableIndexStatistic = 0
tableIndexClustered = 1
tableIndexHashed = 2
tableIndexOther = 3
versionColumnUnknown = 0
versionColumnNotPseudo = 1
versionColumnPseudo = 2
# ============================================================
# IllegalArgumentException
# ============================================================
class IllegalArgumentException(RuntimeException):
"""java.lang.IllegalArgumentException"""
pass