""" Java javax.sql APIs implemented in Python. javax.sql package - DataSource, RowSet, RowSetListener, ConnectionEvent, etc. Desktop implementation wrapping Python sqlite3 module. """ from __future__ import annotations from .._core import Stub, AndroidOnlyError import sqlite3 as _sqlite3 from typing import List, Optional, Any __all__ = [ "DataSource", "RowSet", "RowSetListener", "RowSetMetaData", "CachedRowSet", "WebRowSet", "FilteredRowSet", "JoinRowSet", "Predicate", "SyncProvider", "SyncFactory", "RowSetWriter", "RowSetReader", "ConnectionEvent", "ConnectionEventListener", "PooledConnection", "StatementEvent", "StatementEventListener", "XADataSource", "XAConnection", "XAResource", ] # ============================================================ # DataSource # ============================================================ class DataSource(Stub): """ javax.sql.DataSource A factory for connections to a physical data source. Wraps Python sqlite3. """ def __init__(self, db_path: str = ":memory:"): super().__init__() self._db_path = db_path self._log_writer = None self._login_timeout = 0 self._connection = None def getConnection(self, username: str = None, password: str = None) -> Any: """Gets a connection to the data source.""" self._connection = _sqlite3.connect(self._db_path) return self._connection def getLogWriter(self): return self._log_writer def setLogWriter(self, writer): self._log_writer = writer def getLoginTimeout(self) -> int: return self._login_timeout def setLoginTimeout(self, seconds: int): self._login_timeout = seconds def getParentLogger(self): return None def createConnectionBuilder(self): return None def createPooledConnectionBuilder(self): return None def unwrap(self, iface: type) -> Any: return self def isWrapperFor(self, iface: type) -> bool: return iface == DataSource def toString(self) -> str: return f"DataSource@{hex(id(self))}[db={self._db_path}]" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # RowSetListener # ============================================================ class RowSetListener(Stub): """ javax.sql.RowSetListener Listener for RowSet events. """ def cursorMoved(self, event: Any): pass def rowChanged(self, event: Any): pass def rowSetChanged(self, event: Any): pass def toString(self) -> str: return f"RowSetListener@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # RowSet # ============================================================ class RowSet(Stub): """ javax.sql.RowSet A row set interface that wraps a result set. """ def __init__(self): super().__init__() self._url = "" self._data_source_name = "" self._username = "" self._password = "" self._command = "" self._query_timeout = 0 self._max_rows = 0 self._max_field_size = 0 self._escape_processing = True self._fetch_direction = 1000 # FETCH_FORWARD self._fetch_size = 0 self._type = 1003 # TYPE_FORWARD_ONLY self._concurrency = 1007 # CONCUR_READ_ONLY self._show_deleted = False self._read_only = True self._table_name = "" self._transaction_isolation = 0 self._type_map = None self._key_columns = [] self._match_column = "" self._filter = None self._cursor = None self._listeners = [] self._params = [] self._rows = [] self._current_row = -1 def setUrl(self, url: str): self._url = url def getUrl(self) -> str: return self._url def setDataSourceName(self, name: str): self._data_source_name = name def getDataSourceName(self) -> str: return self._data_source_name def setUsername(self, name: str): self._username = name def getUsername(self) -> str: return self._username def setPassword(self, pwd: str): self._password = pwd def getPassword(self) -> str: return self._password def setCommand(self, cmd: str): self._command = cmd def getCommand(self) -> str: return self._command def setQueryTimeout(self, seconds: int): self._query_timeout = seconds def getQueryTimeout(self) -> int: return self._query_timeout def setMaxRows(self, max_rows: int): self._max_rows = max_rows def getMaxRows(self) -> int: return self._max_rows def setMaxFieldSize(self, max_size: int): self._max_field_size = max_size def getMaxFieldSize(self) -> int: return self._max_field_size def setEscapeProcessing(self, enable: bool): self._escape_processing = enable def getEscapeProcessing(self) -> bool: return self._escape_processing def setFetchDirection(self, direction: int): self._fetch_direction = direction def getFetchDirection(self) -> int: return self._fetch_direction def setFetchSize(self, size: int): self._fetch_size = size def getFetchSize(self) -> int: return self._fetch_size def setType(self, rowset_type: int): self._type = rowset_type def getType(self) -> int: return self._type def setConcurrency(self, concurrency: int): self._concurrency = concurrency def getConcurrency(self) -> int: return self._concurrency def execute(self): """Executes the command and populates the row set.""" self._rows = [] self._current_row = -1 for listener in self._listeners: listener.rowSetChanged(self) def rowSetListeners(self) -> List[RowSetListener]: return list(self._listeners) def addRowSetListener(self, listener: RowSetListener): self._listeners.append(listener) def removeRowSetListener(self, listener: RowSetListener): if listener in self._listeners: self._listeners.remove(listener) def setShowDeleted(self, show: bool): self._show_deleted = show def isShowDeleted(self) -> bool: return self._show_deleted def setReadOnly(self, read_only: bool): self._read_only = read_only def isReadOnly(self) -> bool: return self._read_only def setTableName(self, name: str): self._table_name = name def getTableName(self) -> str: return self._table_name def setTransactionIsolation(self, level: int): self._transaction_isolation = level def getTransactionIsolation(self) -> int: return self._transaction_isolation def setTypeMap(self, type_map: Any): self._type_map = type_map def getTypeMap(self): return self._type_map def setKeyColumns(self, columns: List[int]): self._key_columns = columns def getKeyColumns(self) -> List[int]: return list(self._key_columns) def setMatchColumn(self, column: Any): self._match_column = str(column) def getMatchColumn(self) -> Any: return self._match_column def setFilter(self, f: Any): self._filter = f def getFilter(self): return self._filter def setCursor(self, cursor: Any): self._cursor = cursor def getCursor(self): return self._cursor def clearParameters(self): self._params = [] def validate(self) -> bool: return True def getParams(self) -> List: return list(self._params) def toString(self) -> str: return f"RowSet@{hex(id(self))}[command={self._command}]" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # RowSetMetaData # ============================================================ class RowSetMetaData(Stub): """ javax.sql.RowSetMetaData Metadata for a RowSet. """ def __init__(self): super().__init__() self._column_count = 0 self._auto_increment = {} self._case_sensitive = {} self._searchable = {} self._currency = {} self._nullable = {} self._signed = {} self._display_size = {} self._labels = {} self._column_names = {} self._schema_names = {} self._precision = {} self._scale = {} self._table_names = {} self._catalog_names = {} self._column_types = {} self._column_type_names = {} self._column_class_names = {} def setColumnCount(self, count: int): self._column_count = count def getColumnCount(self) -> int: return self._column_count def setAutoIncrement(self, column: int, value: bool): self._auto_increment[column] = value def isAutoIncrement(self, column: int) -> bool: return self._auto_increment.get(column, False) def setCaseSensitive(self, column: int, value: bool): self._case_sensitive[column] = value def isCaseSensitive(self, column: int) -> bool: return self._case_sensitive.get(column, False) def setSearchable(self, column: int, value: bool): self._searchable[column] = value def isSearchable(self, column: int) -> bool: return self._searchable.get(column, True) def setCurrency(self, column: int, value: bool): self._currency[column] = value def isCurrency(self, column: int) -> bool: return self._currency.get(column, False) def setNullable(self, column: int, value: int): self._nullable[column] = value def isNullable(self, column: int) -> int: return self._nullable.get(column, 1) def setSigned(self, column: int, value: bool): self._signed[column] = value def isSigned(self, column: int) -> bool: return self._signed.get(column, False) def setDisplaySize(self, column: int, size: int): self._display_size[column] = size def getDisplaySize(self, column: int) -> int: return self._display_size.get(column, 0) def setLabel(self, column: int, label: str): self._labels[column] = label def getColumnLabel(self, column: int) -> str: return self._labels.get(column, "") def setColumnName(self, column: int, name: str): self._column_names[column] = name def getColumnName(self, column: int) -> str: return self._column_names.get(column, "") def setSchemaName(self, column: int, name: str): self._schema_names[column] = name def getSchemaName(self, column: int) -> str: return self._schema_names.get(column, "") def setPrecision(self, column: int, precision: int): self._precision[column] = precision def getPrecision(self, column: int) -> int: return self._precision.get(column, 0) def setScale(self, column: int, scale: int): self._scale[column] = scale def getScale(self, column: int) -> int: return self._scale.get(column, 0) def setTableName(self, column: int, name: str): self._table_names[column] = name def getTableName(self, column: int) -> str: return self._table_names.get(column, "") def setCatalogName(self, column: int, name: str): self._catalog_names[column] = name def getCatalogName(self, column: int) -> str: return self._catalog_names.get(column, "") def setColumnType(self, column: int, sql_type: int): self._column_types[column] = sql_type def getColumnType(self, column: int) -> int: return self._column_types.get(column, 0) def setColumnTypeName(self, column: int, name: str): self._column_type_names[column] = name def getColumnTypeName(self, column: int) -> str: return self._column_type_names.get(column, "") def setColumnClassName(self, column: int, name: str): self._column_class_names[column] = name def getColumnClassName(self, column: int) -> str: return self._column_class_names.get(column, "") def toString(self) -> str: return f"RowSetMetaData@{hex(id(self))}[columns={self._column_count}]" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # CachedRowSet # ============================================================ class CachedRowSet(RowSet): """ javax.sql.rowset.CachedRowSet A row set that caches its data in memory. """ def __init__(self): super().__init__() self._sync_provider = None self._page_size = 0 self._cached_data = [] self._original_data = [] def execute(self): super().execute() self._cached_data = list(self._rows) self._original_data = list(self._rows) def populate(self, result_set: Any): """Populates the row set from a ResultSet.""" pass def acceptChanges(self): """Accepts changes to the row set.""" self._original_data = list(self._cached_data) def commit(self): """Commits changes.""" pass def rollback(self, savepoint: Any = None): """Rolls back changes.""" self._cached_data = list(self._original_data) def setSyncProvider(self, provider: str): self._sync_provider = provider def getSyncProvider(self) -> str: return self._sync_provider or "com.sun.rowset.providers.RIOptimisticProvider" def sync(self) -> bool: """Syncs changes to the data source.""" return True def size(self) -> int: return len(self._cached_data) def createCopy(self) -> "CachedRowSet": copy = CachedRowSet() copy._cached_data = list(self._cached_data) return copy def createCopySchema(self) -> "CachedRowSet": return CachedRowSet() def createCopyNoConstraints(self) -> "CachedRowSet": return CachedRowSet() def getOriginal(self): """Returns the original value of the current row.""" return None def getOriginalRow(self): """Returns the original row.""" return None def setPageSize(self, size: int): self._page_size = size def getPageSize(self) -> int: return self._page_size def nextPage(self) -> bool: return False def previousPage(self) -> bool: return False def release(self): self._cached_data = [] def originalContents(self): """Returns the original contents.""" return self._original_data def getBookmark(self): return None def setBookmark(self, bookmark): pass def getShowDeleted(self) -> bool: return self._show_deleted def setShowDeleted(self, show: bool): self._show_deleted = show def isBeforeFirst(self) -> bool: return self._current_row < 0 and len(self._cached_data) > 0 def isAfterLast(self) -> bool: return self._current_row >= len(self._cached_data) def isFirst(self) -> bool: return self._current_row == 0 def isLast(self) -> bool: return self._current_row == len(self._cached_data) - 1 def beforeFirst(self): self._current_row = -1 def afterLast(self): self._current_row = len(self._cached_data) def first(self) -> bool: if self._cached_data: self._current_row = 0 return True return False def last(self) -> bool: if self._cached_data: self._current_row = len(self._cached_data) - 1 return True return False def next(self) -> bool: if self._current_row < len(self._cached_data) - 1: self._current_row += 1 return True self._current_row = len(self._cached_data) return False def previous(self) -> bool: if self._current_row > 0: self._current_row -= 1 return True return False def absolute(self, row: int) -> bool: if 0 < row <= len(self._cached_data): self._current_row = row - 1 return True return False def relative(self, rows: int) -> bool: new_row = self._current_row + rows if 0 <= new_row < len(self._cached_data): self._current_row = new_row return True return False def getRow(self) -> int: return self._current_row + 1 if 0 <= self._current_row < len(self._cached_data) else 0 def setMetaData(self, md: RowSetMetaData): pass def getMetaData(self): return None def findColumn(self, column_name: str) -> int: return 1 # Data retrieval methods (stub) def getObject(self, column: int) -> Any: if 0 <= self._current_row < len(self._cached_data): row = self._cached_data[self._current_row] if isinstance(row, (list, tuple)) and column <= len(row): return row[column - 1] return None def getString(self, column: int) -> str: return str(self.getObject(column) or "") def getInt(self, column: int) -> int: val = self.getObject(column) return int(val) if val else 0 def getLong(self, column: int) -> int: return self.getInt(column) def getFloat(self, column: int) -> float: val = self.getObject(column) return float(val) if val else 0.0 def getDouble(self, column: int) -> float: return self.getFloat(column) def getShort(self, column: int) -> int: return self.getInt(column) def getByte(self, column: int) -> int: return self.getInt(column) & 0xFF def getBytes(self, column: int) -> bytes: val = self.getObject(column) if isinstance(val, bytes): return val return b'' def getBoolean(self, column: int) -> bool: val = self.getObject(column) return bool(val) if val else False def getDate(self, column: int): return self.getObject(column) def getTime(self, column: int): return self.getObject(column) def getTimestamp(self, column: int): return self.getObject(column) def getBigDecimal(self, column: int): return self.getObject(column) def getAsciiStream(self, column: int): return None def getUnicodeStream(self, column: int): return None def getBinaryStream(self, column: int): return None def getCharacterStream(self, column: int): return None def getClob(self, column: int): return None def getBlob(self, column: int): return None def getArray(self, column: int): return None def getRef(self, column: int): return None def getRowId(self, column: int): return None def getNClob(self, column: int): return None def getNString(self, column: int) -> str: return self.getString(column) def getNCharacterStream(self, column: int): return None def getSQLXML(self, column: int): return None def wasNull(self) -> bool: return False # Update methods (stub) def updateNull(self, column: int): pass def updateBoolean(self, column: int, value: bool): pass def updateByte(self, column: int, value: int): pass def updateShort(self, column: int, value: int): pass def updateInt(self, column: int, value: int): pass def updateLong(self, column: int, value: int): pass def updateFloat(self, column: int, value: float): pass def updateDouble(self, column: int, value: float): pass def updateBigDecimal(self, column: int, value): pass def updateString(self, column: int, value: str): pass def updateBytes(self, column: int, value: bytes): pass def updateDate(self, column: int, value): pass def updateTime(self, column: int, value): pass def updateTimestamp(self, column: int, value): pass def updateAsciiStream(self, column: int, stream, length: int = None): pass def updateBinaryStream(self, column: int, stream, length: int = None): pass def updateCharacterStream(self, column: int, stream, length: int = None): pass def updateObject(self, column: int, value, scale_or_target: Any = None): pass def updateNull(self, column: int, type_name: str = None): pass def updateRow(self): pass def deleteRow(self): pass def insertRow(self): pass def cancelRowUpdates(self): pass def moveToInsertRow(self): pass def moveToCurrentRow(self): pass def rowUpdated(self) -> bool: return False def rowInserted(self) -> bool: return False def rowDeleted(self) -> bool: return False def close(self): pass def clearWarnings(self): pass def getWarnings(self): return None # Parameter setters (stub) def setURL(self, col: int, url: str): pass def setAsciiStream(self, col: int, stream, length: int = None): pass def setBigDecimal(self, col: int, value): pass def setBinaryStream(self, col: int, stream, length: int = None): pass def setBlob(self, col: int, blob, length: int = None): pass def setBoolean(self, col: int, value: bool): pass def setByte(self, col: int, value: int): pass def setBytes(self, col: int, value: bytes): pass def setCharacterStream(self, col: int, stream, length: int = None): pass def setClob(self, col: int, clob, length: int = None): pass def setDate(self, col: int, value): pass def setDouble(self, col: int, value: float): pass def setFloat(self, col: int, value: float): pass def setInt(self, col: int, value: int): pass def setLong(self, col: int, value: int): pass def setNCharacterStream(self, col: int, stream, length: int = None): pass def setNClob(self, col: int, value, length: int = None): pass def setNString(self, col: int, value: str): pass def setNull(self, col: int, sql_type: int, type_name: str = None): pass def setObject(self, col: int, value, target_type: Any = None, scale: int = None): pass def setRef(self, col: int, ref): pass def setRowId(self, col: int, row_id): pass def setShort(self, col: int, value: int): pass def setSQLXML(self, col: int, xml): pass def setString(self, col: int, value: str): pass def setTime(self, col: int, value): pass def setTimestamp(self, col: int, value): pass def setUnicodeStream(self, col: int, stream, length: int): pass def toString(self) -> str: return f"CachedRowSet@{hex(id(self))}[size={self.size()}]" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class WebRowSet(CachedRowSet): """javax.sql.rowset.WebRowSet - Web-oriented row set.""" pass class FilteredRowSet(CachedRowSet): """javax.sql.rowset.FilteredRowSet - Filtered row set.""" pass class JoinRowSet(CachedRowSet): """javax.sql.rowset.JoinRowSet - Join row set.""" pass # ============================================================ # Predicate # ============================================================ class Predicate(Stub): """ javax.sql.rowset.Predicate A filter for row set contents. """ def evaluate(self, row_set: CachedRowSet) -> bool: return True def evaluate(self, value: Any, column: int) -> bool: return True def evaluates(self, value: Any, column_name: str) -> bool: return True def toString(self) -> str: return f"Predicate@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # SyncProvider # ============================================================ class SyncProvider(Stub): """ javax.sql.rowset.spi.SyncProvider Service provider for synchronization. """ GRADE_NONE: int = 1 GRADE_LOCK_WHEN_MODIFIED: int = 2 GRADE_LOCK_MODIFIED_WHEN_GRANTED: int = 3 GRADE_CHECK_MODIFIED_AT_COMMIT: int = 4 GRADE_CHECK_ALL_AT_COMMIT: int = 5 DATASOURCE_NO_LOCK: int = 1 DATASOURCE_LOCK: int = 2 DATASOURCE_ROW_LOCK: int = 3 def getProviderID(self) -> str: return "com.sun.rowset.providers.RIOptimisticProvider" def getProviderGrade(self) -> int: return self.GRADE_CHECK_MODIFIED_AT_COMMIT def setProviderGrade(self, grade: int): pass def getDataSourceLock(self) -> int: return self.DATASOURCE_NO_LOCK def setDataSourceLock(self, lock: int): pass def getRowSetWriter(self): return None def getRowSetReader(self): return None def supportsUpdatableView(self) -> bool: return True def toString(self) -> str: return f"SyncProvider@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # SyncFactory # ============================================================ class SyncFactory(Stub): """ javax.sql.rowset.spi.SyncFactory Factory for SyncProvider instances. """ PROVIDER: str = "rowset.provider" ROWSET_SYNC_PROVIDER: str = "rowset.syncProvider" ROWSET_SYNC_VENDOR: str = "rowset.syncVendor" ROWSET_SYNC_PROVIDER_GRADE: str = "rowset.syncProviderGrade" DATASOURCE_LOCK: str = "rowset.datasourceLock" _instance = None _logger = None @classmethod def getInstance(cls) -> "SyncFactory": if cls._instance is None: cls._instance = SyncFactory() return cls._instance def getSyncProvider(self, provider_id: str = None) -> SyncProvider: return SyncProvider() def registerSyncProvider(self, provider_id: str): pass def setJNDIContext(self, ctx): pass def getJNDIContext(self): return None def unregisterSyncProvider(self, provider_id: str): pass def syncProviderRegistered(self, provider_id: str) -> bool: return True def syncProviderAdded(self, provider_id: str) -> bool: return True def syncProviderRemoved(self, provider_id: str) -> bool: return True @classmethod def setLogger(cls, logger): cls._logger = logger @classmethod def getLogger(cls): return cls._logger def toString(self) -> str: return f"SyncFactory@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # RowSetWriter / RowSetReader # ============================================================ class RowSetWriter(Stub): """ javax.sql.RowSetWriter Writes the contents of a RowSet to the data source. """ def writeData(self, caller: CachedRowSet) -> bool: return True def toString(self) -> str: return f"RowSetWriter@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class RowSetReader(Stub): """ javax.sql.RowSetReader Reads the contents of a RowSet from the data source. """ def readData(self, caller: CachedRowSet): pass def toString(self) -> str: return f"RowSetReader@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # ConnectionEvent / ConnectionEventListener # ============================================================ class ConnectionEvent(Stub): """ javax.sql.ConnectionEvent An event that provides information about connection events. """ def __init__(self, conn, exception: Exception = None): super().__init__() self._connection = conn self._exception = exception def getSQLException(self): return self._exception def toString(self) -> str: return f"ConnectionEvent@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class ConnectionEventListener(Stub): """ javax.sql.ConnectionEventListener Listener for connection events on a PooledConnection. """ def connectionClosed(self, event: ConnectionEvent): pass def connectionErrorOccurred(self, event: ConnectionEvent): pass def toString(self) -> str: return f"ConnectionEventListener@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # PooledConnection # ============================================================ class PooledConnection(Stub): """ javax.sql.PooledConnection A connection pool management interface. """ def __init__(self, db_path: str = ":memory:"): super().__init__() self._db_path = db_path self._connection = None self._listeners = [] self._statement_pool_size = 0 def getConnection(self) -> Any: self._connection = _sqlite3.connect(self._db_path) return self._connection def close(self): if self._connection: self._connection.close() event = ConnectionEvent(self) for listener in self._listeners: listener.connectionClosed(event) def addConnectionEventListener(self, listener: ConnectionEventListener): self._listeners.append(listener) def removeConnectionEventListener(self, listener: ConnectionEventListener): if listener in self._listeners: self._listeners.remove(listener) def setStatementPoolingCacheSize(self, size: int): self._statement_pool_size = size def getStatementPoolingCacheSize(self) -> int: return self._statement_pool_size def setConnectionEventListener(self, listener: ConnectionEventListener): self.addConnectionEventListener(listener) def setStatementEventListener(self, listener): pass def removeStatementEventListener(self, listener): pass def addStatementEventListener(self, listener): pass def removeStatementEventListener(self, listener): pass def toString(self) -> str: return f"PooledConnection@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # StatementEvent / StatementEventListener # ============================================================ class StatementEvent(Stub): """ javax.sql.StatementEvent An event for statement-related events. """ def __init__(self, conn, statement: Any = None, exception: Exception = None): super().__init__() self._connection = conn self._statement = statement self._exception = exception def getStatement(self): return self._statement def getSQLException(self): return self._exception def toString(self) -> str: return f"StatementEvent@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class StatementEventListener(Stub): """ javax.sql.StatementEventListener Listener for statement pool events. """ def statementClosed(self, event: StatementEvent): pass def statementErrorOccurred(self, event: StatementEvent): pass def toString(self) -> str: return f"StatementEventListener@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF # ============================================================ # XA stubs # ============================================================ class XADataSource(Stub): """ javax.sql.XADataSource Factory for XAConnection objects. """ def getXAConnection(self, user: str = None, password: str = None) -> "XAConnection": return XAConnection() def toString(self) -> str: return f"XADataSource@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class XAConnection(PooledConnection): """ javax.sql.XAConnection Connection for distributed transactions (stub). """ def __init__(self): super().__init__() def getXAResource(self) -> "XAResource": return XAResource() def toString(self) -> str: return f"XAConnection@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF class XAResource(Stub): """ javax.transaction.xa.XAResource Resource manager for distributed transactions (stub). """ TMENDRSCAN: int = 8388608 TMFAIL: int = 536870912 TMJOIN: int = 2097152 TMNOFLAGS: int = 0 TMONEPHASE: int = 1073741824 TMRESUME: int = 134217728 TMSTARTRSCAN: int = 16777216 TMSUCCESS: int = 67108864 TMSUSPEND: int = 33554432 XA_RDONLY: int = 3 XA_OK: int = 0 def start(self, xid: Any, flags: int): pass def end(self, xid: Any, flags: int): pass def prepare(self, xid: Any) -> int: return XA_OK def commit(self, xid: Any, one_phase: bool): pass def rollback(self, xid: Any): pass def recover(self, flag: int) -> List: return [] def forget(self, xid: Any): pass def getTransactionTimeout(self) -> int: return 0 def setTransactionTimeout(self, timeout: int) -> bool: return True def isSameRM(self, xares: "XAResource") -> bool: return self is xares def toString(self) -> str: return f"XAResource@{hex(id(self))}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self) & 0x7FFFFFFF