updated
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# __init__.py
|
||||
#
|
||||
# Package initialization module.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
if sys.version_info[:2] < (3, 8):
|
||||
message = (
|
||||
f"Python {sys.version_info[0]}.{sys.version_info[1]} is no longer "
|
||||
"supported by the Python core team. Therefore, support for it is "
|
||||
"deprecated in python-oracledb and will be removed in a future release"
|
||||
)
|
||||
warnings.warn(message)
|
||||
|
||||
from .version import __version__ as __version__
|
||||
|
||||
from .constants import (
|
||||
# mandated DB API constants
|
||||
apilevel as apilevel,
|
||||
threadsafety as threadsafety,
|
||||
paramstyle as paramstyle,
|
||||
# authentication modes
|
||||
AUTH_MODE_DEFAULT as AUTH_MODE_DEFAULT,
|
||||
AUTH_MODE_PRELIM as AUTH_MODE_PRELIM,
|
||||
AUTH_MODE_SYSASM as AUTH_MODE_SYSASM,
|
||||
AUTH_MODE_SYSBKP as AUTH_MODE_SYSBKP,
|
||||
AUTH_MODE_SYSDBA as AUTH_MODE_SYSDBA,
|
||||
AUTH_MODE_SYSDGD as AUTH_MODE_SYSDGD,
|
||||
AUTH_MODE_SYSKMT as AUTH_MODE_SYSKMT,
|
||||
AUTH_MODE_SYSOPER as AUTH_MODE_SYSOPER,
|
||||
AUTH_MODE_SYSRAC as AUTH_MODE_SYSRAC,
|
||||
# pool "get" modes
|
||||
POOL_GETMODE_WAIT as POOL_GETMODE_WAIT,
|
||||
POOL_GETMODE_NOWAIT as POOL_GETMODE_NOWAIT,
|
||||
POOL_GETMODE_FORCEGET as POOL_GETMODE_FORCEGET,
|
||||
POOL_GETMODE_TIMEDWAIT as POOL_GETMODE_TIMEDWAIT,
|
||||
# purity values
|
||||
PURITY_DEFAULT as PURITY_DEFAULT,
|
||||
PURITY_NEW as PURITY_NEW,
|
||||
PURITY_SELF as PURITY_SELF,
|
||||
# AQ delivery modes
|
||||
MSG_BUFFERED as MSG_BUFFERED,
|
||||
MSG_PERSISTENT as MSG_PERSISTENT,
|
||||
MSG_PERSISTENT_OR_BUFFERED as MSG_PERSISTENT_OR_BUFFERED,
|
||||
# AQ dequeue modes
|
||||
DEQ_BROWSE as DEQ_BROWSE,
|
||||
DEQ_LOCKED as DEQ_LOCKED,
|
||||
DEQ_REMOVE as DEQ_REMOVE,
|
||||
DEQ_REMOVE_NODATA as DEQ_REMOVE_NODATA,
|
||||
# AQ dequeue navigation modes
|
||||
DEQ_FIRST_MSG as DEQ_FIRST_MSG,
|
||||
DEQ_NEXT_MSG as DEQ_NEXT_MSG,
|
||||
DEQ_NEXT_TRANSACTION as DEQ_NEXT_TRANSACTION,
|
||||
# AQ dequeue visibility modes
|
||||
DEQ_IMMEDIATE as DEQ_IMMEDIATE,
|
||||
DEQ_ON_COMMIT as DEQ_ON_COMMIT,
|
||||
# AQ dequeue wait modes
|
||||
DEQ_NO_WAIT as DEQ_NO_WAIT,
|
||||
DEQ_WAIT_FOREVER as DEQ_WAIT_FOREVER,
|
||||
# AQ enqueue visibility modes
|
||||
ENQ_IMMEDIATE as ENQ_IMMEDIATE,
|
||||
ENQ_ON_COMMIT as ENQ_ON_COMMIT,
|
||||
# AQ message states
|
||||
MSG_EXPIRED as MSG_EXPIRED,
|
||||
MSG_PROCESSED as MSG_PROCESSED,
|
||||
MSG_READY as MSG_READY,
|
||||
MSG_WAITING as MSG_WAITING,
|
||||
# AQ other constants
|
||||
MSG_NO_DELAY as MSG_NO_DELAY,
|
||||
MSG_NO_EXPIRATION as MSG_NO_EXPIRATION,
|
||||
# shutdown modes
|
||||
DBSHUTDOWN_ABORT as DBSHUTDOWN_ABORT,
|
||||
DBSHUTDOWN_FINAL as DBSHUTDOWN_FINAL,
|
||||
DBSHUTDOWN_IMMEDIATE as DBSHUTDOWN_IMMEDIATE,
|
||||
DBSHUTDOWN_TRANSACTIONAL as DBSHUTDOWN_TRANSACTIONAL,
|
||||
DBSHUTDOWN_TRANSACTIONAL_LOCAL as DBSHUTDOWN_TRANSACTIONAL_LOCAL,
|
||||
# subscription grouping classes
|
||||
SUBSCR_GROUPING_CLASS_NONE as SUBSCR_GROUPING_CLASS_NONE,
|
||||
SUBSCR_GROUPING_CLASS_TIME as SUBSCR_GROUPING_CLASS_TIME,
|
||||
# subscription grouping types
|
||||
SUBSCR_GROUPING_TYPE_SUMMARY as SUBSCR_GROUPING_TYPE_SUMMARY,
|
||||
SUBSCR_GROUPING_TYPE_LAST as SUBSCR_GROUPING_TYPE_LAST,
|
||||
# subscription namespaces
|
||||
SUBSCR_NAMESPACE_AQ as SUBSCR_NAMESPACE_AQ,
|
||||
SUBSCR_NAMESPACE_DBCHANGE as SUBSCR_NAMESPACE_DBCHANGE,
|
||||
# subscription protocols
|
||||
SUBSCR_PROTO_HTTP as SUBSCR_PROTO_HTTP,
|
||||
SUBSCR_PROTO_MAIL as SUBSCR_PROTO_MAIL,
|
||||
SUBSCR_PROTO_CALLBACK as SUBSCR_PROTO_CALLBACK,
|
||||
SUBSCR_PROTO_SERVER as SUBSCR_PROTO_SERVER,
|
||||
# subscription quality of service
|
||||
SUBSCR_QOS_BEST_EFFORT as SUBSCR_QOS_BEST_EFFORT,
|
||||
SUBSCR_QOS_DEFAULT as SUBSCR_QOS_DEFAULT,
|
||||
SUBSCR_QOS_DEREG_NFY as SUBSCR_QOS_DEREG_NFY,
|
||||
SUBSCR_QOS_QUERY as SUBSCR_QOS_QUERY,
|
||||
SUBSCR_QOS_RELIABLE as SUBSCR_QOS_RELIABLE,
|
||||
SUBSCR_QOS_ROWIDS as SUBSCR_QOS_ROWIDS,
|
||||
# event types
|
||||
EVENT_AQ as EVENT_AQ,
|
||||
EVENT_DEREG as EVENT_DEREG,
|
||||
EVENT_NONE as EVENT_NONE,
|
||||
EVENT_OBJCHANGE as EVENT_OBJCHANGE,
|
||||
EVENT_QUERYCHANGE as EVENT_QUERYCHANGE,
|
||||
EVENT_SHUTDOWN as EVENT_SHUTDOWN,
|
||||
EVENT_SHUTDOWN_ANY as EVENT_SHUTDOWN_ANY,
|
||||
EVENT_STARTUP as EVENT_STARTUP,
|
||||
# operation codes
|
||||
OPCODE_ALLOPS as OPCODE_ALLOPS,
|
||||
OPCODE_ALLROWS as OPCODE_ALLROWS,
|
||||
OPCODE_ALTER as OPCODE_ALTER,
|
||||
OPCODE_DELETE as OPCODE_DELETE,
|
||||
OPCODE_DROP as OPCODE_DROP,
|
||||
OPCODE_INSERT as OPCODE_INSERT,
|
||||
OPCODE_UPDATE as OPCODE_UPDATE,
|
||||
# flags for tpc_begin()
|
||||
TPC_BEGIN_JOIN as TPC_BEGIN_JOIN,
|
||||
TPC_BEGIN_NEW as TPC_BEGIN_NEW,
|
||||
TPC_BEGIN_PROMOTE as TPC_BEGIN_PROMOTE,
|
||||
TPC_BEGIN_RESUME as TPC_BEGIN_RESUME,
|
||||
# flags for tpc_end()
|
||||
TPC_END_NORMAL as TPC_END_NORMAL,
|
||||
TPC_END_SUSPEND as TPC_END_SUSPEND,
|
||||
)
|
||||
|
||||
from .exceptions import (
|
||||
Warning as Warning,
|
||||
Error as Error,
|
||||
DatabaseError as DatabaseError,
|
||||
DataError as DataError,
|
||||
IntegrityError as IntegrityError,
|
||||
InterfaceError as InterfaceError,
|
||||
InternalError as InternalError,
|
||||
NotSupportedError as NotSupportedError,
|
||||
OperationalError as OperationalError,
|
||||
ProgrammingError as ProgrammingError,
|
||||
)
|
||||
|
||||
from .errors import _Error as _Error
|
||||
|
||||
from .defaults import defaults as defaults
|
||||
|
||||
from .connection import (
|
||||
AsyncConnection as AsyncConnection,
|
||||
connect as connect,
|
||||
connect_async as connect_async,
|
||||
Connection as Connection,
|
||||
)
|
||||
|
||||
from .cursor import (
|
||||
AsyncCursor as AsyncCursor,
|
||||
Cursor as Cursor,
|
||||
)
|
||||
|
||||
from .pool import (
|
||||
AsyncConnectionPool as AsyncConnectionPool,
|
||||
ConnectionPool as ConnectionPool,
|
||||
create_pool as create_pool,
|
||||
create_pool_async as create_pool_async,
|
||||
)
|
||||
|
||||
from .connect_params import ConnectParams as ConnectParams
|
||||
|
||||
from .pool_params import PoolParams as PoolParams
|
||||
|
||||
from .lob import (
|
||||
LOB as LOB,
|
||||
AsyncLOB as AsyncLOB,
|
||||
)
|
||||
|
||||
from .dbobject import DbObject as DbObject, DbObjectType as DbObjectType
|
||||
|
||||
from .fetch_info import FetchInfo as FetchInfo
|
||||
|
||||
from .var import Var as Var
|
||||
|
||||
from .dsn import makedsn as makedsn
|
||||
|
||||
from .driver_mode import is_thin_mode as is_thin_mode
|
||||
|
||||
from . import base_impl, thick_impl, thin_impl
|
||||
|
||||
from .base_impl import (
|
||||
# database types
|
||||
DB_TYPE_BFILE as DB_TYPE_BFILE,
|
||||
DB_TYPE_BINARY_DOUBLE as DB_TYPE_BINARY_DOUBLE,
|
||||
DB_TYPE_BINARY_FLOAT as DB_TYPE_BINARY_FLOAT,
|
||||
DB_TYPE_BINARY_INTEGER as DB_TYPE_BINARY_INTEGER,
|
||||
DB_TYPE_BLOB as DB_TYPE_BLOB,
|
||||
DB_TYPE_BOOLEAN as DB_TYPE_BOOLEAN,
|
||||
DB_TYPE_CHAR as DB_TYPE_CHAR,
|
||||
DB_TYPE_CLOB as DB_TYPE_CLOB,
|
||||
DB_TYPE_CURSOR as DB_TYPE_CURSOR,
|
||||
DB_TYPE_DATE as DB_TYPE_DATE,
|
||||
DB_TYPE_INTERVAL_DS as DB_TYPE_INTERVAL_DS,
|
||||
DB_TYPE_INTERVAL_YM as DB_TYPE_INTERVAL_YM,
|
||||
DB_TYPE_JSON as DB_TYPE_JSON,
|
||||
DB_TYPE_LONG as DB_TYPE_LONG,
|
||||
DB_TYPE_LONG_NVARCHAR as DB_TYPE_LONG_NVARCHAR,
|
||||
DB_TYPE_LONG_RAW as DB_TYPE_LONG_RAW,
|
||||
DB_TYPE_NCHAR as DB_TYPE_NCHAR,
|
||||
DB_TYPE_NCLOB as DB_TYPE_NCLOB,
|
||||
DB_TYPE_NUMBER as DB_TYPE_NUMBER,
|
||||
DB_TYPE_NVARCHAR as DB_TYPE_NVARCHAR,
|
||||
DB_TYPE_OBJECT as DB_TYPE_OBJECT,
|
||||
DB_TYPE_RAW as DB_TYPE_RAW,
|
||||
DB_TYPE_ROWID as DB_TYPE_ROWID,
|
||||
DB_TYPE_TIMESTAMP as DB_TYPE_TIMESTAMP,
|
||||
DB_TYPE_TIMESTAMP_LTZ as DB_TYPE_TIMESTAMP_LTZ,
|
||||
DB_TYPE_TIMESTAMP_TZ as DB_TYPE_TIMESTAMP_TZ,
|
||||
DB_TYPE_UNKNOWN as DB_TYPE_UNKNOWN,
|
||||
DB_TYPE_UROWID as DB_TYPE_UROWID,
|
||||
DB_TYPE_VARCHAR as DB_TYPE_VARCHAR,
|
||||
DB_TYPE_XMLTYPE as DB_TYPE_XMLTYPE,
|
||||
# API types
|
||||
BINARY as BINARY,
|
||||
DATETIME as DATETIME,
|
||||
NUMBER as NUMBER,
|
||||
ROWID as ROWID,
|
||||
STRING as STRING,
|
||||
)
|
||||
|
||||
from .thick_impl import (
|
||||
clientversion as clientversion,
|
||||
init_oracle_client as init_oracle_client,
|
||||
)
|
||||
|
||||
from .constructors import (
|
||||
Binary as Binary,
|
||||
Date as Date,
|
||||
DateFromTicks as DateFromTicks,
|
||||
Time as Time,
|
||||
TimeFromTicks as TimeFromTicks,
|
||||
Timestamp as Timestamp,
|
||||
TimestampFromTicks as TimestampFromTicks,
|
||||
)
|
||||
|
||||
from .future import (
|
||||
future as __future__, # noqa: F401
|
||||
)
|
||||
|
||||
package = sys.modules[__name__]
|
||||
base_impl.init_base_impl(package)
|
||||
thick_impl.init_thick_impl(package)
|
||||
thin_impl.init_thin_impl(package)
|
||||
del package
|
||||
|
||||
# remove unnecessary symbols
|
||||
del sys, warnings
|
||||
del aq, base_impl, connect_params, connection, constants, constructors # noqa
|
||||
del cursor, dbobject, driver_mode, dsn, errors, exceptions, fetch_info # noqa
|
||||
del future, lob, pool, pool_params, soda, subscr, thick_impl, thin_impl # noqa
|
||||
del utils, var # noqa
|
||||
|
||||
# general aliases (for backwards compatibility)
|
||||
ObjectType = DbObjectType
|
||||
Object = DbObject
|
||||
SessionPool = ConnectionPool
|
||||
version = __version__
|
||||
|
||||
# aliases for database types (for backwards compatibility)
|
||||
BFILE = DB_TYPE_BFILE
|
||||
BLOB = DB_TYPE_BLOB
|
||||
BOOLEAN = DB_TYPE_BOOLEAN
|
||||
CLOB = DB_TYPE_CLOB
|
||||
CURSOR = DB_TYPE_CURSOR
|
||||
FIXED_CHAR = DB_TYPE_CHAR
|
||||
FIXED_NCHAR = DB_TYPE_NCHAR
|
||||
INTERVAL = DB_TYPE_INTERVAL_DS
|
||||
LONG_BINARY = DB_TYPE_LONG_RAW
|
||||
LONG_STRING = DB_TYPE_LONG
|
||||
NATIVE_INT = DB_TYPE_BINARY_INTEGER
|
||||
NATIVE_FLOAT = DB_TYPE_BINARY_DOUBLE
|
||||
NCHAR = DB_TYPE_NVARCHAR
|
||||
OBJECT = DB_TYPE_OBJECT
|
||||
NCLOB = DB_TYPE_NCLOB
|
||||
TIMESTAMP = DB_TYPE_TIMESTAMP
|
||||
|
||||
# aliases for authhentication modes (for backwards compatibility)
|
||||
DEFAULT_AUTH = AUTH_MODE_DEFAULT
|
||||
SYSASM = AUTH_MODE_SYSASM
|
||||
SYSBKP = AUTH_MODE_SYSBKP
|
||||
SYSDBA = AUTH_MODE_SYSDBA
|
||||
SYSDGD = AUTH_MODE_SYSDGD
|
||||
SYSKMT = AUTH_MODE_SYSKMT
|
||||
SYSOPER = AUTH_MODE_SYSOPER
|
||||
SYSRAC = AUTH_MODE_SYSRAC
|
||||
PRELIM_AUTH = AUTH_MODE_PRELIM
|
||||
|
||||
# aliases for pool "get" modes (for backwards compatibility)
|
||||
SPOOL_ATTRVAL_WAIT = POOL_GETMODE_WAIT
|
||||
SPOOL_ATTRVAL_NOWAIT = POOL_GETMODE_NOWAIT
|
||||
SPOOL_ATTRVAL_FORCEGET = POOL_GETMODE_FORCEGET
|
||||
SPOOL_ATTRVAL_TIMEDWAIT = POOL_GETMODE_TIMEDWAIT
|
||||
|
||||
# aliases for purity (for backwards compatibility)
|
||||
ATTR_PURITY_DEFAULT = PURITY_DEFAULT
|
||||
ATTR_PURITY_NEW = PURITY_NEW
|
||||
ATTR_PURITY_SELF = PURITY_SELF
|
||||
|
||||
# aliases for subscription protocols (for backwards compatibility)
|
||||
SUBSCR_PROTO_OCI = SUBSCR_PROTO_CALLBACK
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,553 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# aq.py
|
||||
#
|
||||
# Contains the classes used for handling Advanced Queuing (AQ): Queue,
|
||||
# DeqOptions, EnqOptions and MessageProperties.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import datetime
|
||||
|
||||
from . import connection as connection_module
|
||||
from typing import Any, Union, List
|
||||
from . import errors
|
||||
from .dbobject import DbObject, DbObjectType
|
||||
|
||||
|
||||
class Queue:
|
||||
@classmethod
|
||||
def _from_impl(cls, connection, impl):
|
||||
queue = cls.__new__(cls)
|
||||
queue._connection = connection
|
||||
queue._deq_options = DeqOptions._from_impl(impl.deq_options_impl)
|
||||
queue._enq_options = EnqOptions._from_impl(impl.enq_options_impl)
|
||||
queue._payload_type = None
|
||||
queue._impl = impl
|
||||
return queue
|
||||
|
||||
def _verify_message(self, message: "MessageProperties") -> None:
|
||||
"""
|
||||
Internal method used for verifying a message.
|
||||
"""
|
||||
if not isinstance(message, MessageProperties):
|
||||
raise TypeError("expecting MessageProperties object")
|
||||
if message.payload is None:
|
||||
errors._raise_err(errors.ERR_MESSAGE_HAS_NO_PAYLOAD)
|
||||
|
||||
@property
|
||||
def connection(self) -> "connection_module.Connection":
|
||||
"""
|
||||
Returns the connection on which the queue was created.
|
||||
"""
|
||||
return self._connection
|
||||
|
||||
def deqmany(self, max_num_messages: int) -> list:
|
||||
"""
|
||||
Dequeues up to the specified number of messages from the queue and
|
||||
returns a list of these messages.
|
||||
"""
|
||||
message_impls = self._impl.deq_many(max_num_messages)
|
||||
return [MessageProperties._from_impl(impl) for impl in message_impls]
|
||||
|
||||
def deqMany(self, max_num_messages: int) -> List["MessageProperties"]:
|
||||
"""
|
||||
Deprecated: use deqmany() instead.
|
||||
"""
|
||||
return self.deqmany(max_num_messages)
|
||||
|
||||
def deqone(self) -> Union["MessageProperties", None]:
|
||||
"""
|
||||
Dequeues at most one message from the queue and returns it. If no
|
||||
message is dequeued, None is returned.
|
||||
"""
|
||||
message_impl = self._impl.deq_one()
|
||||
if message_impl is not None:
|
||||
return MessageProperties._from_impl(message_impl)
|
||||
|
||||
def deqOne(self) -> Union["MessageProperties", None]:
|
||||
"""
|
||||
Deprecated: use deqone() instead.
|
||||
"""
|
||||
return self.deqone()
|
||||
|
||||
@property
|
||||
def deqoptions(self) -> "DeqOptions":
|
||||
"""
|
||||
Returns the options that will be used when dequeuing messages from the
|
||||
queue.
|
||||
"""
|
||||
return self._deq_options
|
||||
|
||||
@property
|
||||
def deqOptions(self) -> "DeqOptions":
|
||||
"""
|
||||
Deprecated: use deqoptions instead.
|
||||
"""
|
||||
return self.deqoptions
|
||||
|
||||
def enqmany(self, messages: list) -> None:
|
||||
"""
|
||||
Enqueues multiple messages into the queue. The messages parameter must
|
||||
be a sequence containing message property objects which have all had
|
||||
their payload attribute set to a value that the queue supports.
|
||||
|
||||
Warning: calling this function in parallel on different connections
|
||||
acquired from the same pool may fail due to Oracle bug 29928074. Ensure
|
||||
that this function is not run in parallel, use standalone connections
|
||||
or connections from different pools, or make multiple calls to
|
||||
enqOne() instead. The function Queue.deqMany() call is not affected.
|
||||
"""
|
||||
for message in messages:
|
||||
self._verify_message(message)
|
||||
message_impls = [m._impl for m in messages]
|
||||
self._impl.enq_many(message_impls)
|
||||
|
||||
def enqMany(self, messages: list) -> None:
|
||||
"""
|
||||
Deprecated: use enqmany() instead.
|
||||
"""
|
||||
return self.enqmany(messages)
|
||||
|
||||
def enqone(self, message: "MessageProperties") -> None:
|
||||
"""
|
||||
Enqueues a single message into the queue. The message must be a message
|
||||
property object which has had its payload attribute set to a value that
|
||||
the queue supports.
|
||||
"""
|
||||
self._verify_message(message)
|
||||
self._impl.enq_one(message._impl)
|
||||
|
||||
def enqOne(self, message: "MessageProperties") -> None:
|
||||
"""
|
||||
Deprecated: use enqone() instead.
|
||||
"""
|
||||
return self.enqone(message)
|
||||
|
||||
@property
|
||||
def enqoptions(self) -> "EnqOptions":
|
||||
"""
|
||||
Returns the options that will be used when enqueuing messages into the
|
||||
queue.
|
||||
"""
|
||||
return self._enq_options
|
||||
|
||||
@property
|
||||
def enqOptions(self) -> "EnqOptions":
|
||||
"""
|
||||
Deprecated: use enqoptions() instead.
|
||||
"""
|
||||
return self.enqoptions
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Returns the name of the queue.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
@property
|
||||
def payload_type(self) -> Union[DbObjectType, None]:
|
||||
"""
|
||||
Returns the object type for payloads that can be enqueued and dequeued.
|
||||
If using a raw queue, this returns the value None.
|
||||
"""
|
||||
if self._payload_type is None:
|
||||
if self._impl.is_json:
|
||||
self._payload_type = "JSON"
|
||||
elif self._impl.payload_type is not None:
|
||||
self._payload_type = DbObjectType._from_impl(
|
||||
self._impl.payload_type
|
||||
)
|
||||
return self._payload_type
|
||||
|
||||
@property
|
||||
def payloadType(self) -> Union[DbObjectType, None]:
|
||||
"""
|
||||
Deprecated: use payload_type instead.
|
||||
"""
|
||||
return self.payload_type
|
||||
|
||||
|
||||
class DeqOptions:
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
options = cls.__new__(cls)
|
||||
options._impl = impl
|
||||
return options
|
||||
|
||||
@property
|
||||
def condition(self) -> str:
|
||||
"""
|
||||
Specifies a boolean expression similar to the where clause of a SQL
|
||||
query. The boolean expression can include conditions on message
|
||||
properties, user data properties and PL/SQL or SQL functions. The
|
||||
default is to have no condition specified.
|
||||
"""
|
||||
return self._impl.get_condition()
|
||||
|
||||
@condition.setter
|
||||
def condition(self, value: str) -> None:
|
||||
self._impl.set_condition(value)
|
||||
|
||||
@property
|
||||
def consumername(self) -> str:
|
||||
"""
|
||||
Specifies the name of the consumer. Only messages matching the consumer
|
||||
name will be accessed. If the queue is not set up for multiple
|
||||
consumers this attribute should not be set. The default is to have no
|
||||
consumer name specified.
|
||||
"""
|
||||
return self._impl.get_consumer_name()
|
||||
|
||||
@consumername.setter
|
||||
def consumername(self, value: str) -> None:
|
||||
self._impl.set_consumer_name(value)
|
||||
|
||||
@property
|
||||
def correlation(self) -> str:
|
||||
"""
|
||||
Specifies the correlation identifier of the message to be dequeued.
|
||||
Special pattern-matching characters, such as the percent sign (%) and
|
||||
the underscore (_), can be used. If multiple messages satisfy the
|
||||
pattern, the order of dequeuing is indeterminate. The default is to
|
||||
have no correlation specified.
|
||||
"""
|
||||
return self._impl.get_correlation()
|
||||
|
||||
@correlation.setter
|
||||
def correlation(self, value: str) -> None:
|
||||
self._impl.set_correlation(value)
|
||||
|
||||
@property
|
||||
def deliverymode(self) -> None:
|
||||
"""
|
||||
Specifies what types of messages should be dequeued. It should be one
|
||||
of the values MSG_PERSISTENT (default), MSG_BUFFERED or
|
||||
MSG_PERSISTENT_OR_BUFFERED.
|
||||
"""
|
||||
raise AttributeError("deliverymode can only be written")
|
||||
|
||||
@deliverymode.setter
|
||||
def deliverymode(self, value: int) -> None:
|
||||
self._impl.set_delivery_mode(value)
|
||||
|
||||
@property
|
||||
def mode(self) -> int:
|
||||
"""
|
||||
Specifies the locking behaviour associated with the dequeue operation.
|
||||
It should be one of the values DEQ_BROWSE, DEQ_LOCKED, DEQ_REMOVE
|
||||
(default), or DEQ_REMOVE_NODATA.
|
||||
"""
|
||||
return self._impl.get_mode()
|
||||
|
||||
@mode.setter
|
||||
def mode(self, value: int) -> None:
|
||||
self._impl.set_mode(value)
|
||||
|
||||
@property
|
||||
def msgid(self) -> bytes:
|
||||
"""
|
||||
Specifies the identifier of the message to be dequeued. The default is
|
||||
to have no message identifier specified.
|
||||
"""
|
||||
return self._impl.get_message_id()
|
||||
|
||||
@msgid.setter
|
||||
def msgid(self, value: bytes) -> None:
|
||||
self._impl.set_message_id(value)
|
||||
|
||||
@property
|
||||
def navigation(self) -> int:
|
||||
"""
|
||||
Specifies the position of the message that is retrieved. It should be
|
||||
one of the values DEQ_FIRST_MSG, DEQ_NEXT_MSG (default), or
|
||||
DEQ_NEXT_TRANSACTION.
|
||||
"""
|
||||
return self._impl.get_navigation()
|
||||
|
||||
@navigation.setter
|
||||
def navigation(self, value: int) -> None:
|
||||
self._impl.set_navigation(value)
|
||||
|
||||
@property
|
||||
def transformation(self) -> str:
|
||||
"""
|
||||
Specifies the name of the transformation that must be applied after the
|
||||
message is dequeued from the database but before it is returned to the
|
||||
calling application. The transformation must be created using
|
||||
dbms_transform. The default is to have no transformation specified.
|
||||
"""
|
||||
return self._impl.get_transformation()
|
||||
|
||||
@transformation.setter
|
||||
def transformation(self, value: str) -> None:
|
||||
self._impl.set_transformation(value)
|
||||
|
||||
@property
|
||||
def visibility(self) -> int:
|
||||
"""
|
||||
Specifies the transactional behavior of the dequeue request. It should
|
||||
be one of the values DEQ_ON_COMMIT (default) or DEQ_IMMEDIATE. This
|
||||
attribute is ignored when using the DEQ_BROWSE mode. Note the value of
|
||||
autocommit is always ignored.
|
||||
"""
|
||||
return self._impl.get_visibility()
|
||||
|
||||
@visibility.setter
|
||||
def visibility(self, value: int) -> None:
|
||||
self._impl.set_visibility(value)
|
||||
|
||||
@property
|
||||
def wait(self) -> int:
|
||||
"""
|
||||
Specifies the time to wait, in seconds, for a message matching the
|
||||
search criteria to become available for dequeuing. One of the values
|
||||
DEQ_NO_WAIT or DEQ_WAIT_FOREVER can also be used. The default is
|
||||
DEQ_WAIT_FOREVER.
|
||||
"""
|
||||
return self._impl.get_wait()
|
||||
|
||||
@wait.setter
|
||||
def wait(self, value: int) -> None:
|
||||
self._impl.set_wait(value)
|
||||
|
||||
|
||||
class EnqOptions:
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
options = cls.__new__(cls)
|
||||
options._impl = impl
|
||||
return options
|
||||
|
||||
@property
|
||||
def deliverymode(self) -> int:
|
||||
"""
|
||||
Specifies what type of messages should be enqueued. It should be one of
|
||||
the values MSG_PERSISTENT (default) or MSG_BUFFERED.
|
||||
"""
|
||||
raise AttributeError("deliverymode can only be written")
|
||||
|
||||
@deliverymode.setter
|
||||
def deliverymode(self, value: int) -> None:
|
||||
self._impl.set_delivery_mode(value)
|
||||
|
||||
@property
|
||||
def transformation(self) -> str:
|
||||
"""
|
||||
Specifies the name of the transformation that must be applied before
|
||||
the message is enqueued into the database. The transformation must be
|
||||
created using dbms_transform. The default is to have no transformation
|
||||
specified.
|
||||
"""
|
||||
return self._impl.get_transformation()
|
||||
|
||||
@transformation.setter
|
||||
def transformation(self, value: str) -> None:
|
||||
self._impl.set_transformation(value)
|
||||
|
||||
@property
|
||||
def visibility(self) -> int:
|
||||
"""
|
||||
Specifies the transactional behavior of the enqueue request. It should
|
||||
be one of the values ENQ_ON_COMMIT (default) or ENQ_IMMEDIATE. Note the
|
||||
value of autocommit is ignored.
|
||||
"""
|
||||
return self._impl.get_visibility()
|
||||
|
||||
@visibility.setter
|
||||
def visibility(self, value: int) -> None:
|
||||
self._impl.set_visibility(value)
|
||||
|
||||
|
||||
class MessageProperties:
|
||||
_recipients = []
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
props = cls.__new__(cls)
|
||||
props._impl = impl
|
||||
return props
|
||||
|
||||
@property
|
||||
def attempts(self) -> int:
|
||||
"""
|
||||
Specifies the number of attempts that have been made to dequeue the
|
||||
message.
|
||||
"""
|
||||
return self._impl.get_num_attempts()
|
||||
|
||||
@property
|
||||
def correlation(self) -> str:
|
||||
"""
|
||||
Specifies the correlation used when the message was enqueued.
|
||||
"""
|
||||
return self._impl.get_correlation()
|
||||
|
||||
@correlation.setter
|
||||
def correlation(self, value: str) -> None:
|
||||
self._impl.set_correlation(value)
|
||||
|
||||
@property
|
||||
def delay(self) -> int:
|
||||
"""
|
||||
Specifies the number of seconds to delay an enqueued message. Any
|
||||
integer is acceptable but the constant MSG_NO_DELAY can also be used
|
||||
indicating that the message is available for immediate dequeuing.
|
||||
"""
|
||||
return self._impl.get_delay()
|
||||
|
||||
@delay.setter
|
||||
def delay(self, value: int) -> None:
|
||||
self._impl.set_delay(value)
|
||||
|
||||
@property
|
||||
def deliverymode(self) -> int:
|
||||
"""
|
||||
Specifies the type of message that was dequeued. It will be one of the
|
||||
values MSG_PERSISTENT or MSG_BUFFERED.
|
||||
"""
|
||||
return self._impl.get_delivery_mode()
|
||||
|
||||
@property
|
||||
def enqtime(self) -> datetime.datetime:
|
||||
"""
|
||||
Specifies the time that the message was enqueued.
|
||||
"""
|
||||
return self._impl.get_enq_time()
|
||||
|
||||
@property
|
||||
def exceptionq(self) -> str:
|
||||
"""
|
||||
Specifies the name of the queue to which the message is moved if it
|
||||
cannot be processed successfully. Messages are moved if the number of
|
||||
unsuccessful dequeue attempts has exceeded the maximum number of
|
||||
retries or if the message has expired. All messages in the exception
|
||||
queue are in the MSG_EXPIRED state. The default value is the name of
|
||||
the exception queue associated with the queue table.
|
||||
"""
|
||||
return self._impl.get_exception_queue()
|
||||
|
||||
@exceptionq.setter
|
||||
def exceptionq(self, value: str) -> None:
|
||||
self._impl.set_exception_queue(value)
|
||||
|
||||
@property
|
||||
def expiration(self) -> int:
|
||||
"""
|
||||
Specifies, in seconds, how long the message is available for dequeuing.
|
||||
This attribute is an offset from the delay attribute. Expiration
|
||||
processing requires the queue monitor to be running. Any integer is
|
||||
accepted but the constant MSG_NO_EXPIRATION can also be used indicating
|
||||
that the message never expires.
|
||||
"""
|
||||
return self._impl.get_expiration()
|
||||
|
||||
@expiration.setter
|
||||
def expiration(self, value: int) -> None:
|
||||
self._impl.set_expiration(value)
|
||||
|
||||
@property
|
||||
def msgid(self) -> bytes:
|
||||
"""
|
||||
Specifies the id of the message in the last queue that enqueued or
|
||||
dequeued this message. If the message has never been dequeued or
|
||||
enqueued, the value will be `None`.
|
||||
"""
|
||||
return self._impl.get_message_id()
|
||||
|
||||
@property
|
||||
def payload(self) -> Union[bytes, DbObject]:
|
||||
"""
|
||||
Specifies the payload that will be enqueued or the payload that was
|
||||
dequeued when using a queue. When enqueuing, the value is checked to
|
||||
ensure that it conforms to the type expected by that queue. For RAW
|
||||
queues, the value can be a bytes object or a string. If the value is a
|
||||
string it will be converted to bytes in the encoding UTF-8.
|
||||
"""
|
||||
return self._impl.payload
|
||||
|
||||
@payload.setter
|
||||
def payload(self, value: Any) -> None:
|
||||
if isinstance(value, DbObject):
|
||||
self._impl.set_payload_object(value._impl)
|
||||
elif not isinstance(value, (str, bytes)):
|
||||
self._impl.set_payload_json(value)
|
||||
else:
|
||||
if isinstance(value, str):
|
||||
value_bytes = value.encode()
|
||||
elif isinstance(value, bytes):
|
||||
value_bytes = value
|
||||
self._impl.set_payload_bytes(value_bytes)
|
||||
self._impl.payload = value
|
||||
|
||||
@property
|
||||
def priority(self) -> int:
|
||||
"""
|
||||
Specifies the priority of the message. A smaller number indicates a
|
||||
higher priority. The priority can be any integer, including negative
|
||||
numbers. The default value is zero.
|
||||
"""
|
||||
return self._impl.get_priority()
|
||||
|
||||
@priority.setter
|
||||
def priority(self, value: int) -> None:
|
||||
self._impl.set_priority(value)
|
||||
|
||||
@property
|
||||
def recipients(self) -> list:
|
||||
"""
|
||||
A list of recipient names can be associated with a message at the time
|
||||
a message is enqueued. This allows a limited set of recipients to
|
||||
dequeue each message. The recipient list associated with the message
|
||||
overrides the queue subscriber list, if there is one. The recipient
|
||||
names need not be in the subscriber list but can be, if desired.
|
||||
|
||||
To dequeue a message, the consumername attribute can be set to one of
|
||||
the recipient names. The original message recipient list is not
|
||||
available on dequeued messages. All recipients have to dequeue a
|
||||
message before it gets removed from the queue.
|
||||
|
||||
Subscribing to a queue is like subscribing to a magazine: each
|
||||
subscriber can dequeue all the messages placed into a specific queue,
|
||||
just as each magazine subscriber has access to all its articles. Being
|
||||
a recipient, however, is like getting a letter: each recipient is a
|
||||
designated target of a particular message.
|
||||
"""
|
||||
return self._recipients
|
||||
|
||||
@recipients.setter
|
||||
def recipients(self, value: list) -> None:
|
||||
self._impl.set_recipients(value)
|
||||
self._recipients = value
|
||||
|
||||
@property
|
||||
def state(self) -> int:
|
||||
"""
|
||||
Specifies the state of the message at the time of the dequeue. It will
|
||||
be one of the values MSG_WAITING, MSG_READY, MSG_PROCESSED or
|
||||
MSG_EXPIRED.
|
||||
"""
|
||||
return self._impl.get_state()
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,878 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# connect_params.py
|
||||
#
|
||||
# Contains the ConnectParams class used for managing the parameters required to
|
||||
# establish a connection to the database.
|
||||
#
|
||||
# *** NOTICE *** This file is generated from a template and should not be
|
||||
# modified directly. See build_from_template.py in the utils subdirectory for
|
||||
# more information.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import functools
|
||||
from typing import Union, Callable, Any
|
||||
|
||||
import oracledb
|
||||
|
||||
from . import base_impl, utils
|
||||
|
||||
|
||||
class ConnectParams:
|
||||
"""
|
||||
Contains all parameters used for establishing a connection to the
|
||||
database.
|
||||
"""
|
||||
|
||||
__module__ = oracledb.__name__
|
||||
__slots__ = ["_impl"]
|
||||
_impl_class = base_impl.ConnectParamsImpl
|
||||
|
||||
@utils.params_initer
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
user: str = None,
|
||||
proxy_user: str = None,
|
||||
password: str = None,
|
||||
newpassword: str = None,
|
||||
wallet_password: str = None,
|
||||
access_token: Union[str, tuple, Callable] = None,
|
||||
host: str = None,
|
||||
port: int = 1521,
|
||||
protocol: str = "tcp",
|
||||
https_proxy: str = None,
|
||||
https_proxy_port: int = 0,
|
||||
service_name: str = None,
|
||||
sid: str = None,
|
||||
server_type: str = None,
|
||||
cclass: str = None,
|
||||
purity: int = oracledb.PURITY_DEFAULT,
|
||||
expire_time: int = 0,
|
||||
retry_count: int = 0,
|
||||
retry_delay: int = 0,
|
||||
tcp_connect_timeout: float = 60.0,
|
||||
ssl_server_dn_match: bool = True,
|
||||
ssl_server_cert_dn: str = None,
|
||||
wallet_location: str = None,
|
||||
events: bool = False,
|
||||
externalauth: bool = False,
|
||||
mode: int = oracledb.AUTH_MODE_DEFAULT,
|
||||
disable_oob: bool = False,
|
||||
stmtcachesize: int = oracledb.defaults.stmtcachesize,
|
||||
edition: str = None,
|
||||
tag: str = None,
|
||||
matchanytag: bool = False,
|
||||
config_dir: str = oracledb.defaults.config_dir,
|
||||
appcontext: list = None,
|
||||
shardingkey: list = None,
|
||||
supershardingkey: list = None,
|
||||
debug_jdwp: str = None,
|
||||
connection_id_prefix: str = None,
|
||||
ssl_context: Any = None,
|
||||
sdu: int = 8192,
|
||||
handle: int = 0,
|
||||
):
|
||||
"""
|
||||
All parameters are optional. A brief description of each parameter
|
||||
follows:
|
||||
|
||||
- user: the name of the user to connect to (default: None)
|
||||
|
||||
- proxy_user: the name of the proxy user to connect to. If this value
|
||||
is not specified, it will be parsed out of user if user is in the
|
||||
form "user[proxy_user]" (default: None)
|
||||
|
||||
- password: the password for the user (default: None)
|
||||
|
||||
- newpassword: the new password for the user. The new password will
|
||||
take effect immediately upon a successful connection to the database
|
||||
(default: None)
|
||||
|
||||
- wallet_password: the password to use to decrypt the wallet, if it is
|
||||
encrypted. This value is only used in thin mode (default: None)
|
||||
|
||||
- access_token: expected to be a string or a 2-tuple or a callable. If
|
||||
it is a string, it specifies an Azure AD OAuth2 token used for Open
|
||||
Authorization (OAuth 2.0) token based authentication. If it is a
|
||||
2-tuple, it specifies the token and private key strings used for
|
||||
Oracle Cloud Infrastructure (OCI) Identity and Access Management
|
||||
(IAM) token based authentication. If it is a callable, it returns
|
||||
either a string or a 2-tuple used for OAuth 2.0 or OCI IAM token
|
||||
based authentication and is useful when the pool needs to expand and
|
||||
create new connections but the current authentication token has
|
||||
expired (default: None)
|
||||
|
||||
- host: the name or IP address of the machine hosting the database or
|
||||
the database listener (default: None)
|
||||
|
||||
- port: the port number on which the database listener is listening
|
||||
(default: 1521)
|
||||
|
||||
- protocol: one of the strings "tcp" or "tcps" indicating whether to
|
||||
use unencrypted network traffic or encrypted network traffic (TLS)
|
||||
(default: "tcp")
|
||||
|
||||
- https_proxy: the name or IP address of a proxy host to use for
|
||||
tunneling secure connections (default: None)
|
||||
|
||||
- https_proxy_port: the port on which to communicate with the proxy
|
||||
host (default: 0)
|
||||
|
||||
- service_name: the service name of the database (default: None)
|
||||
|
||||
- sid: the system identifier (SID) of the database. Note using a
|
||||
service_name instead is recommended (default: None)
|
||||
|
||||
- server_type: the type of server connection that should be
|
||||
established. If specified, it should be one of "dedicated", "shared"
|
||||
or "pooled" (default: None)
|
||||
|
||||
- cclass: connection class to use for Database Resident Connection
|
||||
Pooling (DRCP) (default: None)
|
||||
|
||||
- purity: purity to use for Database Resident Connection Pooling (DRCP)
|
||||
(default: oracledb.PURITY_DEFAULT)
|
||||
|
||||
- expire_time: an integer indicating the number of minutes between the
|
||||
sending of keepalive probes. If this parameter is set to a value
|
||||
greater than zero it enables keepalive (default: 0)
|
||||
|
||||
- retry_count: the number of times that a connection attempt should be
|
||||
retried before the attempt is terminated (default: 0)
|
||||
|
||||
- retry_delay: the number of seconds to wait before making a new
|
||||
connection attempt (default: 0)
|
||||
|
||||
- tcp_connect_timeout: a float indicating the maximum number of seconds
|
||||
to wait for establishing a connection to the database host (default:
|
||||
60.0)
|
||||
|
||||
- ssl_server_dn_match: boolean indicating whether the server
|
||||
certificate distinguished name (DN) should be matched in addition to
|
||||
the regular certificate verification that is performed. Note that if
|
||||
the ssl_server_cert_dn parameter is not privided, host name matching
|
||||
is performed instead (default: True)
|
||||
|
||||
- ssl_server_cert_dn: the distinguished name (DN) which should be
|
||||
matched with the server. This value is ignored if the
|
||||
ssl_server_dn_match parameter is not set to the value True. If
|
||||
specified this value is used for any verfication. Otherwise the
|
||||
hostname will be used. (default: None)
|
||||
|
||||
- wallet_location: the directory where the wallet can be found. In thin
|
||||
mode this must be the directory containing the PEM-encoded wallet
|
||||
file ewallet.pem. In thick mode this must be the directory containing
|
||||
the file cwallet.sso (default: None)
|
||||
|
||||
- events: boolean specifying whether events mode should be enabled.
|
||||
This value is only used in thick mode and is needed for continuous
|
||||
query notification and high availability event notifications
|
||||
(default: False)
|
||||
|
||||
- externalauth: a boolean indicating whether to use external
|
||||
authentication (default: False)
|
||||
|
||||
- mode: authorization mode to use. For example
|
||||
oracledb.AUTH_MODE_SYSDBA (default: oracledb.AUTH_MODE_DEFAULT)
|
||||
|
||||
- disable_oob: boolean indicating whether out-of-band breaks should be
|
||||
disabled. This value is only used in thin mode. It has no effect on
|
||||
Windows which does not support this functionality (default: False)
|
||||
|
||||
- stmtcachesize: identifies the initial size of the statement cache
|
||||
(default: oracledb.defaults.stmtcachesize)
|
||||
|
||||
- edition: edition to use for the connection. This parameter cannot be
|
||||
used simultaneously with the cclass parameter (default: None)
|
||||
|
||||
- tag: identifies the type of connection that should be returned from a
|
||||
pool. This value is only used in thick mode (default: None)
|
||||
|
||||
- matchanytag: boolean specifying whether any tag can be used when
|
||||
acquiring a connection from the pool. This value is only used in
|
||||
thick mode. (default: False)
|
||||
|
||||
- config_dir: directory in which the optional tnsnames.ora
|
||||
configuration file is located. This value is only used in thin mode.
|
||||
For thick mode use the config_dir parameter of init_oracle_client()
|
||||
(default: oracledb.defaults.config_dir)
|
||||
|
||||
- appcontext: application context used by the connection. It should be
|
||||
a list of 3-tuples (namespace, name, value) and each entry in the
|
||||
tuple should be a string. This value is only used in thick mode
|
||||
(default: None)
|
||||
|
||||
- shardingkey: a list of strings, numbers, bytes or dates that identify
|
||||
the database shard to connect to. This value is only used in thick
|
||||
mode (default: None)
|
||||
|
||||
- supershardingkey: a list of strings, numbers, bytes or dates that
|
||||
identify the database shard to connect to. This value is only used in
|
||||
thick mode (default: None)
|
||||
|
||||
- debug_jdwp: a string with the format "host=<host>;port=<port>" that
|
||||
specifies the host and port of the PL/SQL debugger. This value is
|
||||
only used in thin mode. For thick mode set the ORA_DEBUG_JDWP
|
||||
environment variable (default: None)
|
||||
|
||||
- connection_id_prefix: an application specific prefix that is added to
|
||||
the connection identifier used for tracing (default: None)
|
||||
|
||||
- ssl_context: an SSLContext object used for connecting to the database
|
||||
using TLS. This SSL context will be modified to include the private
|
||||
key or any certificates found in a separately supplied wallet. This
|
||||
parameter should only be specified if the default SSLContext object
|
||||
cannot be used (default: None)
|
||||
|
||||
- sdu: the requested size of the Session Data Unit (SDU), in bytes. The
|
||||
value tunes internal buffers used for communication to the database.
|
||||
Bigger values can increase throughput for large queries or bulk data
|
||||
loads, but at the cost of higher memory use. The SDU size that will
|
||||
actually be used is negotiated down to the lower of this value and
|
||||
the database network SDU configuration value (default: 8192)
|
||||
|
||||
- handle: an integer representing a pointer to a valid service context
|
||||
handle. This value is only used in thick mode. It should be used with
|
||||
extreme caution (default: 0)
|
||||
"""
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
self.__class__.__qualname__
|
||||
+ "("
|
||||
+ f"user={self.user!r}, "
|
||||
+ f"proxy_user={self.proxy_user!r}, "
|
||||
+ f"host={self.host!r}, "
|
||||
+ f"port={self.port!r}, "
|
||||
+ f"protocol={self.protocol!r}, "
|
||||
+ f"https_proxy={self.https_proxy!r}, "
|
||||
+ f"https_proxy_port={self.https_proxy_port!r}, "
|
||||
+ f"service_name={self.service_name!r}, "
|
||||
+ f"sid={self.sid!r}, "
|
||||
+ f"server_type={self.server_type!r}, "
|
||||
+ f"cclass={self.cclass!r}, "
|
||||
+ f"purity={self.purity!r}, "
|
||||
+ f"expire_time={self.expire_time!r}, "
|
||||
+ f"retry_count={self.retry_count!r}, "
|
||||
+ f"retry_delay={self.retry_delay!r}, "
|
||||
+ f"tcp_connect_timeout={self.tcp_connect_timeout!r}, "
|
||||
+ f"ssl_server_dn_match={self.ssl_server_dn_match!r}, "
|
||||
+ f"ssl_server_cert_dn={self.ssl_server_cert_dn!r}, "
|
||||
+ f"wallet_location={self.wallet_location!r}, "
|
||||
+ f"events={self.events!r}, "
|
||||
+ f"externalauth={self.externalauth!r}, "
|
||||
+ f"mode={self.mode!r}, "
|
||||
+ f"disable_oob={self.disable_oob!r}, "
|
||||
+ f"stmtcachesize={self.stmtcachesize!r}, "
|
||||
+ f"edition={self.edition!r}, "
|
||||
+ f"tag={self.tag!r}, "
|
||||
+ f"matchanytag={self.matchanytag!r}, "
|
||||
+ f"config_dir={self.config_dir!r}, "
|
||||
+ f"appcontext={self.appcontext!r}, "
|
||||
+ f"shardingkey={self.shardingkey!r}, "
|
||||
+ f"supershardingkey={self.supershardingkey!r}, "
|
||||
+ f"debug_jdwp={self.debug_jdwp!r}, "
|
||||
+ f"connection_id_prefix={self.connection_id_prefix!r}, "
|
||||
+ f"ssl_context={self.ssl_context!r}, "
|
||||
+ f"sdu={self.sdu!r}"
|
||||
+ ")"
|
||||
)
|
||||
|
||||
def _address_attr(f):
|
||||
"""
|
||||
Helper function used to get address level attributes.
|
||||
"""
|
||||
|
||||
@functools.wraps(f)
|
||||
def wrapped(self):
|
||||
values = [
|
||||
getattr(a, f.__name__) for a in self._impl._get_addresses()
|
||||
]
|
||||
return values if len(values) > 1 else values[0]
|
||||
|
||||
return wrapped
|
||||
|
||||
def _description_attr(f):
|
||||
"""
|
||||
Helper function used to get description level attributes.
|
||||
"""
|
||||
|
||||
@functools.wraps(f)
|
||||
def wrapped(self):
|
||||
values = [
|
||||
getattr(d, f.__name__)
|
||||
for d in self._impl.description_list.children
|
||||
]
|
||||
return values if len(values) > 1 else values[0]
|
||||
|
||||
return wrapped
|
||||
|
||||
@property
|
||||
def appcontext(self) -> list:
|
||||
"""
|
||||
Application context used by the connection. It should be a list of
|
||||
3-tuples (namespace, name, value) and each entry in the tuple should be
|
||||
a string. This value is only used in thick mode.
|
||||
"""
|
||||
return self._impl.appcontext
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def cclass(self) -> Union[list, str]:
|
||||
"""
|
||||
Connection class to use for Database Resident Connection Pooling
|
||||
(DRCP).
|
||||
"""
|
||||
return self._impl.cclass
|
||||
|
||||
@property
|
||||
def config_dir(self) -> str:
|
||||
"""
|
||||
Directory in which the optional tnsnames.ora configuration file is
|
||||
located. This value is only used in thin mode. For thick mode use the
|
||||
config_dir parameter of init_oracle_client().
|
||||
"""
|
||||
return self._impl.config_dir
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def connection_id_prefix(self) -> Union[list, str]:
|
||||
"""
|
||||
An application specific prefix that is added to the connection
|
||||
identifier used for tracing.
|
||||
"""
|
||||
return self._impl.connection_id_prefix
|
||||
|
||||
@property
|
||||
def debug_jdwp(self) -> str:
|
||||
"""
|
||||
A string with the format "host=<host>;port=<port>" that specifies the
|
||||
host and port of the PL/SQL debugger. This value is only used in thin
|
||||
mode. For thick mode set the ORA_DEBUG_JDWP environment variable.
|
||||
"""
|
||||
return self._impl.debug_jdwp
|
||||
|
||||
@property
|
||||
def disable_oob(self) -> bool:
|
||||
"""
|
||||
Boolean indicating whether out-of-band breaks should be disabled. This
|
||||
value is only used in thin mode. It has no effect on Windows which does
|
||||
not support this functionality.
|
||||
"""
|
||||
return self._impl.disable_oob
|
||||
|
||||
@property
|
||||
def edition(self) -> str:
|
||||
"""
|
||||
Edition to use for the connection. This parameter cannot be used
|
||||
simultaneously with the cclass parameter.
|
||||
"""
|
||||
return self._impl.edition
|
||||
|
||||
@property
|
||||
def events(self) -> bool:
|
||||
"""
|
||||
Boolean specifying whether events mode should be enabled. This value is
|
||||
only used in thick mode and is needed for continuous query notification
|
||||
and high availability event notifications.
|
||||
"""
|
||||
return self._impl.events
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def expire_time(self) -> Union[list, int]:
|
||||
"""
|
||||
An integer indicating the number of minutes between the sending of
|
||||
keepalive probes. If this parameter is set to a value greater than zero
|
||||
it enables keepalive.
|
||||
"""
|
||||
return self._impl.expire_time
|
||||
|
||||
@property
|
||||
def externalauth(self) -> bool:
|
||||
"""
|
||||
A boolean indicating whether to use external authentication.
|
||||
"""
|
||||
return self._impl.externalauth
|
||||
|
||||
@property
|
||||
@_address_attr
|
||||
def host(self) -> Union[list, str]:
|
||||
"""
|
||||
The name or IP address of the machine hosting the database or the
|
||||
database listener.
|
||||
"""
|
||||
return self._impl.host
|
||||
|
||||
@property
|
||||
@_address_attr
|
||||
def https_proxy(self) -> Union[list, str]:
|
||||
"""
|
||||
The name or IP address of a proxy host to use for tunneling secure
|
||||
connections.
|
||||
"""
|
||||
return self._impl.https_proxy
|
||||
|
||||
@property
|
||||
@_address_attr
|
||||
def https_proxy_port(self) -> Union[list, int]:
|
||||
"""
|
||||
The port on which to communicate with the proxy host.
|
||||
"""
|
||||
return self._impl.https_proxy_port
|
||||
|
||||
@property
|
||||
def matchanytag(self) -> bool:
|
||||
"""
|
||||
Boolean specifying whether any tag can be used when acquiring a
|
||||
connection from the pool. This value is only used in thick mode..
|
||||
"""
|
||||
return self._impl.matchanytag
|
||||
|
||||
@property
|
||||
def mode(self) -> int:
|
||||
"""
|
||||
Authorization mode to use. For example oracledb.AUTH_MODE_SYSDBA.
|
||||
"""
|
||||
return self._impl.mode
|
||||
|
||||
@property
|
||||
@_address_attr
|
||||
def port(self) -> Union[list, int]:
|
||||
"""
|
||||
The port number on which the database listener is listening.
|
||||
"""
|
||||
return self._impl.port
|
||||
|
||||
@property
|
||||
@_address_attr
|
||||
def protocol(self) -> Union[list, str]:
|
||||
"""
|
||||
One of the strings "tcp" or "tcps" indicating whether to use
|
||||
unencrypted network traffic or encrypted network traffic (TLS).
|
||||
"""
|
||||
return self._impl.protocol
|
||||
|
||||
@property
|
||||
def proxy_user(self) -> str:
|
||||
"""
|
||||
The name of the proxy user to connect to. If this value is not
|
||||
specified, it will be parsed out of user if user is in the form
|
||||
"user[proxy_user]".
|
||||
"""
|
||||
return self._impl.proxy_user
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def purity(self) -> Union[list, int]:
|
||||
"""
|
||||
Purity to use for Database Resident Connection Pooling (DRCP).
|
||||
"""
|
||||
return self._impl.purity
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def retry_count(self) -> Union[list, int]:
|
||||
"""
|
||||
The number of times that a connection attempt should be retried before
|
||||
the attempt is terminated.
|
||||
"""
|
||||
return self._impl.retry_count
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def retry_delay(self) -> Union[list, int]:
|
||||
"""
|
||||
The number of seconds to wait before making a new connection attempt.
|
||||
"""
|
||||
return self._impl.retry_delay
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def sdu(self) -> Union[list, int]:
|
||||
"""
|
||||
The requested size of the Session Data Unit (SDU), in bytes. The value
|
||||
tunes internal buffers used for communication to the database. Bigger
|
||||
values can increase throughput for large queries or bulk data loads,
|
||||
but at the cost of higher memory use. The SDU size that will actually
|
||||
be used is negotiated down to the lower of this value and the database
|
||||
network SDU configuration value.
|
||||
"""
|
||||
return self._impl.sdu
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def server_type(self) -> Union[list, str]:
|
||||
"""
|
||||
The type of server connection that should be established. If specified,
|
||||
it should be one of "dedicated", "shared" or "pooled".
|
||||
"""
|
||||
return self._impl.server_type
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def service_name(self) -> Union[list, str]:
|
||||
"""
|
||||
The service name of the database.
|
||||
"""
|
||||
return self._impl.service_name
|
||||
|
||||
@property
|
||||
def shardingkey(self) -> list:
|
||||
"""
|
||||
A list of strings, numbers, bytes or dates that identify the database
|
||||
shard to connect to. This value is only used in thick mode.
|
||||
"""
|
||||
return self._impl.shardingkey
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def sid(self) -> Union[list, str]:
|
||||
"""
|
||||
The system identifier (SID) of the database. Note using a service_name
|
||||
instead is recommended.
|
||||
"""
|
||||
return self._impl.sid
|
||||
|
||||
@property
|
||||
def ssl_context(self) -> Any:
|
||||
"""
|
||||
An SSLContext object used for connecting to the database using TLS.
|
||||
This SSL context will be modified to include the private key or any
|
||||
certificates found in a separately supplied wallet. This parameter
|
||||
should only be specified if the default SSLContext object cannot be
|
||||
used.
|
||||
"""
|
||||
return self._impl.ssl_context
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def ssl_server_cert_dn(self) -> Union[list, str]:
|
||||
"""
|
||||
The distinguished name (DN) which should be matched with the server.
|
||||
This value is ignored if the ssl_server_dn_match parameter is not set
|
||||
to the value True. If specified this value is used for any verfication.
|
||||
Otherwise the hostname will be used..
|
||||
"""
|
||||
return self._impl.ssl_server_cert_dn
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def ssl_server_dn_match(self) -> Union[list, bool]:
|
||||
"""
|
||||
Boolean indicating whether the server certificate distinguished name
|
||||
(DN) should be matched in addition to the regular certificate
|
||||
verification that is performed. Note that if the ssl_server_cert_dn
|
||||
parameter is not privided, host name matching is performed instead.
|
||||
"""
|
||||
return self._impl.ssl_server_dn_match
|
||||
|
||||
@property
|
||||
def stmtcachesize(self) -> int:
|
||||
"""
|
||||
Identifies the initial size of the statement cache.
|
||||
"""
|
||||
return self._impl.stmtcachesize
|
||||
|
||||
@property
|
||||
def supershardingkey(self) -> list:
|
||||
"""
|
||||
A list of strings, numbers, bytes or dates that identify the database
|
||||
shard to connect to. This value is only used in thick mode.
|
||||
"""
|
||||
return self._impl.supershardingkey
|
||||
|
||||
@property
|
||||
def tag(self) -> str:
|
||||
"""
|
||||
Identifies the type of connection that should be returned from a pool.
|
||||
This value is only used in thick mode.
|
||||
"""
|
||||
return self._impl.tag
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def tcp_connect_timeout(self) -> Union[list, float]:
|
||||
"""
|
||||
A float indicating the maximum number of seconds to wait for
|
||||
establishing a connection to the database host.
|
||||
"""
|
||||
return self._impl.tcp_connect_timeout
|
||||
|
||||
@property
|
||||
def user(self) -> str:
|
||||
"""
|
||||
The name of the user to connect to.
|
||||
"""
|
||||
return self._impl.user
|
||||
|
||||
@property
|
||||
@_description_attr
|
||||
def wallet_location(self) -> Union[list, str]:
|
||||
"""
|
||||
The directory where the wallet can be found. In thin mode this must be
|
||||
the directory containing the PEM-encoded wallet file ewallet.pem. In
|
||||
thick mode this must be the directory containing the file cwallet.sso.
|
||||
"""
|
||||
return self._impl.wallet_location
|
||||
|
||||
def copy(self) -> "ConnectParams":
|
||||
"""
|
||||
Creates a copy of the parameters and returns it.
|
||||
"""
|
||||
params = ConnectParams.__new__(ConnectParams)
|
||||
params._impl = self._impl.copy()
|
||||
return params
|
||||
|
||||
def get_connect_string(self) -> str:
|
||||
"""
|
||||
Returns a connect string generated from the parameters.
|
||||
"""
|
||||
return self._impl.get_connect_string()
|
||||
|
||||
def parse_connect_string(self, connect_string: str) -> None:
|
||||
"""
|
||||
Parses the connect string into its components and stores the
|
||||
parameters. The connect string could be an Easy Connect string,
|
||||
name-value pairs or a simple alias which is looked up in tnsnames.ora.
|
||||
Any parameters found in the connect string override any currently
|
||||
stored values.
|
||||
"""
|
||||
self._impl.parse_connect_string(connect_string)
|
||||
|
||||
def parse_dsn_with_credentials(self, dsn: str) -> tuple:
|
||||
"""
|
||||
Parses a dsn in the form <user>/<password>@<connect_string> or in the
|
||||
form <user>/<password> and returns a 3-tuple containing the parsed
|
||||
user, password and connect string. Empty strings are returned as the
|
||||
value None. This is done automatically when a value is passed to
|
||||
the dsn parameter but no value is passed to the user password when
|
||||
creating a standalone connection or connection pool.
|
||||
"""
|
||||
return self._impl.parse_dsn_with_credentials(dsn)
|
||||
|
||||
@utils.params_setter
|
||||
def set(
|
||||
self,
|
||||
*,
|
||||
user: str = None,
|
||||
proxy_user: str = None,
|
||||
password: str = None,
|
||||
newpassword: str = None,
|
||||
wallet_password: str = None,
|
||||
access_token: Union[str, tuple, Callable] = None,
|
||||
host: str = None,
|
||||
port: int = None,
|
||||
protocol: str = None,
|
||||
https_proxy: str = None,
|
||||
https_proxy_port: int = None,
|
||||
service_name: str = None,
|
||||
sid: str = None,
|
||||
server_type: str = None,
|
||||
cclass: str = None,
|
||||
purity: int = None,
|
||||
expire_time: int = None,
|
||||
retry_count: int = None,
|
||||
retry_delay: int = None,
|
||||
tcp_connect_timeout: float = None,
|
||||
ssl_server_dn_match: bool = None,
|
||||
ssl_server_cert_dn: str = None,
|
||||
wallet_location: str = None,
|
||||
events: bool = None,
|
||||
externalauth: bool = None,
|
||||
mode: int = None,
|
||||
disable_oob: bool = None,
|
||||
stmtcachesize: int = None,
|
||||
edition: str = None,
|
||||
tag: str = None,
|
||||
matchanytag: bool = None,
|
||||
config_dir: str = None,
|
||||
appcontext: list = None,
|
||||
shardingkey: list = None,
|
||||
supershardingkey: list = None,
|
||||
debug_jdwp: str = None,
|
||||
connection_id_prefix: str = None,
|
||||
ssl_context: Any = None,
|
||||
sdu: int = None,
|
||||
handle: int = None,
|
||||
):
|
||||
"""
|
||||
All parameters are optional. A brief description of each parameter
|
||||
follows:
|
||||
|
||||
- user: the name of the user to connect to
|
||||
|
||||
- proxy_user: the name of the proxy user to connect to. If this value
|
||||
is not specified, it will be parsed out of user if user is in the
|
||||
form "user[proxy_user]"
|
||||
|
||||
- password: the password for the user
|
||||
|
||||
- newpassword: the new password for the user. The new password will
|
||||
take effect immediately upon a successful connection to the database
|
||||
|
||||
- wallet_password: the password to use to decrypt the wallet, if it is
|
||||
encrypted. This value is only used in thin mode
|
||||
|
||||
- access_token: expected to be a string or a 2-tuple or a callable. If
|
||||
it is a string, it specifies an Azure AD OAuth2 token used for Open
|
||||
Authorization (OAuth 2.0) token based authentication. If it is a
|
||||
2-tuple, it specifies the token and private key strings used for
|
||||
Oracle Cloud Infrastructure (OCI) Identity and Access Management
|
||||
(IAM) token based authentication. If it is a callable, it returns
|
||||
either a string or a 2-tuple used for OAuth 2.0 or OCI IAM token
|
||||
based authentication and is useful when the pool needs to expand and
|
||||
create new connections but the current authentication token has
|
||||
expired
|
||||
|
||||
- host: the name or IP address of the machine hosting the database or
|
||||
the database listener
|
||||
|
||||
- port: the port number on which the database listener is listening
|
||||
|
||||
- protocol: one of the strings "tcp" or "tcps" indicating whether to
|
||||
use unencrypted network traffic or encrypted network traffic (TLS)
|
||||
|
||||
- https_proxy: the name or IP address of a proxy host to use for
|
||||
tunneling secure connections
|
||||
|
||||
- https_proxy_port: the port on which to communicate with the proxy
|
||||
host
|
||||
|
||||
- service_name: the service name of the database
|
||||
|
||||
- sid: the system identifier (SID) of the database. Note using a
|
||||
service_name instead is recommended
|
||||
|
||||
- server_type: the type of server connection that should be
|
||||
established. If specified, it should be one of "dedicated", "shared"
|
||||
or "pooled"
|
||||
|
||||
- cclass: connection class to use for Database Resident Connection
|
||||
Pooling (DRCP)
|
||||
|
||||
- purity: purity to use for Database Resident Connection Pooling (DRCP)
|
||||
|
||||
- expire_time: an integer indicating the number of minutes between the
|
||||
sending of keepalive probes. If this parameter is set to a value
|
||||
greater than zero it enables keepalive
|
||||
|
||||
- retry_count: the number of times that a connection attempt should be
|
||||
retried before the attempt is terminated
|
||||
|
||||
- retry_delay: the number of seconds to wait before making a new
|
||||
connection attempt
|
||||
|
||||
- tcp_connect_timeout: a float indicating the maximum number of seconds
|
||||
to wait for establishing a connection to the database host
|
||||
|
||||
- ssl_server_dn_match: boolean indicating whether the server
|
||||
certificate distinguished name (DN) should be matched in addition to
|
||||
the regular certificate verification that is performed. Note that if
|
||||
the ssl_server_cert_dn parameter is not privided, host name matching
|
||||
is performed instead
|
||||
|
||||
- ssl_server_cert_dn: the distinguished name (DN) which should be
|
||||
matched with the server. This value is ignored if the
|
||||
ssl_server_dn_match parameter is not set to the value True. If
|
||||
specified this value is used for any verfication. Otherwise the
|
||||
hostname will be used.
|
||||
|
||||
- wallet_location: the directory where the wallet can be found. In thin
|
||||
mode this must be the directory containing the PEM-encoded wallet
|
||||
file ewallet.pem. In thick mode this must be the directory containing
|
||||
the file cwallet.sso
|
||||
|
||||
- events: boolean specifying whether events mode should be enabled.
|
||||
This value is only used in thick mode and is needed for continuous
|
||||
query notification and high availability event notifications
|
||||
|
||||
- externalauth: a boolean indicating whether to use external
|
||||
authentication
|
||||
|
||||
- mode: authorization mode to use. For example
|
||||
oracledb.AUTH_MODE_SYSDBA
|
||||
|
||||
- disable_oob: boolean indicating whether out-of-band breaks should be
|
||||
disabled. This value is only used in thin mode. It has no effect on
|
||||
Windows which does not support this functionality
|
||||
|
||||
- stmtcachesize: identifies the initial size of the statement cache
|
||||
|
||||
- edition: edition to use for the connection. This parameter cannot be
|
||||
used simultaneously with the cclass parameter
|
||||
|
||||
- tag: identifies the type of connection that should be returned from a
|
||||
pool. This value is only used in thick mode
|
||||
|
||||
- matchanytag: boolean specifying whether any tag can be used when
|
||||
acquiring a connection from the pool. This value is only used in
|
||||
thick mode.
|
||||
|
||||
- config_dir: directory in which the optional tnsnames.ora
|
||||
configuration file is located. This value is only used in thin mode.
|
||||
For thick mode use the config_dir parameter of init_oracle_client()
|
||||
|
||||
- appcontext: application context used by the connection. It should be
|
||||
a list of 3-tuples (namespace, name, value) and each entry in the
|
||||
tuple should be a string. This value is only used in thick mode
|
||||
|
||||
- shardingkey: a list of strings, numbers, bytes or dates that identify
|
||||
the database shard to connect to. This value is only used in thick
|
||||
mode
|
||||
|
||||
- supershardingkey: a list of strings, numbers, bytes or dates that
|
||||
identify the database shard to connect to. This value is only used in
|
||||
thick mode
|
||||
|
||||
- debug_jdwp: a string with the format "host=<host>;port=<port>" that
|
||||
specifies the host and port of the PL/SQL debugger. This value is
|
||||
only used in thin mode. For thick mode set the ORA_DEBUG_JDWP
|
||||
environment variable
|
||||
|
||||
- connection_id_prefix: an application specific prefix that is added to
|
||||
the connection identifier used for tracing
|
||||
|
||||
- ssl_context: an SSLContext object used for connecting to the database
|
||||
using TLS. This SSL context will be modified to include the private
|
||||
key or any certificates found in a separately supplied wallet. This
|
||||
parameter should only be specified if the default SSLContext object
|
||||
cannot be used
|
||||
|
||||
- sdu: the requested size of the Session Data Unit (SDU), in bytes. The
|
||||
value tunes internal buffers used for communication to the database.
|
||||
Bigger values can increase throughput for large queries or bulk data
|
||||
loads, but at the cost of higher memory use. The SDU size that will
|
||||
actually be used is negotiated down to the lower of this value and
|
||||
the database network SDU configuration value
|
||||
|
||||
- handle: an integer representing a pointer to a valid service context
|
||||
handle. This value is only used in thick mode. It should be used with
|
||||
extreme caution
|
||||
"""
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,164 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# constants.py
|
||||
#
|
||||
# Contains the constants defined by the package.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# mandated DB API constants
|
||||
apilevel = "2.0"
|
||||
threadsafety = 2
|
||||
paramstyle = "named"
|
||||
|
||||
# authentication modes
|
||||
AUTH_MODE_DEFAULT = 0
|
||||
AUTH_MODE_PRELIM = 0x00000008
|
||||
AUTH_MODE_SYSASM = 0x00008000
|
||||
AUTH_MODE_SYSBKP = 0x00020000
|
||||
AUTH_MODE_SYSDBA = 0x00000002
|
||||
AUTH_MODE_SYSDGD = 0x00040000
|
||||
AUTH_MODE_SYSKMT = 0x00080000
|
||||
AUTH_MODE_SYSOPER = 0x00000004
|
||||
AUTH_MODE_SYSRAC = 0x00100000
|
||||
|
||||
# pool "get" modes
|
||||
POOL_GETMODE_WAIT = 0
|
||||
POOL_GETMODE_NOWAIT = 1
|
||||
POOL_GETMODE_FORCEGET = 2
|
||||
POOL_GETMODE_TIMEDWAIT = 3
|
||||
|
||||
# purity values
|
||||
PURITY_DEFAULT = 0
|
||||
PURITY_NEW = 1
|
||||
PURITY_SELF = 2
|
||||
|
||||
# AQ delivery modes
|
||||
MSG_BUFFERED = 2
|
||||
MSG_PERSISTENT = 1
|
||||
MSG_PERSISTENT_OR_BUFFERED = 3
|
||||
|
||||
# AQ dequeue modes
|
||||
DEQ_BROWSE = 1
|
||||
DEQ_LOCKED = 2
|
||||
DEQ_REMOVE = 3
|
||||
DEQ_REMOVE_NODATA = 4
|
||||
|
||||
# AQ dequeue navigation modes
|
||||
DEQ_FIRST_MSG = 1
|
||||
DEQ_NEXT_MSG = 3
|
||||
DEQ_NEXT_TRANSACTION = 2
|
||||
|
||||
# AQ dequeue visibility modes
|
||||
DEQ_IMMEDIATE = 1
|
||||
DEQ_ON_COMMIT = 2
|
||||
|
||||
# AQ dequeue wait modes
|
||||
DEQ_NO_WAIT = 0
|
||||
DEQ_WAIT_FOREVER = 2**32 - 1
|
||||
|
||||
# AQ enqueue visibility modes
|
||||
ENQ_IMMEDIATE = 1
|
||||
ENQ_ON_COMMIT = 2
|
||||
|
||||
# AQ message states
|
||||
MSG_EXPIRED = 3
|
||||
MSG_PROCESSED = 2
|
||||
MSG_READY = 0
|
||||
MSG_WAITING = 1
|
||||
|
||||
# AQ other constants
|
||||
MSG_NO_DELAY = 0
|
||||
MSG_NO_EXPIRATION = -1
|
||||
|
||||
# shutdown modes
|
||||
DBSHUTDOWN_ABORT = 4
|
||||
DBSHUTDOWN_FINAL = 5
|
||||
DBSHUTDOWN_IMMEDIATE = 3
|
||||
DBSHUTDOWN_TRANSACTIONAL = 1
|
||||
DBSHUTDOWN_TRANSACTIONAL_LOCAL = 2
|
||||
|
||||
# subscription grouping classes
|
||||
SUBSCR_GROUPING_CLASS_NONE = 0
|
||||
SUBSCR_GROUPING_CLASS_TIME = 1
|
||||
|
||||
# subscription grouping types
|
||||
SUBSCR_GROUPING_TYPE_SUMMARY = 1
|
||||
SUBSCR_GROUPING_TYPE_LAST = 2
|
||||
|
||||
# subscription namespaces
|
||||
SUBSCR_NAMESPACE_AQ = 1
|
||||
SUBSCR_NAMESPACE_DBCHANGE = 2
|
||||
|
||||
# subscription protocols
|
||||
SUBSCR_PROTO_HTTP = 3
|
||||
SUBSCR_PROTO_MAIL = 1
|
||||
SUBSCR_PROTO_CALLBACK = 0
|
||||
SUBSCR_PROTO_SERVER = 2
|
||||
|
||||
# subscription quality of service
|
||||
SUBSCR_QOS_BEST_EFFORT = 0x10
|
||||
SUBSCR_QOS_DEFAULT = 0
|
||||
SUBSCR_QOS_DEREG_NFY = 0x02
|
||||
SUBSCR_QOS_QUERY = 0x08
|
||||
SUBSCR_QOS_RELIABLE = 0x01
|
||||
SUBSCR_QOS_ROWIDS = 0x04
|
||||
|
||||
# event types
|
||||
EVENT_AQ = 100
|
||||
EVENT_DEREG = 5
|
||||
EVENT_NONE = 0
|
||||
EVENT_OBJCHANGE = 6
|
||||
EVENT_QUERYCHANGE = 7
|
||||
EVENT_SHUTDOWN = 2
|
||||
EVENT_SHUTDOWN_ANY = 3
|
||||
EVENT_STARTUP = 1
|
||||
|
||||
# operation codes
|
||||
OPCODE_ALLOPS = 0
|
||||
OPCODE_ALLROWS = 0x01
|
||||
OPCODE_ALTER = 0x10
|
||||
OPCODE_DELETE = 0x08
|
||||
OPCODE_DROP = 0x20
|
||||
OPCODE_INSERT = 0x02
|
||||
OPCODE_UPDATE = 0x04
|
||||
|
||||
# flags for tpc_begin()
|
||||
TPC_BEGIN_JOIN = 0x00000002
|
||||
TPC_BEGIN_NEW = 0x00000001
|
||||
TPC_BEGIN_PROMOTE = 0x00000008
|
||||
TPC_BEGIN_RESUME = 0x00000004
|
||||
|
||||
# flags for tpc_end()
|
||||
TPC_END_NORMAL = 0
|
||||
TPC_END_SUSPEND = 0x00100000
|
||||
|
||||
# basic configuration constants
|
||||
DRIVER_NAME = "python-oracledb"
|
||||
INSTALLATION_URL = (
|
||||
"https://python-oracledb.readthedocs.io/en/"
|
||||
"latest/user_guide/initialization.html"
|
||||
)
|
||||
ENCODING = "UTF-8"
|
||||
@@ -0,0 +1,76 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# constructors.py
|
||||
#
|
||||
# Contains the constructors mandated by the Python Database API.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import datetime
|
||||
|
||||
from . import errors
|
||||
|
||||
# synonyms for the types mandated by the database API
|
||||
Binary = bytes
|
||||
Date = datetime.date
|
||||
Timestamp = datetime.datetime
|
||||
|
||||
|
||||
def Time(hour: int, minute: int, second: int) -> None:
|
||||
"""
|
||||
Constructor mandated by the database API for creating a time value. Since
|
||||
Oracle doesn't support time only values, an exception is raised when this
|
||||
method is called.
|
||||
"""
|
||||
errors._raise_err(errors.ERR_TIME_NOT_SUPPORTED)
|
||||
|
||||
|
||||
def DateFromTicks(ticks: float) -> datetime.date:
|
||||
"""
|
||||
Constructor mandated by the database API for creating a date value given
|
||||
the number of seconds since the epoch (January 1, 1970). This is equivalent
|
||||
to using datetime.date.fromtimestamp() and that should be used instead.
|
||||
"""
|
||||
return datetime.date.fromtimestamp(ticks)
|
||||
|
||||
|
||||
def TimeFromTicks(ticks: float) -> None:
|
||||
"""
|
||||
Constructor mandated by the database API for creating a time value given
|
||||
the number of seconds since the epoch (January 1, 1970). Since Oracle
|
||||
doesn't support time only values, an exception is raised when this method
|
||||
is called.
|
||||
"""
|
||||
errors._raise_err(errors.ERR_TIME_NOT_SUPPORTED)
|
||||
|
||||
|
||||
def TimestampFromTicks(ticks: float) -> datetime.datetime:
|
||||
"""
|
||||
Constructor mandated by the database API for creating a timestamp value
|
||||
given the number of seconds since the epoch (January 1, 1970). This is
|
||||
equivalent to using datetime.datetime.fromtimestamp() and that should be
|
||||
used instead.
|
||||
"""
|
||||
return datetime.datetime.fromtimestamp(ticks)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,358 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# dbobject.py
|
||||
#
|
||||
# Contains the classes used for managing database objects and the database
|
||||
# object type metadata: DbObject, DbObjectType and DbObjectAttr.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Any, Sequence, Union
|
||||
|
||||
from . import errors
|
||||
from . import __name__ as MODULE_NAME
|
||||
from .base_impl import DbType
|
||||
|
||||
|
||||
class DbObject:
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
attr_impl = self._impl.type.attrs_by_name[name]
|
||||
except KeyError:
|
||||
return super().__getattribute__(name)
|
||||
return self._impl.get_attr_value(attr_impl)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<oracledb.DbObject {self.type._get_full_name()} at "
|
||||
f"{hex(id(self))}>"
|
||||
)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name == "_impl" or name == "_type":
|
||||
super().__setattr__(name, value)
|
||||
else:
|
||||
attr_impl = self._impl.type.attrs_by_name[name]
|
||||
self._impl.set_attr_value(attr_impl, value)
|
||||
|
||||
def _ensure_is_collection(self):
|
||||
"""
|
||||
Ensures that the object refers to a collection. If not, an exception is
|
||||
raised.
|
||||
"""
|
||||
if not self.type.iscollection:
|
||||
errors._raise_err(
|
||||
errors.ERR_OBJECT_IS_NOT_A_COLLECTION,
|
||||
name=self.type._get_full_name(),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
obj = cls.__new__(cls)
|
||||
obj._impl = impl
|
||||
obj._type = None
|
||||
return obj
|
||||
|
||||
def append(self, element: Any) -> None:
|
||||
"""
|
||||
Append an element to the collection object. If no elements exist in the
|
||||
collection, this creates an element at index 0; otherwise, it creates
|
||||
an element immediately following the highest index available in the
|
||||
collection.
|
||||
"""
|
||||
self._impl.append(element)
|
||||
|
||||
def asdict(self) -> dict:
|
||||
"""
|
||||
Return a dictionary where the collection’s indexes are the keys and the
|
||||
elements are its values.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
result = {}
|
||||
ix = self._impl.get_first_index()
|
||||
while ix is not None:
|
||||
result[ix] = self._impl.get_element_by_index(ix)
|
||||
ix = self._impl.get_next_index(ix)
|
||||
return result
|
||||
|
||||
def aslist(self) -> list:
|
||||
"""
|
||||
Return a list of each of the collection’s elements in index order.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
result = []
|
||||
ix = self._impl.get_first_index()
|
||||
while ix is not None:
|
||||
result.append(self._impl.get_element_by_index(ix))
|
||||
ix = self._impl.get_next_index(ix)
|
||||
return result
|
||||
|
||||
def copy(self) -> "DbObject":
|
||||
"""
|
||||
Create a copy of the object and return it.
|
||||
"""
|
||||
copied_impl = self._impl.copy()
|
||||
return DbObject._from_impl(copied_impl)
|
||||
|
||||
def delete(self, index: int) -> None:
|
||||
"""
|
||||
Delete the element at the specified index of the collection. If the
|
||||
element does not exist or is otherwise invalid, an error is raised.
|
||||
Note that the indices of the remaining elements in the collection are
|
||||
not changed. In other words, the delete operation creates holes in the
|
||||
collection.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
self._impl.delete_by_index(index)
|
||||
|
||||
def exists(self, index: int) -> bool:
|
||||
"""
|
||||
Return True or False indicating if an element exists in the collection
|
||||
at the specified index.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.exists_by_index(index)
|
||||
|
||||
def extend(self, seq: list) -> None:
|
||||
"""
|
||||
Append all of the elements in the sequence to the collection. This is
|
||||
the equivalent of performing append() for each element found in the
|
||||
sequence.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
for value in seq:
|
||||
self.append(value)
|
||||
|
||||
def first(self) -> int:
|
||||
"""
|
||||
Return the index of the first element in the collection. If the
|
||||
collection is empty, None is returned.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_first_index()
|
||||
|
||||
def getelement(self, index: int) -> Any:
|
||||
"""
|
||||
Return the element at the specified index of the collection. If no
|
||||
element exists at that index, an exception is raised.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_element_by_index(index)
|
||||
|
||||
def last(self) -> int:
|
||||
"""
|
||||
Return the index of the last element in the collection. If the
|
||||
collection is empty, None is returned.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_last_index()
|
||||
|
||||
def next(self, index: int) -> int:
|
||||
"""
|
||||
Return the index of the next element in the collection following the
|
||||
specified index. If there are no elements in the collection following
|
||||
the specified index, None is returned.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_next_index(index)
|
||||
|
||||
def prev(self, index: int) -> int:
|
||||
"""
|
||||
Return the index of the element in the collection preceding the
|
||||
specified index. If there are no elements in the collection preceding
|
||||
the specified index, None is returned.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_prev_index(index)
|
||||
|
||||
def setelement(self, index: int, value: Any) -> None:
|
||||
"""
|
||||
Set the value in the collection at the specified index to the given
|
||||
value.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
self._impl.set_element_by_index(index, value)
|
||||
|
||||
def size(self) -> int:
|
||||
"""
|
||||
Return the number of elements in the collection.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
return self._impl.get_size()
|
||||
|
||||
def trim(self, num: int) -> None:
|
||||
"""
|
||||
Remove the specified number of elements from the end of the collection.
|
||||
"""
|
||||
self._ensure_is_collection()
|
||||
self._impl.trim(num)
|
||||
|
||||
@property
|
||||
def type(self) -> "DbObjectType":
|
||||
"""
|
||||
Returns an ObjectType corresponding to the type of the object.
|
||||
"""
|
||||
if self._type is None:
|
||||
self._type = DbObjectType._from_impl(self._impl.type)
|
||||
return self._type
|
||||
|
||||
|
||||
class DbObjectAttr:
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __repr__(self):
|
||||
return f"<oracledb.DbObjectAttr {self.name}>"
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
attr = cls.__new__(cls)
|
||||
attr._impl = impl
|
||||
attr._type = None
|
||||
return attr
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the name of the attribute.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
@property
|
||||
def type(self) -> Union["DbObjectType", DbType]:
|
||||
"""
|
||||
This read-only attribute returns the type of the attribute. This will
|
||||
be an Oracle Object Type if the variable binds Oracle objects;
|
||||
otherwise, it will be one of the database type constants.
|
||||
"""
|
||||
if self._type is None:
|
||||
if self._impl.objtype is not None:
|
||||
self._type = DbObjectType._from_impl(self._impl.objtype)
|
||||
else:
|
||||
self._type = self._impl.dbtype
|
||||
return self._type
|
||||
|
||||
|
||||
class DbObjectType:
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __call__(self, value=None):
|
||||
return self.newobject(value)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, DbObjectType):
|
||||
return other._impl == self._impl
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
return f"<oracledb.DbObjectType {self._get_full_name()}>"
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
typ = cls.__new__(cls)
|
||||
typ._impl = impl
|
||||
typ._attributes = None
|
||||
typ._element_type = None
|
||||
return typ
|
||||
|
||||
def _get_full_name(self):
|
||||
"""
|
||||
Returns the full name of the type.
|
||||
"""
|
||||
return self._impl._get_fqn()
|
||||
|
||||
@property
|
||||
def attributes(self) -> list:
|
||||
"""
|
||||
This read-only attribute returns a list of the attributes that make up
|
||||
the object type.
|
||||
"""
|
||||
if self._attributes is None:
|
||||
self._attributes = [
|
||||
DbObjectAttr._from_impl(i) for i in self._impl.attrs
|
||||
]
|
||||
return self._attributes
|
||||
|
||||
@property
|
||||
def iscollection(self) -> bool:
|
||||
"""
|
||||
This read-only attribute returns a boolean indicating if the object
|
||||
type refers to a collection or not.
|
||||
"""
|
||||
return self._impl.is_collection
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the name of the type.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
@property
|
||||
def element_type(self) -> Union["DbObjectType", DbType]:
|
||||
"""
|
||||
This read-only attribute returns the type of elements found in
|
||||
collections of this type, if iscollection is True; otherwise, it
|
||||
returns None. If the collection contains objects, this will be another
|
||||
object type; otherwise, it will be one of the database type constants.
|
||||
"""
|
||||
if self._element_type is None:
|
||||
if self._impl.element_objtype is not None:
|
||||
typ_impl = self._impl.element_objtype
|
||||
self._element_type = DbObjectType._from_impl(typ_impl)
|
||||
else:
|
||||
self._element_type = self._impl.element_dbtype
|
||||
return self._element_type
|
||||
|
||||
def newobject(self, value: Sequence = None) -> DbObject:
|
||||
"""
|
||||
Return a new Oracle object of the given type. This object can then be
|
||||
modified by setting its attributes and then bound to a cursor for
|
||||
interaction with Oracle. If the object type refers to a collection, a
|
||||
sequence may be passed and the collection will be initialized with the
|
||||
items in that sequence.
|
||||
"""
|
||||
obj_impl = self._impl.create_new_object()
|
||||
obj = DbObject._from_impl(obj_impl)
|
||||
if value is not None:
|
||||
obj.extend(value)
|
||||
return obj
|
||||
|
||||
@property
|
||||
def package_name(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the name of the package containing the
|
||||
PL/SQL type or None if the type is not a PL/SQL type.
|
||||
"""
|
||||
return self._impl.package_name
|
||||
|
||||
@property
|
||||
def schema(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the name of the schema that owns the
|
||||
type.
|
||||
"""
|
||||
return self._impl.schema
|
||||
@@ -0,0 +1,53 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# defaults.py
|
||||
#
|
||||
# Contains the Defaults class used for managing default values used throughout
|
||||
# the module.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
|
||||
from . import __name__ as MODULE_NAME
|
||||
|
||||
|
||||
class Defaults:
|
||||
"""
|
||||
Identifies the default values used by the driver.
|
||||
"""
|
||||
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.arraysize = 100
|
||||
self.stmtcachesize = 20
|
||||
self.config_dir = os.environ.get("TNS_ADMIN")
|
||||
self.fetch_lobs = True
|
||||
self.fetch_decimals = False
|
||||
self.prefetchrows = 2
|
||||
|
||||
|
||||
defaults = Defaults()
|
||||
@@ -0,0 +1,140 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023 Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# driver_mode.py
|
||||
#
|
||||
# Contains a simple method for checking and returning which mode the driver is
|
||||
# currently using. The driver only supports creating connections and pools with
|
||||
# either the thin implementation or the thick implementation, not both
|
||||
# simultaneously.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import threading
|
||||
|
||||
from . import errors
|
||||
|
||||
|
||||
# The DriverModeHandler class is used to manage which mode the driver is using.
|
||||
#
|
||||
# The "thin_mode" flag contains the current state:
|
||||
# None: neither thick nor thin implementation has been used yet
|
||||
# False: thick implementation is being used
|
||||
# True: thin implementation is being used
|
||||
#
|
||||
# The "requested_thin_mode" flag is set to the mode that is being requested:
|
||||
# False: thick implementation is being initialized
|
||||
# True: thin implementation is being initialized
|
||||
class DriverModeManager:
|
||||
"""
|
||||
Manages the mode the driver is using. The "thin_mode" flag contains the
|
||||
current state:
|
||||
None: neither thick nor thin implementation has been used yet
|
||||
False: thick implementation is being used
|
||||
True: thin implementation is being used
|
||||
The "requested_thin_mode" is set to the mode that is being requested, but
|
||||
only while initialization is taking place (otherwise, it contains the value
|
||||
None):
|
||||
False: thick implementation is being initialized
|
||||
True: thin implementation is being initialized
|
||||
The condition is used to ensure that only one thread is performing
|
||||
initialization.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.thin_mode = None
|
||||
self.requested_thin_mode = None
|
||||
self.condition = threading.Condition()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||
with self.condition:
|
||||
if (
|
||||
exc_type is None
|
||||
and exc_value is None
|
||||
and exc_tb is None
|
||||
and self.requested_thin_mode is not None
|
||||
):
|
||||
self.thin_mode = self.requested_thin_mode
|
||||
self.requested_thin_mode = None
|
||||
self.condition.notify()
|
||||
|
||||
@property
|
||||
def thin(self):
|
||||
if self.requested_thin_mode is not None:
|
||||
return self.requested_thin_mode
|
||||
return self.thin_mode
|
||||
|
||||
|
||||
manager = DriverModeManager()
|
||||
|
||||
|
||||
def get_manager(requested_thin_mode=None):
|
||||
"""
|
||||
Returns the manager, but only after ensuring that no other threads are
|
||||
attempting to initialize the mode.
|
||||
|
||||
NOTE: the current implementation of the driver only requires
|
||||
requested_thin_mode to be set when initializing the thick mode; for this
|
||||
reason the error raised is specified about a thin mode connection already
|
||||
being created. If this assumption changes, a new error message will be
|
||||
required.
|
||||
"""
|
||||
with manager.condition:
|
||||
if manager.thin_mode is None:
|
||||
if manager.requested_thin_mode is not None:
|
||||
manager.condition.wait()
|
||||
if manager.thin_mode is None:
|
||||
if requested_thin_mode is None:
|
||||
manager.requested_thin_mode = True
|
||||
else:
|
||||
manager.requested_thin_mode = requested_thin_mode
|
||||
elif (
|
||||
requested_thin_mode is not None
|
||||
and requested_thin_mode != manager.thin_mode
|
||||
):
|
||||
errors._raise_err(errors.ERR_THIN_CONNECTION_ALREADY_CREATED)
|
||||
return manager
|
||||
|
||||
|
||||
def is_thin_mode() -> bool:
|
||||
"""
|
||||
Return a boolean specifying whether the driver is using thin mode (True) or
|
||||
thick mode (False).
|
||||
|
||||
Immediately after python-oracledb is imported, this function will return
|
||||
True indicating that python-oracledb defaults to Thin mode. If
|
||||
oracledb.init_oracle_client() is called successfully, then a subsequent
|
||||
call to is_thin_mode() will return False indicating that Thick mode is
|
||||
enabled. Once the first standalone connection or connection pool is
|
||||
created succesfully, or a call to oracledb.init_oracle_client() is made
|
||||
successfully, then python-oracledb's mode is fixed and the value returned
|
||||
by is_thin_mode() will never change for the lifetime of the process.
|
||||
|
||||
"""
|
||||
if manager.thin_mode is not None:
|
||||
return manager.thin_mode
|
||||
return True
|
||||
@@ -0,0 +1,80 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# dsn.py
|
||||
#
|
||||
# Contains makedsn(), a method available for backwards compatibility with
|
||||
# cx_Oracle. Use of the ConnectParams class or the keyword arguments to
|
||||
# connect() and create_pool() is recommended instead.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from . import errors
|
||||
|
||||
|
||||
def _check_arg(name: str, value: str) -> None:
|
||||
"""
|
||||
Checks the argument to ensure that it does not contain (, ) or = as these
|
||||
characters are not permitted within connect strings.
|
||||
"""
|
||||
if "(" in value or ")" in value or "=" in value:
|
||||
errors._raise_err(errors.ERR_INVALID_MAKEDSN_ARG, name=name)
|
||||
|
||||
|
||||
def makedsn(
|
||||
host: str,
|
||||
port: int,
|
||||
sid: str = None,
|
||||
service_name: str = None,
|
||||
region: str = None,
|
||||
sharding_key: str = None,
|
||||
super_sharding_key: str = None,
|
||||
) -> str:
|
||||
"""
|
||||
Return a string suitable for use as the dsn parameter for connect(). This
|
||||
string is identical to the strings that are defined in the tnsnames.ora
|
||||
file.
|
||||
"""
|
||||
connect_data_parts = []
|
||||
_check_arg("host", host)
|
||||
if sid is not None:
|
||||
_check_arg("sid", sid)
|
||||
connect_data_parts.append(f"(SID={sid})")
|
||||
if service_name is not None:
|
||||
_check_arg("service_name", service_name)
|
||||
connect_data_parts.append(f"(SERVICE_NAME={service_name})")
|
||||
if region is not None:
|
||||
_check_arg("region", region)
|
||||
connect_data_parts.append(f"(REGION={region})")
|
||||
if sharding_key is not None:
|
||||
_check_arg("sharding_key", sharding_key)
|
||||
connect_data_parts.append(f"(SHARDING_KEY={sharding_key})")
|
||||
if super_sharding_key is not None:
|
||||
_check_arg("super_sharding_key", super_sharding_key)
|
||||
connect_data_parts.append(f"(SUPER_SHARDING_KEY={super_sharding_key})")
|
||||
connect_data = "".join(connect_data_parts)
|
||||
return (
|
||||
f"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={host})"
|
||||
f"(PORT={port}))(CONNECT_DATA={connect_data}))"
|
||||
)
|
||||
@@ -0,0 +1,638 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# errors.py
|
||||
#
|
||||
# Contains the _Error class and all of the errors that are raised explicitly by
|
||||
# the package. Oracle Database errors and ODPI-C errors (when using thick mode)
|
||||
# are only referenced here if they are transformed into package specific
|
||||
# errors.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import re
|
||||
|
||||
from .driver_mode import is_thin_mode
|
||||
from . import exceptions
|
||||
|
||||
|
||||
class _Error:
|
||||
"""
|
||||
Error class which is used for all errors that are raised by the driver.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str = None,
|
||||
context: str = None,
|
||||
isrecoverable: bool = False,
|
||||
iswarning: bool = False,
|
||||
code: int = 0,
|
||||
offset: int = 0,
|
||||
) -> None:
|
||||
self.message = message
|
||||
self.context = context
|
||||
self.isrecoverable = isrecoverable
|
||||
self.iswarning = iswarning
|
||||
self.code = code
|
||||
self.offset = offset
|
||||
self.is_session_dead = False
|
||||
self.full_code = ""
|
||||
self._make_adjustments()
|
||||
|
||||
def _make_adjustments(self):
|
||||
"""
|
||||
Make adjustments to the error, if needed, and calculate the full_code
|
||||
attribute.
|
||||
"""
|
||||
if self.message is not None:
|
||||
pos = self.message.find(":")
|
||||
if pos > 0:
|
||||
self.full_code = self.message[:pos]
|
||||
|
||||
# add Oracle Database Error Help Portal URL for database error
|
||||
# messages, but only in thin mode since this is done
|
||||
# automatically in thick mode with Oracle Client 23c and higher
|
||||
if self.code != 0 and is_thin_mode():
|
||||
self.message = (
|
||||
self.message
|
||||
+ "\n"
|
||||
+ "Help: https://docs.oracle.com/error-help/db/ora-"
|
||||
+ f"{self.code:05}/"
|
||||
)
|
||||
elif self.full_code in ERR_TROUBLESHOOTING_AVAILABLE:
|
||||
self.message = (
|
||||
self.message
|
||||
+ "\n"
|
||||
+ "Help: https://python-oracledb.readthedocs.io/en/"
|
||||
+ "latest/user_guide/troubleshooting.html#"
|
||||
+ self.full_code.lower()
|
||||
)
|
||||
|
||||
if self.code != 0 or self.full_code.startswith("DPI-"):
|
||||
args = {}
|
||||
if self.code != 0:
|
||||
driver_error_info = ERR_ORACLE_ERROR_XREF.get(self.code)
|
||||
else:
|
||||
error_num = int(self.full_code[4:])
|
||||
driver_error_info = ERR_DPI_ERROR_XREF.get(error_num)
|
||||
if driver_error_info is not None:
|
||||
if isinstance(driver_error_info, tuple):
|
||||
driver_error_num, pattern = driver_error_info
|
||||
match = re.search(pattern, self.message)
|
||||
args = {} if match is None else match.groupdict()
|
||||
else:
|
||||
driver_error_num = driver_error_info
|
||||
if driver_error_num == ERR_CONNECTION_CLOSED:
|
||||
self.is_session_dead = True
|
||||
driver_error = _get_error_text(driver_error_num, **args)
|
||||
self.message = f"{driver_error}\n{self.message}"
|
||||
self.full_code = f"{ERR_PREFIX}-{driver_error_num:04}"
|
||||
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
|
||||
def _get_error_text(error_num: int, **args) -> str:
|
||||
"""
|
||||
Return the error text for the driver specific error number.
|
||||
"""
|
||||
message_format = ERR_MESSAGE_FORMATS.get(error_num)
|
||||
if message_format is None:
|
||||
message_format = "missing error {error_num}"
|
||||
args = dict(error_num=error_num)
|
||||
error_num = ERR_MISSING_ERROR
|
||||
try:
|
||||
message = message_format.format(**args)
|
||||
except KeyError:
|
||||
message = (
|
||||
message_format
|
||||
+ "\nWrong arguments to message format:\n"
|
||||
+ repr(args)
|
||||
)
|
||||
return f"{ERR_PREFIX}-{error_num:04}: {message}"
|
||||
|
||||
|
||||
def _create_warning(error_num: int, **args) -> _Error:
|
||||
"""
|
||||
Returns a warning error object for the specified error number and supplied
|
||||
arguments.
|
||||
"""
|
||||
message = _get_error_text(error_num, **args)
|
||||
return _Error(message, iswarning=True)
|
||||
|
||||
|
||||
def _raise_err(
|
||||
error_num: int,
|
||||
context_error_message: str = None,
|
||||
cause: Exception = None,
|
||||
**args,
|
||||
) -> None:
|
||||
"""
|
||||
Raises a driver specific exception from the specified error number and
|
||||
supplied arguments.
|
||||
"""
|
||||
message = _get_error_text(error_num, **args)
|
||||
if context_error_message is None and cause is not None:
|
||||
context_error_message = str(cause)
|
||||
if context_error_message is not None:
|
||||
message = f"{message}\n{context_error_message}"
|
||||
exc_type = ERR_EXCEPTION_TYPES[error_num // 1000]
|
||||
raise exc_type(_Error(message)) from cause
|
||||
|
||||
|
||||
def _raise_from_string(exc_type: Exception, message: str) -> None:
|
||||
"""
|
||||
Raises an exception from a given string. This ensures that an _Error object
|
||||
is created for all exceptions that are raised.
|
||||
"""
|
||||
raise exc_type(_Error(message)) from None
|
||||
|
||||
|
||||
# prefix used for all error messages
|
||||
ERR_PREFIX = "DPY"
|
||||
|
||||
# error numbers that result in InterfaceError
|
||||
ERR_MISSING_ERROR = 1000
|
||||
ERR_NOT_CONNECTED = 1001
|
||||
ERR_POOL_NOT_OPEN = 1002
|
||||
ERR_NOT_A_QUERY = 1003
|
||||
ERR_NO_STATEMENT_EXECUTED = 1004
|
||||
ERR_POOL_HAS_BUSY_CONNECTIONS = 1005
|
||||
ERR_CURSOR_NOT_OPEN = 1006
|
||||
|
||||
# error numbers that result in ProgrammingError
|
||||
ERR_MESSAGE_HAS_NO_PAYLOAD = 2000
|
||||
ERR_NO_STATEMENT = 2001
|
||||
ERR_NO_STATEMENT_PREPARED = 2002
|
||||
ERR_WRONG_EXECUTE_PARAMETERS_TYPE = 2003
|
||||
ERR_WRONG_EXECUTEMANY_PARAMETERS_TYPE = 2004
|
||||
ERR_ARGS_AND_KEYWORD_ARGS = 2005
|
||||
ERR_MIXED_POSITIONAL_AND_NAMED_BINDS = 2006
|
||||
ERR_EXPECTING_TYPE = 2007
|
||||
ERR_WRONG_OBJECT_TYPE = 2008
|
||||
ERR_WRONG_SCROLL_MODE = 2009
|
||||
ERR_MIXED_ELEMENT_TYPES = 2010
|
||||
ERR_WRONG_ARRAY_DEFINITION = 2011
|
||||
ERR_ARGS_MUST_BE_LIST_OR_TUPLE = 2012
|
||||
ERR_KEYWORD_ARGS_MUST_BE_DICT = 2013
|
||||
ERR_DUPLICATED_PARAMETER = 2014
|
||||
ERR_EXPECTING_VAR = 2015
|
||||
ERR_INCORRECT_VAR_ARRAYSIZE = 2016
|
||||
ERR_LIBRARY_ALREADY_INITIALIZED = 2017
|
||||
ERR_WALLET_FILE_MISSING = 2018
|
||||
ERR_THIN_CONNECTION_ALREADY_CREATED = 2019
|
||||
ERR_INVALID_MAKEDSN_ARG = 2020
|
||||
ERR_INIT_ORACLE_CLIENT_NOT_CALLED = 2021
|
||||
ERR_INVALID_OCI_ATTR_TYPE = 2022
|
||||
ERR_INVALID_CONN_CLASS = 2023
|
||||
ERR_INVALID_CONNECT_PARAMS = 2025
|
||||
ERR_INVALID_POOL_CLASS = 2026
|
||||
ERR_INVALID_POOL_PARAMS = 2027
|
||||
ERR_EXPECTING_LIST_FOR_ARRAY_VAR = 2028
|
||||
ERR_HTTPS_PROXY_REQUIRES_TCPS = 2029
|
||||
ERR_INVALID_LOB_OFFSET = 2030
|
||||
ERR_INVALID_ACCESS_TOKEN_PARAM = 2031
|
||||
ERR_INVALID_ACCESS_TOKEN_RETURNED = 2032
|
||||
ERR_EXPIRED_ACCESS_TOKEN = 2033
|
||||
ERR_ACCESS_TOKEN_REQUIRES_TCPS = 2034
|
||||
ERR_INVALID_OBJECT_TYPE_NAME = 2035
|
||||
ERR_OBJECT_IS_NOT_A_COLLECTION = 2036
|
||||
ERR_MISSING_TYPE_NAME_FOR_OBJECT_VAR = 2037
|
||||
ERR_INVALID_COLL_INDEX_GET = 2038
|
||||
ERR_INVALID_COLL_INDEX_SET = 2039
|
||||
ERR_EXECUTE_MODE_ONLY_FOR_DML = 2040
|
||||
ERR_MISSING_QUOTE_IN_STRING = 2041
|
||||
ERR_MISSING_QUOTE_IN_IDENTIFIER = 2042
|
||||
ERR_DBOBJECT_ATTR_MAX_SIZE_VIOLATED = 2043
|
||||
ERR_DBOBJECT_ELEMENT_MAX_SIZE_VIOLATED = 2044
|
||||
|
||||
# error numbers that result in NotSupportedError
|
||||
ERR_TIME_NOT_SUPPORTED = 3000
|
||||
ERR_FEATURE_NOT_SUPPORTED = 3001
|
||||
ERR_PYTHON_VALUE_NOT_SUPPORTED = 3002
|
||||
ERR_PYTHON_TYPE_NOT_SUPPORTED = 3003
|
||||
ERR_UNSUPPORTED_TYPE_SET = 3004
|
||||
ERR_ARRAYS_OF_ARRAYS = 3005
|
||||
ERR_ORACLE_TYPE_NOT_SUPPORTED = 3006
|
||||
ERR_DB_TYPE_NOT_SUPPORTED = 3007
|
||||
ERR_UNSUPPORTED_INBAND_NOTIFICATION = 3008
|
||||
ERR_SELF_BIND_NOT_SUPPORTED = 3009
|
||||
ERR_SERVER_VERSION_NOT_SUPPORTED = 3010
|
||||
ERR_NCHAR_CS_NOT_SUPPORTED = 3012
|
||||
ERR_UNSUPPORTED_PYTHON_TYPE_FOR_DB_TYPE = 3013
|
||||
ERR_LOB_OF_WRONG_TYPE = 3014
|
||||
ERR_UNSUPPORTED_VERIFIER_TYPE = 3015
|
||||
ERR_NO_CRYPTOGRAPHY_PACKAGE = 3016
|
||||
ERR_ORACLE_TYPE_NAME_NOT_SUPPORTED = 3017
|
||||
ERR_TDS_TYPE_NOT_SUPPORTED = 3018
|
||||
ERR_OSON_NODE_TYPE_NOT_SUPPORTED = 3019
|
||||
ERR_OSON_FIELD_NAME_LIMITATION = 3020
|
||||
ERR_OSON_VERSION_NOT_SUPPORTED = 3021
|
||||
ERR_NAMED_TIMEZONE_NOT_SUPPORTED = 3022
|
||||
|
||||
# error numbers that result in DatabaseError
|
||||
ERR_TNS_ENTRY_NOT_FOUND = 4000
|
||||
ERR_NO_CREDENTIALS = 4001
|
||||
ERR_COLUMN_TRUNCATED = 4002
|
||||
ERR_ORACLE_NUMBER_NO_REPR = 4003
|
||||
ERR_INVALID_NUMBER = 4004
|
||||
ERR_POOL_NO_CONNECTION_AVAILABLE = 4005
|
||||
ERR_ARRAY_DML_ROW_COUNTS_NOT_ENABLED = 4006
|
||||
ERR_INCONSISTENT_DATATYPES = 4007
|
||||
ERR_INVALID_BIND_NAME = 4008
|
||||
ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS = 4009
|
||||
ERR_MISSING_BIND_VALUE = 4010
|
||||
ERR_CONNECTION_CLOSED = 4011
|
||||
ERR_NUMBER_WITH_INVALID_EXPONENT = 4012
|
||||
ERR_NUMBER_STRING_OF_ZERO_LENGTH = 4013
|
||||
ERR_NUMBER_STRING_TOO_LONG = 4014
|
||||
ERR_NUMBER_WITH_EMPTY_EXPONENT = 4015
|
||||
ERR_CONTENT_INVALID_AFTER_NUMBER = 4016
|
||||
ERR_INVALID_CONNECT_DESCRIPTOR = 4017
|
||||
ERR_CANNOT_PARSE_CONNECT_STRING = 4018
|
||||
ERR_INVALID_REDIRECT_DATA = 4019
|
||||
ERR_INVALID_PROTOCOL = 4021
|
||||
ERR_INVALID_POOL_PURITY = 4022
|
||||
ERR_CALL_TIMEOUT_EXCEEDED = 4024
|
||||
ERR_INVALID_REF_CURSOR = 4025
|
||||
ERR_TNS_NAMES_FILE_MISSING = 4026
|
||||
ERR_NO_CONFIG_DIR = 4027
|
||||
ERR_INVALID_SERVER_TYPE = 4028
|
||||
ERR_TOO_MANY_BATCH_ERRORS = 4029
|
||||
|
||||
# error numbers that result in InternalError
|
||||
ERR_MESSAGE_TYPE_UNKNOWN = 5000
|
||||
ERR_BUFFER_LENGTH_INSUFFICIENT = 5001
|
||||
ERR_INTEGER_TOO_LARGE = 5002
|
||||
ERR_UNEXPECTED_NEGATIVE_INTEGER = 5003
|
||||
ERR_UNEXPECTED_DATA = 5004
|
||||
ERR_UNEXPECTED_REFUSE = 5005
|
||||
ERR_UNEXPECTED_END_OF_DATA = 5006
|
||||
ERR_UNEXPECTED_XML_TYPE = 5007
|
||||
ERR_TOO_MANY_CURSORS_TO_CLOSE = 5008
|
||||
ERR_UNKOWN_SERVER_SIDE_PIGGYBACK = 5009
|
||||
|
||||
# error numbers that result in OperationalError
|
||||
ERR_LISTENER_REFUSED_CONNECTION = 6000
|
||||
ERR_INVALID_SERVICE_NAME = 6001
|
||||
ERR_INVALID_SERVER_CERT_DN = 6002
|
||||
ERR_INVALID_SID = 6003
|
||||
ERR_PROXY_FAILURE = 6004
|
||||
ERR_CONNECTION_FAILED = 6005
|
||||
|
||||
# error numbers that result in Warning
|
||||
WRN_COMPILATION_ERROR = 7000
|
||||
|
||||
# Oracle error number cross reference
|
||||
ERR_ORACLE_ERROR_XREF = {
|
||||
28: ERR_CONNECTION_CLOSED,
|
||||
600: ERR_CONNECTION_CLOSED,
|
||||
1005: ERR_NO_CREDENTIALS,
|
||||
1740: ERR_MISSING_QUOTE_IN_IDENTIFIER,
|
||||
1756: ERR_MISSING_QUOTE_IN_STRING,
|
||||
22165: (
|
||||
ERR_INVALID_COLL_INDEX_SET,
|
||||
r"index \[(?P<index>\d+)\] must be in the range of "
|
||||
r"\[(?P<min_index>\d+)\] to \[(?P<max_index>\d+)\]",
|
||||
),
|
||||
22303: (ERR_INVALID_OBJECT_TYPE_NAME, r'type "(?P<name>[^"]*"."[^"]*)"'),
|
||||
24422: ERR_POOL_HAS_BUSY_CONNECTIONS,
|
||||
24349: ERR_ARRAY_DML_ROW_COUNTS_NOT_ENABLED,
|
||||
24459: ERR_POOL_NO_CONNECTION_AVAILABLE,
|
||||
24496: ERR_POOL_NO_CONNECTION_AVAILABLE,
|
||||
24338: ERR_INVALID_REF_CURSOR,
|
||||
24344: WRN_COMPILATION_ERROR,
|
||||
38902: ERR_TOO_MANY_BATCH_ERRORS,
|
||||
}
|
||||
|
||||
# ODPI-C error number cross reference
|
||||
ERR_DPI_ERROR_XREF = {
|
||||
1010: ERR_CONNECTION_CLOSED,
|
||||
1024: (ERR_INVALID_COLL_INDEX_GET, r"at index (?P<index>\d+) does"),
|
||||
1043: ERR_INVALID_NUMBER,
|
||||
1044: ERR_ORACLE_NUMBER_NO_REPR,
|
||||
1063: ERR_EXECUTE_MODE_ONLY_FOR_DML,
|
||||
1067: (ERR_CALL_TIMEOUT_EXCEEDED, r"call timeout of (?P<timeout>\d+) ms"),
|
||||
1080: ERR_CONNECTION_CLOSED,
|
||||
}
|
||||
|
||||
# error message exception types (multiples of 1000)
|
||||
ERR_EXCEPTION_TYPES = {
|
||||
1: exceptions.InterfaceError,
|
||||
2: exceptions.ProgrammingError,
|
||||
3: exceptions.NotSupportedError,
|
||||
4: exceptions.DatabaseError,
|
||||
5: exceptions.InternalError,
|
||||
6: exceptions.OperationalError,
|
||||
7: exceptions.Warning,
|
||||
}
|
||||
|
||||
# error messages that have a troubleshooting section available
|
||||
ERR_TROUBLESHOOTING_AVAILABLE = set(
|
||||
[
|
||||
"DPI-1047", # Oracle Client library cannot be loaded
|
||||
"DPI-1072", # Oracle Client library version is unsupported
|
||||
"DPY-3010", # connections to Oracle Database version not supported
|
||||
"DPY-3015", # password verifier type is not supported
|
||||
"DPY-4011", # the database or network closed the connection
|
||||
]
|
||||
)
|
||||
|
||||
# error message formats
|
||||
ERR_MESSAGE_FORMATS = {
|
||||
ERR_ACCESS_TOKEN_REQUIRES_TCPS: (
|
||||
"access_token requires use of the tcps protocol"
|
||||
),
|
||||
ERR_ARGS_MUST_BE_LIST_OR_TUPLE: "arguments must be a list or tuple",
|
||||
ERR_ARGS_AND_KEYWORD_ARGS: (
|
||||
"expecting positional arguments or keyword arguments, not both"
|
||||
),
|
||||
ERR_ARRAY_DML_ROW_COUNTS_NOT_ENABLED: (
|
||||
"array DML row counts mode is not enabled"
|
||||
),
|
||||
ERR_ARRAYS_OF_ARRAYS: "arrays of arrays are not supported",
|
||||
ERR_BUFFER_LENGTH_INSUFFICIENT: (
|
||||
"internal error: buffer of length {actual_buffer_len} "
|
||||
"insufficient to hold {required_buffer_len} bytes"
|
||||
),
|
||||
ERR_CALL_TIMEOUT_EXCEEDED: "call timeout of {timeout} ms exceeded",
|
||||
ERR_CANNOT_PARSE_CONNECT_STRING: 'cannot parse connect string "{data}"',
|
||||
ERR_COLUMN_TRUNCATED: (
|
||||
"column truncated to {col_value_len} {unit}. "
|
||||
"Untruncated was {actual_len}"
|
||||
),
|
||||
ERR_CONNECTION_FAILED: (
|
||||
"cannot connect to database (CONNECTION_ID={connection_id})."
|
||||
),
|
||||
ERR_CONTENT_INVALID_AFTER_NUMBER: "invalid number (content after number)",
|
||||
ERR_CURSOR_NOT_OPEN: "cursor is not open",
|
||||
ERR_DBOBJECT_ATTR_MAX_SIZE_VIOLATED: (
|
||||
"attribute {attr_name} of type {type_name} exceeds its maximum size "
|
||||
"(actual: {actual_size}, maximum: {max_size})"
|
||||
),
|
||||
ERR_DBOBJECT_ELEMENT_MAX_SIZE_VIOLATED: (
|
||||
"element {index} of type {type_name} exceeds its maximum size "
|
||||
"(actual: {actual_size}, maximum: {max_size})"
|
||||
),
|
||||
ERR_DB_TYPE_NOT_SUPPORTED: 'database type "{name}" is not supported',
|
||||
ERR_DUPLICATED_PARAMETER: (
|
||||
'"{deprecated_name}" and "{new_name}" cannot be specified together'
|
||||
),
|
||||
ERR_EXECUTE_MODE_ONLY_FOR_DML: (
|
||||
'parameters "batcherrors" and "arraydmlrowcounts" may only be '
|
||||
"true when used with insert, update, delete and merge statements"
|
||||
),
|
||||
ERR_EXPECTING_LIST_FOR_ARRAY_VAR: (
|
||||
"expecting list when setting array variables"
|
||||
),
|
||||
ERR_EXPECTING_TYPE: "expected a type",
|
||||
ERR_EXPECTING_VAR: (
|
||||
"type handler should return None or the value returned by a call "
|
||||
"to cursor.var()"
|
||||
),
|
||||
ERR_EXPIRED_ACCESS_TOKEN: "access token has expired",
|
||||
ERR_FEATURE_NOT_SUPPORTED: (
|
||||
"{feature} is only supported in python-oracledb {driver_type} mode"
|
||||
),
|
||||
ERR_HTTPS_PROXY_REQUIRES_TCPS: (
|
||||
"https_proxy requires use of the tcps protocol"
|
||||
),
|
||||
ERR_INCONSISTENT_DATATYPES: (
|
||||
"cannot convert from data type {input_type} to {output_type}"
|
||||
),
|
||||
ERR_INCORRECT_VAR_ARRAYSIZE: (
|
||||
"variable array size of {var_arraysize} is "
|
||||
"too small (should be at least {required_arraysize})"
|
||||
),
|
||||
ERR_INIT_ORACLE_CLIENT_NOT_CALLED: (
|
||||
"init_oracle_client() must be called first"
|
||||
),
|
||||
ERR_INTEGER_TOO_LARGE: (
|
||||
"internal error: read integer of length {length} when expecting "
|
||||
"integer of no more than length {max_length}"
|
||||
),
|
||||
ERR_INVALID_ACCESS_TOKEN_PARAM: (
|
||||
"invalid access token: value must be a string (for OAuth), a "
|
||||
"2-tuple containing the token and private key strings (for IAM), "
|
||||
"or a callable that returns a string or 2-tuple"
|
||||
),
|
||||
ERR_INVALID_ACCESS_TOKEN_RETURNED: (
|
||||
"invalid access token returned from callable: value must be a "
|
||||
"string (for OAuth) or a 2-tuple containing the token and private "
|
||||
"key strings (for IAM)"
|
||||
),
|
||||
ERR_INVALID_BIND_NAME: (
|
||||
'no bind placeholder named ":{name}" was found in the SQL text'
|
||||
),
|
||||
ERR_INVALID_CONN_CLASS: "invalid connection class",
|
||||
ERR_INVALID_CONNECT_DESCRIPTOR: 'invalid connect descriptor "{data}"',
|
||||
ERR_INVALID_CONNECT_PARAMS: "invalid connection params",
|
||||
ERR_INVALID_COLL_INDEX_GET: "element at index {index} does not exist",
|
||||
ERR_INVALID_COLL_INDEX_SET: (
|
||||
"given index {index} must be in the range of {min_index} to "
|
||||
"{max_index}"
|
||||
),
|
||||
ERR_INVALID_LOB_OFFSET: "LOB offset must be greater than zero",
|
||||
ERR_INVALID_MAKEDSN_ARG: '"{name}" argument contains invalid values',
|
||||
ERR_INVALID_NUMBER: "invalid number",
|
||||
ERR_INVALID_OBJECT_TYPE_NAME: 'invalid object type name: "{name}"',
|
||||
ERR_INVALID_OCI_ATTR_TYPE: "invalid OCI attribute type {attr_type}",
|
||||
ERR_INVALID_POOL_CLASS: "invalid connection pool class",
|
||||
ERR_INVALID_POOL_PARAMS: "invalid pool params",
|
||||
ERR_INVALID_POOL_PURITY: "invalid DRCP purity {purity}",
|
||||
ERR_INVALID_PROTOCOL: 'invalid protocol "{protocol}"',
|
||||
ERR_INVALID_REDIRECT_DATA: "invalid redirect data {data}",
|
||||
ERR_INVALID_REF_CURSOR: "invalid REF CURSOR: never opened in PL/SQL",
|
||||
ERR_INVALID_SERVER_CERT_DN: (
|
||||
"The distinguished name (DN) on the server certificate does not "
|
||||
"match the expected value"
|
||||
),
|
||||
ERR_INVALID_SERVER_TYPE: "invalid server_type: {server_type}",
|
||||
ERR_INVALID_SERVICE_NAME: (
|
||||
'Service "{service_name}" is not registered with the listener at '
|
||||
'host "{host}" port {port}. (Similar to ORA-12514)'
|
||||
),
|
||||
ERR_INVALID_SID: (
|
||||
'SID "{sid}" is not registered with the listener at host "{host}" '
|
||||
"port {port}. (Similar to ORA-12505)"
|
||||
),
|
||||
ERR_KEYWORD_ARGS_MUST_BE_DICT: (
|
||||
'"keyword_parameters" argument must be a dict'
|
||||
),
|
||||
ERR_LIBRARY_ALREADY_INITIALIZED: (
|
||||
"init_oracle_client() was already called with different arguments"
|
||||
),
|
||||
ERR_LISTENER_REFUSED_CONNECTION: (
|
||||
"Listener refused connection. (Similar to ORA-{error_code})"
|
||||
),
|
||||
ERR_LOB_OF_WRONG_TYPE: (
|
||||
"LOB is of type {actual_type_name} but must be of type "
|
||||
"{expected_type_name}"
|
||||
),
|
||||
ERR_MESSAGE_HAS_NO_PAYLOAD: "message has no payload",
|
||||
ERR_MESSAGE_TYPE_UNKNOWN: (
|
||||
"internal error: unknown protocol message type {message_type} "
|
||||
"at position {position}"
|
||||
),
|
||||
ERR_MISSING_BIND_VALUE: (
|
||||
'a bind variable replacement value for placeholder ":{name}" was '
|
||||
"not provided"
|
||||
),
|
||||
ERR_MISSING_QUOTE_IN_IDENTIFIER: 'missing ending quote (") in identifier',
|
||||
ERR_MISSING_QUOTE_IN_STRING: "missing ending quote (') in string",
|
||||
ERR_MISSING_TYPE_NAME_FOR_OBJECT_VAR: (
|
||||
"no object type specified for object variable"
|
||||
),
|
||||
ERR_MIXED_ELEMENT_TYPES: (
|
||||
"element {element} is not the same data type as previous elements"
|
||||
),
|
||||
ERR_MIXED_POSITIONAL_AND_NAMED_BINDS: (
|
||||
"positional and named binds cannot be intermixed"
|
||||
),
|
||||
ERR_NAMED_TIMEZONE_NOT_SUPPORTED: (
|
||||
"named time zones are not supported in thin mode"
|
||||
),
|
||||
ERR_NCHAR_CS_NOT_SUPPORTED: (
|
||||
"national character set id {charset_id} is not supported by "
|
||||
"python-oracledb in thin mode"
|
||||
),
|
||||
ERR_NO_CONFIG_DIR: "no configuration directory to search for tnsnames.ora",
|
||||
ERR_NO_CREDENTIALS: "no credentials specified",
|
||||
ERR_NO_CRYPTOGRAPHY_PACKAGE: (
|
||||
"python-oracledb thin mode cannot be used because the "
|
||||
"cryptography package is not installed"
|
||||
),
|
||||
ERR_NO_STATEMENT: "no statement specified and no prior statement prepared",
|
||||
ERR_NO_STATEMENT_EXECUTED: "no statement executed",
|
||||
ERR_NO_STATEMENT_PREPARED: "statement must be prepared first",
|
||||
ERR_NOT_A_QUERY: "the executed statement does not return rows",
|
||||
ERR_NOT_CONNECTED: "not connected to database",
|
||||
ERR_NUMBER_STRING_OF_ZERO_LENGTH: "invalid number: zero length string",
|
||||
ERR_NUMBER_STRING_TOO_LONG: "invalid number: string too long",
|
||||
ERR_NUMBER_WITH_EMPTY_EXPONENT: "invalid number: empty exponent",
|
||||
ERR_NUMBER_WITH_INVALID_EXPONENT: "invalid number: invalid exponent",
|
||||
ERR_OBJECT_IS_NOT_A_COLLECTION: "object {name} is not a collection",
|
||||
ERR_ORACLE_NUMBER_NO_REPR: (
|
||||
"value cannot be represented as an Oracle number"
|
||||
),
|
||||
ERR_ORACLE_TYPE_NAME_NOT_SUPPORTED: (
|
||||
'Oracle data type name "{name}" is not supported'
|
||||
),
|
||||
ERR_ORACLE_TYPE_NOT_SUPPORTED: "Oracle data type {num} is not supported",
|
||||
ERR_OSON_FIELD_NAME_LIMITATION: (
|
||||
"OSON field names may not exceed {max_fname_size} UTF-8 encoded bytes"
|
||||
),
|
||||
ERR_OSON_NODE_TYPE_NOT_SUPPORTED: (
|
||||
"OSON node type 0x{node_type:x} is not supported"
|
||||
),
|
||||
ERR_OSON_VERSION_NOT_SUPPORTED: "OSON version {version} is not supported",
|
||||
ERR_POOL_HAS_BUSY_CONNECTIONS: (
|
||||
"connection pool cannot be closed because connections are busy"
|
||||
),
|
||||
ERR_POOL_NO_CONNECTION_AVAILABLE: (
|
||||
"timed out waiting for the connection pool to return a connection"
|
||||
),
|
||||
ERR_POOL_NOT_OPEN: "connection pool is not open",
|
||||
ERR_PROXY_FAILURE: "network proxy failed: response was {response}",
|
||||
ERR_PYTHON_TYPE_NOT_SUPPORTED: "Python type {typ} is not supported",
|
||||
ERR_PYTHON_VALUE_NOT_SUPPORTED: (
|
||||
'Python value of type "{type_name}" is not supported'
|
||||
),
|
||||
ERR_SELF_BIND_NOT_SUPPORTED: "binding to self is not supported",
|
||||
ERR_CONNECTION_CLOSED: "the database or network closed the connection",
|
||||
ERR_SERVER_VERSION_NOT_SUPPORTED: (
|
||||
"connections to this database server version are not supported "
|
||||
"by python-oracledb in thin mode"
|
||||
),
|
||||
ERR_TDS_TYPE_NOT_SUPPORTED: "Oracle TDS data type {num} is not supported",
|
||||
ERR_THIN_CONNECTION_ALREADY_CREATED: (
|
||||
"python-oracledb thick mode cannot be used because a thin mode "
|
||||
"connection has already been created"
|
||||
),
|
||||
ERR_TIME_NOT_SUPPORTED: (
|
||||
"Oracle Database does not support time only variables"
|
||||
),
|
||||
ERR_TNS_ENTRY_NOT_FOUND: 'unable to find "{name}" in {file_name}',
|
||||
ERR_TNS_NAMES_FILE_MISSING: "file tnsnames.ora not found in {config_dir}",
|
||||
ERR_TOO_MANY_CURSORS_TO_CLOSE: (
|
||||
"internal error: attempt to close more than {num_cursors} cursors"
|
||||
),
|
||||
ERR_TOO_MANY_BATCH_ERRORS: (
|
||||
"the number of batch errors from executemany() exceeds 65535"
|
||||
),
|
||||
ERR_UNEXPECTED_DATA: "unexpected data received: {data}",
|
||||
ERR_UNEXPECTED_END_OF_DATA: (
|
||||
"unexpected end of data: want {num_bytes_wanted} bytes but "
|
||||
"only {num_bytes_available} bytes are available"
|
||||
),
|
||||
ERR_UNEXPECTED_NEGATIVE_INTEGER: (
|
||||
"internal error: read a negative integer when expecting a "
|
||||
"positive integer"
|
||||
),
|
||||
ERR_UNEXPECTED_REFUSE: (
|
||||
"the listener refused the connection but an unexpected error "
|
||||
"format was returned"
|
||||
),
|
||||
ERR_UNEXPECTED_XML_TYPE: "unexpected XMLType with flag {flag}",
|
||||
ERR_UNKOWN_SERVER_SIDE_PIGGYBACK: (
|
||||
"internal error: unknown server side piggyback opcode {opcode}"
|
||||
),
|
||||
ERR_UNSUPPORTED_INBAND_NOTIFICATION: (
|
||||
"unsupported in-band notification with error number {err_num}"
|
||||
),
|
||||
ERR_UNSUPPORTED_PYTHON_TYPE_FOR_DB_TYPE: (
|
||||
"unsupported Python type {py_type_name} for database type "
|
||||
"{db_type_name}"
|
||||
),
|
||||
ERR_UNSUPPORTED_TYPE_SET: "type {db_type_name} does not support being set",
|
||||
ERR_UNSUPPORTED_VERIFIER_TYPE: (
|
||||
"password verifier type 0x{verifier_type:x} is not supported by "
|
||||
"python-oracledb in thin mode"
|
||||
),
|
||||
ERR_WALLET_FILE_MISSING: "wallet file {name} was not found",
|
||||
ERR_WRONG_ARRAY_DEFINITION: (
|
||||
"expecting a list of two elements [type, numelems]"
|
||||
),
|
||||
ERR_WRONG_EXECUTE_PARAMETERS_TYPE: (
|
||||
"expecting a dictionary, list or tuple, or keyword args"
|
||||
),
|
||||
ERR_WRONG_EXECUTEMANY_PARAMETERS_TYPE: (
|
||||
'"parameters" argument should be a list of sequences or '
|
||||
"dictionaries, or an integer specifying the number of "
|
||||
"times to execute the statement"
|
||||
),
|
||||
ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS: (
|
||||
"{expected_num} positional bind values are required but "
|
||||
"{actual_num} were provided"
|
||||
),
|
||||
ERR_WRONG_OBJECT_TYPE: (
|
||||
'found object of type "{actual_schema}.{actual_name}" when '
|
||||
'expecting object of type "{expected_schema}.{expected_name}"'
|
||||
),
|
||||
ERR_WRONG_SCROLL_MODE: (
|
||||
"scroll mode must be relative, absolute, first or last"
|
||||
),
|
||||
WRN_COMPILATION_ERROR: "creation succeeded with compilation errors",
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# exceptions.py
|
||||
#
|
||||
# Contains the exception classes mandated by the Python Database API.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class Warning(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class DatabaseError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class DataError(DatabaseError):
|
||||
pass
|
||||
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
pass
|
||||
|
||||
|
||||
class InterfaceError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class InternalError(DatabaseError):
|
||||
pass
|
||||
|
||||
|
||||
class NotSupportedError(DatabaseError):
|
||||
pass
|
||||
|
||||
|
||||
class OperationalError(DatabaseError):
|
||||
pass
|
||||
|
||||
|
||||
class ProgrammingError(DatabaseError):
|
||||
pass
|
||||
@@ -0,0 +1,215 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# fetch_info.py
|
||||
#
|
||||
# Contains the FetchInfo class which stores metadata about columns that are
|
||||
# being fetched.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Union
|
||||
|
||||
from . import __name__ as MODULE_NAME
|
||||
from .dbobject import DbObjectType
|
||||
from .base_impl import (
|
||||
DbType,
|
||||
DB_TYPE_DATE,
|
||||
DB_TYPE_TIMESTAMP,
|
||||
DB_TYPE_TIMESTAMP_LTZ,
|
||||
DB_TYPE_TIMESTAMP_TZ,
|
||||
DB_TYPE_BINARY_FLOAT,
|
||||
DB_TYPE_BINARY_DOUBLE,
|
||||
DB_TYPE_BINARY_INTEGER,
|
||||
DB_TYPE_NUMBER,
|
||||
)
|
||||
|
||||
|
||||
class FetchInfo:
|
||||
"""
|
||||
Identifies metadata of columns that are being fetched.
|
||||
"""
|
||||
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __eq__(self, other):
|
||||
return tuple(self) == other
|
||||
|
||||
def __getitem__(self, index):
|
||||
"""
|
||||
Return the parts mandated by the Python Database API.
|
||||
"""
|
||||
if index == 0 or index == -7:
|
||||
return self.name
|
||||
elif index == 1 or index == -6:
|
||||
return self.type_code
|
||||
elif index == 2 or index == -5:
|
||||
return self.display_size
|
||||
elif index == 3 or index == -4:
|
||||
return self.internal_size
|
||||
elif index == 4 or index == -3:
|
||||
return self.precision
|
||||
elif index == 5 or index == -2:
|
||||
return self.scale
|
||||
elif index == 6 or index == -1:
|
||||
return self.null_ok
|
||||
elif isinstance(index, slice):
|
||||
return tuple(self).__getitem__(index)
|
||||
raise IndexError("list index out of range")
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Length mandated by the Python Database API.
|
||||
"""
|
||||
return 7
|
||||
|
||||
def __repr__(self):
|
||||
return repr(tuple(self))
|
||||
|
||||
def __str__(self):
|
||||
return str(tuple(self))
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
info = cls.__new__(cls)
|
||||
info._impl = impl
|
||||
info._type = None
|
||||
return info
|
||||
|
||||
@property
|
||||
def annotations(self) -> Union[dict, None]:
|
||||
"""
|
||||
Returns a dictionary of the annotations associated with the column, if
|
||||
applicable.
|
||||
"""
|
||||
return self._impl.annotations
|
||||
|
||||
@property
|
||||
def display_size(self) -> Union[int, None]:
|
||||
"""
|
||||
Returns the display size of the column.
|
||||
"""
|
||||
if self._impl.size > 0:
|
||||
return self._impl.size
|
||||
dbtype = self._impl.dbtype
|
||||
if (
|
||||
dbtype is DB_TYPE_DATE
|
||||
or dbtype is DB_TYPE_TIMESTAMP
|
||||
or dbtype is DB_TYPE_TIMESTAMP_LTZ
|
||||
or dbtype is DB_TYPE_TIMESTAMP_TZ
|
||||
):
|
||||
return 23
|
||||
elif (
|
||||
dbtype is DB_TYPE_BINARY_FLOAT
|
||||
or dbtype is DB_TYPE_BINARY_DOUBLE
|
||||
or dbtype is DB_TYPE_BINARY_INTEGER
|
||||
or dbtype is DB_TYPE_NUMBER
|
||||
):
|
||||
if self._impl.precision:
|
||||
display_size = self._impl.precision + 1
|
||||
if self._impl.scale > 0:
|
||||
display_size += self._impl.scale + 1
|
||||
else:
|
||||
display_size = 127
|
||||
return display_size
|
||||
|
||||
@property
|
||||
def domain_name(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the domain, if applicable.
|
||||
"""
|
||||
return self._impl.domain_name
|
||||
|
||||
@property
|
||||
def domain_schema(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the schema in which the domain is found, if
|
||||
applicable.
|
||||
"""
|
||||
return self._impl.domain_schema
|
||||
|
||||
@property
|
||||
def internal_size(self) -> Union[int, None]:
|
||||
"""
|
||||
Returns the size in bytes of the column.
|
||||
"""
|
||||
if self._impl.size > 0:
|
||||
return self._impl.buffer_size
|
||||
|
||||
@property
|
||||
def is_json(self) -> bool:
|
||||
"""
|
||||
Returns whether the column contains JSON.
|
||||
"""
|
||||
return self._impl.is_json
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Returns the name of the column.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
@property
|
||||
def null_ok(self) -> bool:
|
||||
"""
|
||||
Returns whether nulls or permitted or not in the column.
|
||||
"""
|
||||
return self._impl.nulls_allowed
|
||||
|
||||
@property
|
||||
def precision(self) -> Union[int, None]:
|
||||
"""
|
||||
Returns the precision of the column.
|
||||
"""
|
||||
if self._impl.precision or self._impl.scale:
|
||||
return self._impl.precision
|
||||
|
||||
@property
|
||||
def scale(self) -> Union[int, None]:
|
||||
"""
|
||||
Returns the scale of the column.
|
||||
"""
|
||||
if self._impl.precision or self._impl.scale:
|
||||
return self._impl.scale
|
||||
|
||||
@property
|
||||
def type(self) -> Union[DbType, DbObjectType]:
|
||||
"""
|
||||
Returns the type of the column, as either a database object type or a
|
||||
database type.
|
||||
"""
|
||||
if self._type is None:
|
||||
if self._impl.objtype is not None:
|
||||
self._type = DbObjectType._from_impl(self._impl.objtype)
|
||||
else:
|
||||
self._type = self._impl.dbtype
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def type_code(self) -> DbType:
|
||||
"""
|
||||
Returns the type of the column.
|
||||
"""
|
||||
return self._impl.dbtype
|
||||
@@ -0,0 +1,46 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# future.py
|
||||
#
|
||||
# Module for handling backwards incompatible changes.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
FEATURES = []
|
||||
|
||||
|
||||
# future object used for managing backwards incompatible changes
|
||||
class Future:
|
||||
def __getattr__(self, name):
|
||||
if name in FEATURES:
|
||||
return super().__getattr__(name)
|
||||
return None
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in FEATURES:
|
||||
return super().__setattr__(name, value)
|
||||
|
||||
|
||||
future = Future()
|
||||
@@ -0,0 +1,285 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# lob.py
|
||||
#
|
||||
# Contains the LOB class for managing BLOB, CLOB, NCLOB and BFILE data.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Any, Union
|
||||
|
||||
from . import __name__ as MODULE_NAME
|
||||
from . import errors
|
||||
|
||||
|
||||
class BaseLOB:
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __del__(self):
|
||||
self._impl.free_lob()
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
lob = cls.__new__(cls)
|
||||
lob._impl = impl
|
||||
return lob
|
||||
|
||||
@property
|
||||
def type(self) -> Any:
|
||||
"""
|
||||
Returns the type of the LOB as one of the database type constants.
|
||||
"""
|
||||
return self._impl.dbtype
|
||||
|
||||
|
||||
class LOB(BaseLOB):
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
def __reduce__(self):
|
||||
value = self.read()
|
||||
return (type(value), (value,))
|
||||
|
||||
def __str__(self):
|
||||
return self.read()
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
Close the LOB. Call this when writing is completed so that the indexes
|
||||
associated with the LOB can be updated -– but only if open() was called
|
||||
first.
|
||||
"""
|
||||
self._impl.close()
|
||||
|
||||
def fileexists(self) -> bool:
|
||||
"""
|
||||
Return a boolean indicating if the file referenced by a BFILE type LOB
|
||||
exists.
|
||||
"""
|
||||
return self._impl.file_exists()
|
||||
|
||||
def getchunksize(self) -> int:
|
||||
"""
|
||||
Return the chunk size for the LOB. Reading and writing to the LOB in
|
||||
chunks of multiples of this size will improve performance.
|
||||
"""
|
||||
return self._impl.get_chunk_size()
|
||||
|
||||
def getfilename(self) -> tuple:
|
||||
"""
|
||||
Return a two-tuple consisting of the directory alias and file name for
|
||||
a BFILE type LOB.
|
||||
"""
|
||||
return self._impl.get_file_name()
|
||||
|
||||
def isopen(self) -> bool:
|
||||
"""
|
||||
Return a boolean indicating if the LOB has been opened using the method
|
||||
open().
|
||||
"""
|
||||
return self._impl.get_is_open()
|
||||
|
||||
def open(self) -> None:
|
||||
"""
|
||||
Open the LOB for writing. This will improve performance when writing to
|
||||
the LOB in chunks and there are functional or extensible indexes
|
||||
associated with the LOB. If this method is not called, each write will
|
||||
perform an open internally followed by a close after the write has been
|
||||
completed.
|
||||
"""
|
||||
self._impl.open()
|
||||
|
||||
def read(self, offset: int = 1, amount: int = None) -> Union[str, bytes]:
|
||||
"""
|
||||
Return a portion (or all) of the data in the LOB. Note that the amount
|
||||
and offset are in bytes for BLOB and BFILE type LOBs and in UCS-2 code
|
||||
points for CLOB and NCLOB type LOBs. UCS-2 code points are equivalent
|
||||
to characters for all but supplemental characters. If supplemental
|
||||
characters are in the LOB, the offset and amount will have to be chosen
|
||||
carefully to avoid splitting a character.
|
||||
"""
|
||||
if amount is None:
|
||||
amount = self._impl.get_max_amount()
|
||||
if amount >= offset:
|
||||
amount = amount - offset + 1
|
||||
else:
|
||||
amount = 1
|
||||
if offset <= 0:
|
||||
errors._raise_err(errors.ERR_INVALID_LOB_OFFSET)
|
||||
return self._impl.read(offset, amount)
|
||||
|
||||
def setfilename(self, dir_alias: str, name: str) -> None:
|
||||
"""
|
||||
Set the directory alias and name of a BFILE type LOB.
|
||||
"""
|
||||
self._impl.set_file_name(dir_alias, name)
|
||||
|
||||
def size(self) -> int:
|
||||
"""
|
||||
Returns the size of the data in the LOB. For BLOB and BFILE type LOBs
|
||||
this is the number of bytes. For CLOB and NCLOB type LOBs this is the
|
||||
number of UCS-2 code points. UCS-2 code points are equivalent to
|
||||
characters for all but supplemental characters.
|
||||
"""
|
||||
return self._impl.get_size()
|
||||
|
||||
def trim(self, new_size: int = 0, *, newSize: int = None) -> None:
|
||||
"""
|
||||
Trim the LOB to the new size (the second parameter is deprecated and
|
||||
should not be used).
|
||||
"""
|
||||
if newSize is not None:
|
||||
if new_size != 0:
|
||||
errors._raise_err(
|
||||
errors.ERR_DUPLICATED_PARAMETER,
|
||||
deprecated_name="newSize",
|
||||
new_name="new_size",
|
||||
)
|
||||
new_size = newSize
|
||||
self._impl.trim(new_size)
|
||||
|
||||
def write(self, data: Union[str, bytes], offset: int = 1) -> None:
|
||||
"""
|
||||
Write the data to the LOB at the given offset. The offset is in bytes
|
||||
for BLOB type LOBs and in UCS-2 code points for CLOB and NCLOB type
|
||||
LOBs. UCS-2 code points are equivalent to characters for all but
|
||||
supplemental characters. If supplemental characters are in the LOB, the
|
||||
offset will have to be chosen carefully to avoid splitting a character.
|
||||
Note that if you want to make the LOB value smaller, you must use the
|
||||
trim() function.
|
||||
"""
|
||||
self._impl.write(data, offset)
|
||||
|
||||
|
||||
class AsyncLOB(BaseLOB):
|
||||
__module__ = MODULE_NAME
|
||||
|
||||
async def close(self) -> None:
|
||||
"""
|
||||
Close the LOB. Call this when writing is completed so that the indexes
|
||||
associated with the LOB can be updated -– but only if open() was called
|
||||
first.
|
||||
"""
|
||||
await self._impl.close()
|
||||
|
||||
async def fileexists(self) -> bool:
|
||||
"""
|
||||
Return a boolean indicating if the file referenced by a BFILE type LOB
|
||||
exists.
|
||||
"""
|
||||
return await self._impl.file_exists()
|
||||
|
||||
async def getchunksize(self) -> int:
|
||||
"""
|
||||
Return the chunk size for the LOB. Reading and writing to the LOB in
|
||||
chunks of multiples of this size will improve performance.
|
||||
"""
|
||||
return await self._impl.get_chunk_size()
|
||||
|
||||
async def getfilename(self) -> tuple:
|
||||
"""
|
||||
Return a two-tuple consisting of the directory alias and file name for
|
||||
a BFILE type LOB.
|
||||
"""
|
||||
return await self._impl.get_file_name()
|
||||
|
||||
async def isopen(self) -> bool:
|
||||
"""
|
||||
Return a boolean indicating if the LOB has been opened using the method
|
||||
open().
|
||||
"""
|
||||
return await self._impl.get_is_open()
|
||||
|
||||
async def open(self) -> None:
|
||||
"""
|
||||
Open the LOB for writing. This will improve performance when writing to
|
||||
the LOB in chunks and there are functional or extensible indexes
|
||||
associated with the LOB. If this method is not called, each write will
|
||||
perform an open internally followed by a close after the write has been
|
||||
completed.
|
||||
"""
|
||||
await self._impl.open()
|
||||
|
||||
async def read(
|
||||
self, offset: int = 1, amount: int = None
|
||||
) -> Union[str, bytes]:
|
||||
"""
|
||||
Return a portion (or all) of the data in the LOB. Note that the amount
|
||||
and offset are in bytes for BLOB and BFILE type LOBs and in UCS-2 code
|
||||
points for CLOB and NCLOB type LOBs. UCS-2 code points are equivalent
|
||||
to characters for all but supplemental characters. If supplemental
|
||||
characters are in the LOB, the offset and amount will have to be chosen
|
||||
carefully to avoid splitting a character.
|
||||
"""
|
||||
if amount is None:
|
||||
amount = self._impl.get_max_amount()
|
||||
if amount >= offset:
|
||||
amount = amount - offset + 1
|
||||
else:
|
||||
amount = 1
|
||||
if offset <= 0:
|
||||
errors._raise_err(errors.ERR_INVALID_LOB_OFFSET)
|
||||
return await self._impl.read(offset, amount)
|
||||
|
||||
async def setfilename(self, dir_alias: str, name: str) -> None:
|
||||
"""
|
||||
Set the directory alias and name of a BFILE type LOB.
|
||||
"""
|
||||
await self._impl.set_file_name(dir_alias, name)
|
||||
|
||||
async def size(self) -> int:
|
||||
"""
|
||||
Returns the size of the data in the LOB. For BLOB and BFILE type LOBs
|
||||
this is the number of bytes. For CLOB and NCLOB type LOBs this is the
|
||||
number of UCS-2 code points. UCS-2 code points are equivalent to
|
||||
characters for all but supplemental characters.
|
||||
"""
|
||||
return await self._impl.get_size()
|
||||
|
||||
async def trim(self, new_size: int = 0, *, newSize: int = None) -> None:
|
||||
"""
|
||||
Trim the LOB to the new size (the second parameter is deprecated and
|
||||
should not be used).
|
||||
"""
|
||||
if newSize is not None:
|
||||
if new_size != 0:
|
||||
errors._raise_err(
|
||||
errors.ERR_DUPLICATED_PARAMETER,
|
||||
deprecated_name="newSize",
|
||||
new_name="new_size",
|
||||
)
|
||||
new_size = newSize
|
||||
await self._impl.trim(new_size)
|
||||
|
||||
async def write(self, data: Union[str, bytes], offset: int = 1) -> None:
|
||||
"""
|
||||
Write the data to the LOB at the given offset. The offset is in bytes
|
||||
for BLOB type LOBs and in UCS-2 code points for CLOB and NCLOB type
|
||||
LOBs. UCS-2 code points are equivalent to characters for all but
|
||||
supplemental characters. If supplemental characters are in the LOB, the
|
||||
offset will have to be chosen carefully to avoid splitting a character.
|
||||
Note that if you want to make the LOB value smaller, you must use the
|
||||
trim() function.
|
||||
"""
|
||||
await self._impl.write(data, offset)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,759 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2022, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# pool_params.py
|
||||
#
|
||||
# Contains the PoolParams class used for managing the parameters required to
|
||||
# create a connection pool.
|
||||
#
|
||||
# *** NOTICE *** This file is generated from a template and should not be
|
||||
# modified directly. See build_from_template.py in the utils subdirectory for
|
||||
# more information.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Callable, Type, Union, Any
|
||||
|
||||
import oracledb
|
||||
|
||||
from . import base_impl, utils
|
||||
from .connect_params import ConnectParams
|
||||
|
||||
|
||||
class PoolParams(ConnectParams):
|
||||
"""
|
||||
Contains all parameters used for creating a connection pool.
|
||||
"""
|
||||
|
||||
__module__ = oracledb.__name__
|
||||
__slots__ = ["_impl"]
|
||||
_impl_class = base_impl.PoolParamsImpl
|
||||
|
||||
@utils.params_initer
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
min: int = 1,
|
||||
max: int = 2,
|
||||
increment: int = 1,
|
||||
connectiontype: Type["oracledb.Connection"] = None,
|
||||
getmode: int = oracledb.POOL_GETMODE_WAIT,
|
||||
homogeneous: bool = True,
|
||||
timeout: int = 0,
|
||||
wait_timeout: int = 0,
|
||||
max_lifetime_session: int = 0,
|
||||
session_callback: Callable = None,
|
||||
max_sessions_per_shard: int = 0,
|
||||
soda_metadata_cache: bool = False,
|
||||
ping_interval: int = 60,
|
||||
user: str = None,
|
||||
proxy_user: str = None,
|
||||
password: str = None,
|
||||
newpassword: str = None,
|
||||
wallet_password: str = None,
|
||||
access_token: Union[str, tuple, Callable] = None,
|
||||
host: str = None,
|
||||
port: int = 1521,
|
||||
protocol: str = "tcp",
|
||||
https_proxy: str = None,
|
||||
https_proxy_port: int = 0,
|
||||
service_name: str = None,
|
||||
sid: str = None,
|
||||
server_type: str = None,
|
||||
cclass: str = None,
|
||||
purity: int = oracledb.PURITY_DEFAULT,
|
||||
expire_time: int = 0,
|
||||
retry_count: int = 0,
|
||||
retry_delay: int = 0,
|
||||
tcp_connect_timeout: float = 60.0,
|
||||
ssl_server_dn_match: bool = True,
|
||||
ssl_server_cert_dn: str = None,
|
||||
wallet_location: str = None,
|
||||
events: bool = False,
|
||||
externalauth: bool = False,
|
||||
mode: int = oracledb.AUTH_MODE_DEFAULT,
|
||||
disable_oob: bool = False,
|
||||
stmtcachesize: int = oracledb.defaults.stmtcachesize,
|
||||
edition: str = None,
|
||||
tag: str = None,
|
||||
matchanytag: bool = False,
|
||||
config_dir: str = oracledb.defaults.config_dir,
|
||||
appcontext: list = None,
|
||||
shardingkey: list = None,
|
||||
supershardingkey: list = None,
|
||||
debug_jdwp: str = None,
|
||||
connection_id_prefix: str = None,
|
||||
ssl_context: Any = None,
|
||||
sdu: int = 8192,
|
||||
handle: int = 0,
|
||||
):
|
||||
"""
|
||||
All parameters are optional. A brief description of each parameter
|
||||
follows:
|
||||
|
||||
- min: the minimum number of connections the pool should contain
|
||||
(default: 1)
|
||||
|
||||
- max: the maximum number of connections the pool should contain
|
||||
(default: 2)
|
||||
|
||||
- increment: the number of connections that should be added to the pool
|
||||
whenever a new connection needs to be created (default: 1)
|
||||
|
||||
- connectiontype: the class of the connection that should be returned
|
||||
during calls to pool.acquire(). It must be Connection or a subclass
|
||||
of Connection (default: None)
|
||||
|
||||
- getmode: how pool.acquire() will behave. One of the constants
|
||||
oracledb.POOL_GETMODE_WAIT, oracledb.POOL_GETMODE_NOWAIT,
|
||||
oracledb.POOL_GETMODE_FORCEGET, or oracledb.POOL_GETMODE_TIMEDWAIT
|
||||
(default: oracledb.POOL_GETMODE_WAIT)
|
||||
|
||||
- homogeneous: a boolean indicating whether the connections are
|
||||
homogeneous (same user) or heterogeneous (multiple users) (default:
|
||||
True)
|
||||
|
||||
- timeout: length of time (in seconds) that a connection may remain
|
||||
idle in the pool before it is terminated. If it is 0 then connections
|
||||
are never terminated (default: 0)
|
||||
|
||||
- wait_timeout: length of time (in milliseconds) that a caller should
|
||||
wait when acquiring a connection from the pool with getmode set to
|
||||
oracledb.POOL_GETMODE_TIMEDWAIT (default: 0)
|
||||
|
||||
- max_lifetime_session: length of time (in seconds) that connections
|
||||
can remain in the pool. If it is 0 then connections may remain in the
|
||||
pool indefinitely (default: 0)
|
||||
|
||||
- session_callback: a callable that is invoked when a connection is
|
||||
returned from the pool for the first time, or when the connection tag
|
||||
differs from the one requested (default: None)
|
||||
|
||||
- max_sessions_per_shard: the maximum number of connections that may be
|
||||
associated with a particular shard (default: 0)
|
||||
|
||||
- soda_metadata_cache: boolean indicating whether or not the SODA
|
||||
metadata cache should be enabled (default: False)
|
||||
|
||||
- ping_interval: length of time (in seconds) after which an unused
|
||||
connection in the pool will be a candidate for pinging when
|
||||
pool.acquire() is called. If the ping to the database indicates the
|
||||
connection is not alive a replacement connection will be returned by
|
||||
pool.acquire(). If ping_interval is a negative value the ping
|
||||
functionality will be disabled (default: 60)
|
||||
|
||||
- user: the name of the user to connect to (default: None)
|
||||
|
||||
- proxy_user: the name of the proxy user to connect to. If this value
|
||||
is not specified, it will be parsed out of user if user is in the
|
||||
form "user[proxy_user]" (default: None)
|
||||
|
||||
- password: the password for the user (default: None)
|
||||
|
||||
- newpassword: the new password for the user. The new password will
|
||||
take effect immediately upon a successful connection to the database
|
||||
(default: None)
|
||||
|
||||
- wallet_password: the password to use to decrypt the wallet, if it is
|
||||
encrypted. This value is only used in thin mode (default: None)
|
||||
|
||||
- access_token: expected to be a string or a 2-tuple or a callable. If
|
||||
it is a string, it specifies an Azure AD OAuth2 token used for Open
|
||||
Authorization (OAuth 2.0) token based authentication. If it is a
|
||||
2-tuple, it specifies the token and private key strings used for
|
||||
Oracle Cloud Infrastructure (OCI) Identity and Access Management
|
||||
(IAM) token based authentication. If it is a callable, it returns
|
||||
either a string or a 2-tuple used for OAuth 2.0 or OCI IAM token
|
||||
based authentication and is useful when the pool needs to expand and
|
||||
create new connections but the current authentication token has
|
||||
expired (default: None)
|
||||
|
||||
- host: the name or IP address of the machine hosting the database or
|
||||
the database listener (default: None)
|
||||
|
||||
- port: the port number on which the database listener is listening
|
||||
(default: 1521)
|
||||
|
||||
- protocol: one of the strings "tcp" or "tcps" indicating whether to
|
||||
use unencrypted network traffic or encrypted network traffic (TLS)
|
||||
(default: "tcp")
|
||||
|
||||
- https_proxy: the name or IP address of a proxy host to use for
|
||||
tunneling secure connections (default: None)
|
||||
|
||||
- https_proxy_port: the port on which to communicate with the proxy
|
||||
host (default: 0)
|
||||
|
||||
- service_name: the service name of the database (default: None)
|
||||
|
||||
- sid: the system identifier (SID) of the database. Note using a
|
||||
service_name instead is recommended (default: None)
|
||||
|
||||
- server_type: the type of server connection that should be
|
||||
established. If specified, it should be one of "dedicated", "shared"
|
||||
or "pooled" (default: None)
|
||||
|
||||
- cclass: connection class to use for Database Resident Connection
|
||||
Pooling (DRCP) (default: None)
|
||||
|
||||
- purity: purity to use for Database Resident Connection Pooling (DRCP)
|
||||
(default: oracledb.PURITY_DEFAULT)
|
||||
|
||||
- expire_time: an integer indicating the number of minutes between the
|
||||
sending of keepalive probes. If this parameter is set to a value
|
||||
greater than zero it enables keepalive (default: 0)
|
||||
|
||||
- retry_count: the number of times that a connection attempt should be
|
||||
retried before the attempt is terminated (default: 0)
|
||||
|
||||
- retry_delay: the number of seconds to wait before making a new
|
||||
connection attempt (default: 0)
|
||||
|
||||
- tcp_connect_timeout: a float indicating the maximum number of seconds
|
||||
to wait for establishing a connection to the database host (default:
|
||||
60.0)
|
||||
|
||||
- ssl_server_dn_match: boolean indicating whether the server
|
||||
certificate distinguished name (DN) should be matched in addition to
|
||||
the regular certificate verification that is performed. Note that if
|
||||
the ssl_server_cert_dn parameter is not privided, host name matching
|
||||
is performed instead (default: True)
|
||||
|
||||
- ssl_server_cert_dn: the distinguished name (DN) which should be
|
||||
matched with the server. This value is ignored if the
|
||||
ssl_server_dn_match parameter is not set to the value True. If
|
||||
specified this value is used for any verfication. Otherwise the
|
||||
hostname will be used. (default: None)
|
||||
|
||||
- wallet_location: the directory where the wallet can be found. In thin
|
||||
mode this must be the directory containing the PEM-encoded wallet
|
||||
file ewallet.pem. In thick mode this must be the directory containing
|
||||
the file cwallet.sso (default: None)
|
||||
|
||||
- events: boolean specifying whether events mode should be enabled.
|
||||
This value is only used in thick mode and is needed for continuous
|
||||
query notification and high availability event notifications
|
||||
(default: False)
|
||||
|
||||
- externalauth: a boolean indicating whether to use external
|
||||
authentication (default: False)
|
||||
|
||||
- mode: authorization mode to use. For example
|
||||
oracledb.AUTH_MODE_SYSDBA (default: oracledb.AUTH_MODE_DEFAULT)
|
||||
|
||||
- disable_oob: boolean indicating whether out-of-band breaks should be
|
||||
disabled. This value is only used in thin mode. It has no effect on
|
||||
Windows which does not support this functionality (default: False)
|
||||
|
||||
- stmtcachesize: identifies the initial size of the statement cache
|
||||
(default: oracledb.defaults.stmtcachesize)
|
||||
|
||||
- edition: edition to use for the connection. This parameter cannot be
|
||||
used simultaneously with the cclass parameter (default: None)
|
||||
|
||||
- tag: identifies the type of connection that should be returned from a
|
||||
pool. This value is only used in thick mode (default: None)
|
||||
|
||||
- matchanytag: boolean specifying whether any tag can be used when
|
||||
acquiring a connection from the pool. This value is only used in
|
||||
thick mode. (default: False)
|
||||
|
||||
- config_dir: directory in which the optional tnsnames.ora
|
||||
configuration file is located. This value is only used in thin mode.
|
||||
For thick mode use the config_dir parameter of init_oracle_client()
|
||||
(default: oracledb.defaults.config_dir)
|
||||
|
||||
- appcontext: application context used by the connection. It should be
|
||||
a list of 3-tuples (namespace, name, value) and each entry in the
|
||||
tuple should be a string. This value is only used in thick mode
|
||||
(default: None)
|
||||
|
||||
- shardingkey: a list of strings, numbers, bytes or dates that identify
|
||||
the database shard to connect to. This value is only used in thick
|
||||
mode (default: None)
|
||||
|
||||
- supershardingkey: a list of strings, numbers, bytes or dates that
|
||||
identify the database shard to connect to. This value is only used in
|
||||
thick mode (default: None)
|
||||
|
||||
- debug_jdwp: a string with the format "host=<host>;port=<port>" that
|
||||
specifies the host and port of the PL/SQL debugger. This value is
|
||||
only used in thin mode. For thick mode set the ORA_DEBUG_JDWP
|
||||
environment variable (default: None)
|
||||
|
||||
- connection_id_prefix: an application specific prefix that is added to
|
||||
the connection identifier used for tracing (default: None)
|
||||
|
||||
- ssl_context: an SSLContext object used for connecting to the database
|
||||
using TLS. This SSL context will be modified to include the private
|
||||
key or any certificates found in a separately supplied wallet. This
|
||||
parameter should only be specified if the default SSLContext object
|
||||
cannot be used (default: None)
|
||||
|
||||
- sdu: the requested size of the Session Data Unit (SDU), in bytes. The
|
||||
value tunes internal buffers used for communication to the database.
|
||||
Bigger values can increase throughput for large queries or bulk data
|
||||
loads, but at the cost of higher memory use. The SDU size that will
|
||||
actually be used is negotiated down to the lower of this value and
|
||||
the database network SDU configuration value (default: 8192)
|
||||
|
||||
- handle: an integer representing a pointer to a valid service context
|
||||
handle. This value is only used in thick mode. It should be used with
|
||||
extreme caution (default: 0)
|
||||
"""
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
self.__class__.__qualname__
|
||||
+ "("
|
||||
+ f"min={self.min!r}, "
|
||||
+ f"max={self.max!r}, "
|
||||
+ f"increment={self.increment!r}, "
|
||||
+ f"connectiontype={self.connectiontype!r}, "
|
||||
+ f"getmode={self.getmode!r}, "
|
||||
+ f"homogeneous={self.homogeneous!r}, "
|
||||
+ f"timeout={self.timeout!r}, "
|
||||
+ f"wait_timeout={self.wait_timeout!r}, "
|
||||
+ f"max_lifetime_session={self.max_lifetime_session!r}, "
|
||||
+ f"session_callback={self.session_callback!r}, "
|
||||
+ f"max_sessions_per_shard={self.max_sessions_per_shard!r}, "
|
||||
+ f"soda_metadata_cache={self.soda_metadata_cache!r}, "
|
||||
+ f"ping_interval={self.ping_interval!r}, "
|
||||
+ f"user={self.user!r}, "
|
||||
+ f"proxy_user={self.proxy_user!r}, "
|
||||
+ f"host={self.host!r}, "
|
||||
+ f"port={self.port!r}, "
|
||||
+ f"protocol={self.protocol!r}, "
|
||||
+ f"https_proxy={self.https_proxy!r}, "
|
||||
+ f"https_proxy_port={self.https_proxy_port!r}, "
|
||||
+ f"service_name={self.service_name!r}, "
|
||||
+ f"sid={self.sid!r}, "
|
||||
+ f"server_type={self.server_type!r}, "
|
||||
+ f"cclass={self.cclass!r}, "
|
||||
+ f"purity={self.purity!r}, "
|
||||
+ f"expire_time={self.expire_time!r}, "
|
||||
+ f"retry_count={self.retry_count!r}, "
|
||||
+ f"retry_delay={self.retry_delay!r}, "
|
||||
+ f"tcp_connect_timeout={self.tcp_connect_timeout!r}, "
|
||||
+ f"ssl_server_dn_match={self.ssl_server_dn_match!r}, "
|
||||
+ f"ssl_server_cert_dn={self.ssl_server_cert_dn!r}, "
|
||||
+ f"wallet_location={self.wallet_location!r}, "
|
||||
+ f"events={self.events!r}, "
|
||||
+ f"externalauth={self.externalauth!r}, "
|
||||
+ f"mode={self.mode!r}, "
|
||||
+ f"disable_oob={self.disable_oob!r}, "
|
||||
+ f"stmtcachesize={self.stmtcachesize!r}, "
|
||||
+ f"edition={self.edition!r}, "
|
||||
+ f"tag={self.tag!r}, "
|
||||
+ f"matchanytag={self.matchanytag!r}, "
|
||||
+ f"config_dir={self.config_dir!r}, "
|
||||
+ f"appcontext={self.appcontext!r}, "
|
||||
+ f"shardingkey={self.shardingkey!r}, "
|
||||
+ f"supershardingkey={self.supershardingkey!r}, "
|
||||
+ f"debug_jdwp={self.debug_jdwp!r}, "
|
||||
+ f"connection_id_prefix={self.connection_id_prefix!r}, "
|
||||
+ f"ssl_context={self.ssl_context!r}, "
|
||||
+ f"sdu={self.sdu!r}"
|
||||
+ ")"
|
||||
)
|
||||
|
||||
@property
|
||||
def connectiontype(self) -> Type["oracledb.Connection"]:
|
||||
"""
|
||||
The class of the connection that should be returned during calls to
|
||||
pool.acquire(). It must be Connection or a subclass of Connection.
|
||||
"""
|
||||
return self._impl.connectiontype
|
||||
|
||||
@property
|
||||
def getmode(self) -> int:
|
||||
"""
|
||||
How pool.acquire() will behave. One of the constants
|
||||
oracledb.POOL_GETMODE_WAIT, oracledb.POOL_GETMODE_NOWAIT,
|
||||
oracledb.POOL_GETMODE_FORCEGET, or oracledb.POOL_GETMODE_TIMEDWAIT.
|
||||
"""
|
||||
return self._impl.getmode
|
||||
|
||||
@property
|
||||
def homogeneous(self) -> bool:
|
||||
"""
|
||||
A boolean indicating whether the connections are homogeneous (same
|
||||
user) or heterogeneous (multiple users).
|
||||
"""
|
||||
return self._impl.homogeneous
|
||||
|
||||
@property
|
||||
def increment(self) -> int:
|
||||
"""
|
||||
The number of connections that should be added to the pool whenever a
|
||||
new connection needs to be created.
|
||||
"""
|
||||
return self._impl.increment
|
||||
|
||||
@property
|
||||
def max(self) -> int:
|
||||
"""
|
||||
The maximum number of connections the pool should contain.
|
||||
"""
|
||||
return self._impl.max
|
||||
|
||||
@property
|
||||
def max_lifetime_session(self) -> int:
|
||||
"""
|
||||
Length of time (in seconds) that connections can remain in the pool. If
|
||||
it is 0 then connections may remain in the pool indefinitely.
|
||||
"""
|
||||
return self._impl.max_lifetime_session
|
||||
|
||||
@property
|
||||
def max_sessions_per_shard(self) -> int:
|
||||
"""
|
||||
The maximum number of connections that may be associated with a
|
||||
particular shard.
|
||||
"""
|
||||
return self._impl.max_sessions_per_shard
|
||||
|
||||
@property
|
||||
def min(self) -> int:
|
||||
"""
|
||||
The minimum number of connections the pool should contain.
|
||||
"""
|
||||
return self._impl.min
|
||||
|
||||
@property
|
||||
def ping_interval(self) -> int:
|
||||
"""
|
||||
Length of time (in seconds) after which an unused connection in the
|
||||
pool will be a candidate for pinging when pool.acquire() is called. If
|
||||
the ping to the database indicates the connection is not alive a
|
||||
replacement connection will be returned by pool.acquire(). If
|
||||
ping_interval is a negative value the ping functionality will be
|
||||
disabled.
|
||||
"""
|
||||
return self._impl.ping_interval
|
||||
|
||||
@property
|
||||
def session_callback(self) -> Callable:
|
||||
"""
|
||||
A callable that is invoked when a connection is returned from the pool
|
||||
for the first time, or when the connection tag differs from the one
|
||||
requested.
|
||||
"""
|
||||
return self._impl.session_callback
|
||||
|
||||
@property
|
||||
def soda_metadata_cache(self) -> bool:
|
||||
"""
|
||||
Boolean indicating whether or not the SODA metadata cache should be
|
||||
enabled.
|
||||
"""
|
||||
return self._impl.soda_metadata_cache
|
||||
|
||||
@property
|
||||
def timeout(self) -> int:
|
||||
"""
|
||||
Length of time (in seconds) that a connection may remain idle in the
|
||||
pool before it is terminated. If it is 0 then connections are never
|
||||
terminated.
|
||||
"""
|
||||
return self._impl.timeout
|
||||
|
||||
@property
|
||||
def wait_timeout(self) -> int:
|
||||
"""
|
||||
Length of time (in milliseconds) that a caller should wait when
|
||||
acquiring a connection from the pool with getmode set to
|
||||
oracledb.POOL_GETMODE_TIMEDWAIT.
|
||||
"""
|
||||
return self._impl.wait_timeout
|
||||
|
||||
def copy(self) -> "PoolParams":
|
||||
"""
|
||||
Creates a copy of the parameters and returns it.
|
||||
"""
|
||||
params = PoolParams.__new__(PoolParams)
|
||||
params._impl = self._impl.copy()
|
||||
return params
|
||||
|
||||
@utils.params_setter
|
||||
def set(
|
||||
self,
|
||||
*,
|
||||
min: int = None,
|
||||
max: int = None,
|
||||
increment: int = None,
|
||||
connectiontype: Type["oracledb.Connection"] = None,
|
||||
getmode: int = None,
|
||||
homogeneous: bool = None,
|
||||
timeout: int = None,
|
||||
wait_timeout: int = None,
|
||||
max_lifetime_session: int = None,
|
||||
session_callback: Callable = None,
|
||||
max_sessions_per_shard: int = None,
|
||||
soda_metadata_cache: bool = None,
|
||||
ping_interval: int = None,
|
||||
user: str = None,
|
||||
proxy_user: str = None,
|
||||
password: str = None,
|
||||
newpassword: str = None,
|
||||
wallet_password: str = None,
|
||||
access_token: Union[str, tuple, Callable] = None,
|
||||
host: str = None,
|
||||
port: int = None,
|
||||
protocol: str = None,
|
||||
https_proxy: str = None,
|
||||
https_proxy_port: int = None,
|
||||
service_name: str = None,
|
||||
sid: str = None,
|
||||
server_type: str = None,
|
||||
cclass: str = None,
|
||||
purity: int = None,
|
||||
expire_time: int = None,
|
||||
retry_count: int = None,
|
||||
retry_delay: int = None,
|
||||
tcp_connect_timeout: float = None,
|
||||
ssl_server_dn_match: bool = None,
|
||||
ssl_server_cert_dn: str = None,
|
||||
wallet_location: str = None,
|
||||
events: bool = None,
|
||||
externalauth: bool = None,
|
||||
mode: int = None,
|
||||
disable_oob: bool = None,
|
||||
stmtcachesize: int = None,
|
||||
edition: str = None,
|
||||
tag: str = None,
|
||||
matchanytag: bool = None,
|
||||
config_dir: str = None,
|
||||
appcontext: list = None,
|
||||
shardingkey: list = None,
|
||||
supershardingkey: list = None,
|
||||
debug_jdwp: str = None,
|
||||
connection_id_prefix: str = None,
|
||||
ssl_context: Any = None,
|
||||
sdu: int = None,
|
||||
handle: int = None,
|
||||
):
|
||||
"""
|
||||
All parameters are optional. A brief description of each parameter
|
||||
follows:
|
||||
|
||||
- min: the minimum number of connections the pool should contain
|
||||
|
||||
- max: the maximum number of connections the pool should contain
|
||||
|
||||
- increment: the number of connections that should be added to the pool
|
||||
whenever a new connection needs to be created
|
||||
|
||||
- connectiontype: the class of the connection that should be returned
|
||||
during calls to pool.acquire(). It must be Connection or a subclass
|
||||
of Connection
|
||||
|
||||
- getmode: how pool.acquire() will behave. One of the constants
|
||||
oracledb.POOL_GETMODE_WAIT, oracledb.POOL_GETMODE_NOWAIT,
|
||||
oracledb.POOL_GETMODE_FORCEGET, or oracledb.POOL_GETMODE_TIMEDWAIT
|
||||
|
||||
- homogeneous: a boolean indicating whether the connections are
|
||||
homogeneous (same user) or heterogeneous (multiple users)
|
||||
|
||||
- timeout: length of time (in seconds) that a connection may remain
|
||||
idle in the pool before it is terminated. If it is 0 then connections
|
||||
are never terminated
|
||||
|
||||
- wait_timeout: length of time (in milliseconds) that a caller should
|
||||
wait when acquiring a connection from the pool with getmode set to
|
||||
oracledb.POOL_GETMODE_TIMEDWAIT
|
||||
|
||||
- max_lifetime_session: length of time (in seconds) that connections
|
||||
can remain in the pool. If it is 0 then connections may remain in the
|
||||
pool indefinitely
|
||||
|
||||
- session_callback: a callable that is invoked when a connection is
|
||||
returned from the pool for the first time, or when the connection tag
|
||||
differs from the one requested
|
||||
|
||||
- max_sessions_per_shard: the maximum number of connections that may be
|
||||
associated with a particular shard
|
||||
|
||||
- soda_metadata_cache: boolean indicating whether or not the SODA
|
||||
metadata cache should be enabled
|
||||
|
||||
- ping_interval: length of time (in seconds) after which an unused
|
||||
connection in the pool will be a candidate for pinging when
|
||||
pool.acquire() is called. If the ping to the database indicates the
|
||||
connection is not alive a replacement connection will be returned by
|
||||
pool.acquire(). If ping_interval is a negative value the ping
|
||||
functionality will be disabled
|
||||
|
||||
- user: the name of the user to connect to
|
||||
|
||||
- proxy_user: the name of the proxy user to connect to. If this value
|
||||
is not specified, it will be parsed out of user if user is in the
|
||||
form "user[proxy_user]"
|
||||
|
||||
- password: the password for the user
|
||||
|
||||
- newpassword: the new password for the user. The new password will
|
||||
take effect immediately upon a successful connection to the database
|
||||
|
||||
- wallet_password: the password to use to decrypt the wallet, if it is
|
||||
encrypted. This value is only used in thin mode
|
||||
|
||||
- access_token: expected to be a string or a 2-tuple or a callable. If
|
||||
it is a string, it specifies an Azure AD OAuth2 token used for Open
|
||||
Authorization (OAuth 2.0) token based authentication. If it is a
|
||||
2-tuple, it specifies the token and private key strings used for
|
||||
Oracle Cloud Infrastructure (OCI) Identity and Access Management
|
||||
(IAM) token based authentication. If it is a callable, it returns
|
||||
either a string or a 2-tuple used for OAuth 2.0 or OCI IAM token
|
||||
based authentication and is useful when the pool needs to expand and
|
||||
create new connections but the current authentication token has
|
||||
expired
|
||||
|
||||
- host: the name or IP address of the machine hosting the database or
|
||||
the database listener
|
||||
|
||||
- port: the port number on which the database listener is listening
|
||||
|
||||
- protocol: one of the strings "tcp" or "tcps" indicating whether to
|
||||
use unencrypted network traffic or encrypted network traffic (TLS)
|
||||
|
||||
- https_proxy: the name or IP address of a proxy host to use for
|
||||
tunneling secure connections
|
||||
|
||||
- https_proxy_port: the port on which to communicate with the proxy
|
||||
host
|
||||
|
||||
- service_name: the service name of the database
|
||||
|
||||
- sid: the system identifier (SID) of the database. Note using a
|
||||
service_name instead is recommended
|
||||
|
||||
- server_type: the type of server connection that should be
|
||||
established. If specified, it should be one of "dedicated", "shared"
|
||||
or "pooled"
|
||||
|
||||
- cclass: connection class to use for Database Resident Connection
|
||||
Pooling (DRCP)
|
||||
|
||||
- purity: purity to use for Database Resident Connection Pooling (DRCP)
|
||||
|
||||
- expire_time: an integer indicating the number of minutes between the
|
||||
sending of keepalive probes. If this parameter is set to a value
|
||||
greater than zero it enables keepalive
|
||||
|
||||
- retry_count: the number of times that a connection attempt should be
|
||||
retried before the attempt is terminated
|
||||
|
||||
- retry_delay: the number of seconds to wait before making a new
|
||||
connection attempt
|
||||
|
||||
- tcp_connect_timeout: a float indicating the maximum number of seconds
|
||||
to wait for establishing a connection to the database host
|
||||
|
||||
- ssl_server_dn_match: boolean indicating whether the server
|
||||
certificate distinguished name (DN) should be matched in addition to
|
||||
the regular certificate verification that is performed. Note that if
|
||||
the ssl_server_cert_dn parameter is not privided, host name matching
|
||||
is performed instead
|
||||
|
||||
- ssl_server_cert_dn: the distinguished name (DN) which should be
|
||||
matched with the server. This value is ignored if the
|
||||
ssl_server_dn_match parameter is not set to the value True. If
|
||||
specified this value is used for any verfication. Otherwise the
|
||||
hostname will be used.
|
||||
|
||||
- wallet_location: the directory where the wallet can be found. In thin
|
||||
mode this must be the directory containing the PEM-encoded wallet
|
||||
file ewallet.pem. In thick mode this must be the directory containing
|
||||
the file cwallet.sso
|
||||
|
||||
- events: boolean specifying whether events mode should be enabled.
|
||||
This value is only used in thick mode and is needed for continuous
|
||||
query notification and high availability event notifications
|
||||
|
||||
- externalauth: a boolean indicating whether to use external
|
||||
authentication
|
||||
|
||||
- mode: authorization mode to use. For example
|
||||
oracledb.AUTH_MODE_SYSDBA
|
||||
|
||||
- disable_oob: boolean indicating whether out-of-band breaks should be
|
||||
disabled. This value is only used in thin mode. It has no effect on
|
||||
Windows which does not support this functionality
|
||||
|
||||
- stmtcachesize: identifies the initial size of the statement cache
|
||||
|
||||
- edition: edition to use for the connection. This parameter cannot be
|
||||
used simultaneously with the cclass parameter
|
||||
|
||||
- tag: identifies the type of connection that should be returned from a
|
||||
pool. This value is only used in thick mode
|
||||
|
||||
- matchanytag: boolean specifying whether any tag can be used when
|
||||
acquiring a connection from the pool. This value is only used in
|
||||
thick mode.
|
||||
|
||||
- config_dir: directory in which the optional tnsnames.ora
|
||||
configuration file is located. This value is only used in thin mode.
|
||||
For thick mode use the config_dir parameter of init_oracle_client()
|
||||
|
||||
- appcontext: application context used by the connection. It should be
|
||||
a list of 3-tuples (namespace, name, value) and each entry in the
|
||||
tuple should be a string. This value is only used in thick mode
|
||||
|
||||
- shardingkey: a list of strings, numbers, bytes or dates that identify
|
||||
the database shard to connect to. This value is only used in thick
|
||||
mode
|
||||
|
||||
- supershardingkey: a list of strings, numbers, bytes or dates that
|
||||
identify the database shard to connect to. This value is only used in
|
||||
thick mode
|
||||
|
||||
- debug_jdwp: a string with the format "host=<host>;port=<port>" that
|
||||
specifies the host and port of the PL/SQL debugger. This value is
|
||||
only used in thin mode. For thick mode set the ORA_DEBUG_JDWP
|
||||
environment variable
|
||||
|
||||
- connection_id_prefix: an application specific prefix that is added to
|
||||
the connection identifier used for tracing
|
||||
|
||||
- ssl_context: an SSLContext object used for connecting to the database
|
||||
using TLS. This SSL context will be modified to include the private
|
||||
key or any certificates found in a separately supplied wallet. This
|
||||
parameter should only be specified if the default SSLContext object
|
||||
cannot be used
|
||||
|
||||
- sdu: the requested size of the Session Data Unit (SDU), in bytes. The
|
||||
value tunes internal buffers used for communication to the database.
|
||||
Bigger values can increase throughput for large queries or bulk data
|
||||
loads, but at the cost of higher memory use. The SDU size that will
|
||||
actually be used is negotiated down to the lower of this value and
|
||||
the database network SDU configuration value
|
||||
|
||||
- handle: an integer representing a pointer to a valid service context
|
||||
handle. This value is only used in thick mode. It should be used with
|
||||
extreme caution
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,685 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# soda.py
|
||||
#
|
||||
# Contains the classes for managing Simple Oracle Document Access (SODA):
|
||||
# SodaDatabase, SodaCollection, SodaDocument, SodaDocCursor and SodaOperation.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Any, Union, List
|
||||
import json
|
||||
|
||||
from . import errors
|
||||
|
||||
|
||||
class SodaDatabase:
|
||||
def __repr__(self):
|
||||
return f"<oracledb.SodaDatabase on {self._conn!r}>"
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, conn, impl):
|
||||
db = cls.__new__(cls)
|
||||
db._conn = conn
|
||||
db._impl = impl
|
||||
return db
|
||||
|
||||
def _get_content_bytes(self, content: Any) -> bytes:
|
||||
"""
|
||||
Internal method used for returning the bytes to store in document
|
||||
content.
|
||||
"""
|
||||
if isinstance(content, str):
|
||||
return content.encode()
|
||||
elif isinstance(content, bytes):
|
||||
return content
|
||||
return json.dumps(content).encode()
|
||||
|
||||
def createCollection(
|
||||
self,
|
||||
name: str,
|
||||
metadata: Union[str, dict] = None,
|
||||
mapMode: bool = False,
|
||||
) -> "SodaCollection":
|
||||
"""
|
||||
Creates a SODA collection with the given name and returns a new SODA
|
||||
collection object. If you try to create a collection, and a collection
|
||||
with the same name and metadata already exists, then that existing
|
||||
collection is opened without error.
|
||||
|
||||
If metadata is specified, it is expected to be a string containing
|
||||
valid JSON or a dictionary that will be transformed into a JSON string.
|
||||
This JSON permits you to specify the configuration of the collection
|
||||
including storage options; specifying the presence or absence of
|
||||
columns for creation timestamp, last modified timestamp and version;
|
||||
whether the collection can store only JSON documents; and methods of
|
||||
key and version generation. The default metadata creates a collection
|
||||
that only supports JSON documents and uses system generated keys.
|
||||
|
||||
If the mapMode parameter is set to True, the new collection is mapped
|
||||
to an existing table instead of creating a table. If a collection is
|
||||
created in this way, dropping the collection will not drop the existing
|
||||
table either.
|
||||
"""
|
||||
if metadata is not None and not isinstance(metadata, str):
|
||||
metadata = json.dumps(metadata)
|
||||
collection_impl = self._impl.create_collection(name, metadata, mapMode)
|
||||
return SodaCollection._from_impl(self, collection_impl)
|
||||
|
||||
def createDocument(
|
||||
self,
|
||||
content: Any,
|
||||
key: str = None,
|
||||
mediaType: str = "application/json",
|
||||
) -> "SodaDocument":
|
||||
"""
|
||||
Creates a SODA document usable for SODA write operations. You only need
|
||||
to use this method if your collection requires client-assigned keys or
|
||||
has non-JSON content; otherwise, you can pass your content directly to
|
||||
SODA write operations. SodaDocument attributes "createdOn",
|
||||
"lastModified" and "version" will be None.
|
||||
|
||||
The content parameter can be a dictionary or list which will be
|
||||
transformed into a JSON string and then UTF-8 encoded. It can also be a
|
||||
string which will be UTF-8 encoded or it can be a bytes object which
|
||||
will be stored unchanged. If a bytes object is provided and the content
|
||||
is expected to be JSON, note that SODA only supports UTF-8, UTF-16LE
|
||||
and UTF-16BE encodings.
|
||||
|
||||
The key parameter should only be supplied if the collection in which
|
||||
the document is to be placed requires client-assigned keys.
|
||||
|
||||
The mediaType parameter should only be supplied if the collection in
|
||||
which the document is to be placed supports non-JSON documents and the
|
||||
content for this document is non-JSON. Using a standard MIME type for
|
||||
this value is recommended but any string will be accepted.
|
||||
"""
|
||||
content_bytes = self._get_content_bytes(content)
|
||||
doc_impl = self._impl.create_document(content_bytes, key, mediaType)
|
||||
return SodaDocument._from_impl(doc_impl)
|
||||
|
||||
def getCollectionNames(
|
||||
self, startName: str = None, limit: int = 0
|
||||
) -> List[str]:
|
||||
"""
|
||||
Returns a list of the names of collections in the database that match
|
||||
the criteria, in alphabetical order.
|
||||
|
||||
If the startName parameter is specified, the list of names returned
|
||||
will start with this value and also contain any names that fall after
|
||||
this value in alphabetical order.
|
||||
|
||||
If the limit parameter is specified and is non-zero, the number of
|
||||
collection names returned will be limited to this value.
|
||||
"""
|
||||
return self._impl.get_collection_names(startName, limit)
|
||||
|
||||
def openCollection(self, name: str) -> "SodaCollection":
|
||||
"""
|
||||
Opens an existing collection with the given name and returns a new SODA
|
||||
collection object. If a collection with that name does not exist, None
|
||||
is returned.
|
||||
"""
|
||||
collection_impl = self._impl.open_collection(name)
|
||||
if collection_impl is not None:
|
||||
return SodaCollection._from_impl(self, collection_impl)
|
||||
|
||||
|
||||
class SodaCollection:
|
||||
@classmethod
|
||||
def _from_impl(cls, db, impl):
|
||||
coll = cls.__new__(cls)
|
||||
coll._db = db
|
||||
coll._impl = impl
|
||||
return coll
|
||||
|
||||
def _process_doc_arg(self, arg):
|
||||
if isinstance(arg, SodaDocument):
|
||||
return arg._impl
|
||||
content_bytes = self._db._get_content_bytes(arg)
|
||||
return self._db._impl.create_document(content_bytes, None, None)
|
||||
|
||||
def createIndex(self, spec: Union[dict, str]) -> None:
|
||||
"""
|
||||
Creates an index on a SODA collection. The spec is expected to be a
|
||||
dictionary or a JSON-encoded string.
|
||||
|
||||
Note that a commit should be performed before attempting to create an
|
||||
index.
|
||||
"""
|
||||
if isinstance(spec, dict):
|
||||
spec = json.dumps(spec)
|
||||
elif not isinstance(spec, str):
|
||||
raise TypeError("expecting a dictionary or string")
|
||||
self._impl.create_index(spec)
|
||||
|
||||
def drop(self) -> bool:
|
||||
"""
|
||||
Drops the collection from the database, if it exists. Note that if the
|
||||
collection was created with mapMode set to True the underlying table
|
||||
will not be dropped.
|
||||
|
||||
A boolean value is returned indicating if the collection was actually
|
||||
dropped.
|
||||
"""
|
||||
return self._impl.drop()
|
||||
|
||||
def dropIndex(self, name: str, force: bool = False) -> bool:
|
||||
"""
|
||||
Drops the index with the specified name, if it exists.
|
||||
|
||||
The force parameter, if set to True, can be used to force the dropping
|
||||
of an index that the underlying Oracle Database domain index doesn’t
|
||||
normally permit. This is only applicable to spatial and JSON search
|
||||
indexes. See here for more information.
|
||||
|
||||
A boolean value is returned indicating if the index was actually
|
||||
dropped.
|
||||
"""
|
||||
return self._impl.drop_index(name, force)
|
||||
|
||||
def find(self) -> "SodaOperation":
|
||||
"""
|
||||
This method is used to begin an operation that will act upon documents
|
||||
in the collection. It creates and returns a SodaOperation object which
|
||||
is used to specify the criteria and the operation that will be
|
||||
performed on the documents that match that criteria.
|
||||
"""
|
||||
return SodaOperation(self)
|
||||
|
||||
def getDataGuide(self) -> "SodaDocument":
|
||||
"""
|
||||
Returns a SODA document object containing property names, data types
|
||||
and lengths inferred from the JSON documents in the collection. It can
|
||||
be useful for exploring the schema of a collection. Note that this
|
||||
method is only supported for JSON-only collections where a JSON search
|
||||
index has been created with the ‘dataguide’ option enabled. If there
|
||||
are no documents in the collection, None is returned.
|
||||
"""
|
||||
doc_impl = self._impl.get_data_guide()
|
||||
if doc_impl is not None:
|
||||
return SodaDocument._from_impl(doc_impl)
|
||||
|
||||
def insertMany(self, docs: list) -> None:
|
||||
"""
|
||||
Inserts a list of documents into the collection at one time. Each of
|
||||
the input documents can be a dictionary or list or an existing SODA
|
||||
document object.
|
||||
"""
|
||||
doc_impls = [self._process_doc_arg(d) for d in docs]
|
||||
self._impl.insert_many(doc_impls, hint=None, return_docs=False)
|
||||
|
||||
def insertManyAndGet(self, docs: list, hint: str = None) -> list:
|
||||
"""
|
||||
Similarly to insertMany() this method inserts a list of documents into
|
||||
the collection at one time. The only difference is that it returns a
|
||||
list of SODA Document objects. Note that for performance reasons the
|
||||
returned documents do not contain the content.
|
||||
|
||||
The hint parameter, if specified, supplies a hint to the database when
|
||||
processing the SODA operation. This is expected to be a string in the
|
||||
same format as SQL hints but without any comment characters, for
|
||||
example hint="MONITOR". While you could use this to pass any SQL hint,
|
||||
the hints MONITOR (turn on monitoring) and NO_MONITOR (turn off
|
||||
monitoring) are the most useful. Use of the hint parameter requires
|
||||
Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11).
|
||||
"""
|
||||
doc_impls = [self._process_doc_arg(d) for d in docs]
|
||||
if hint is not None and not isinstance(hint, str):
|
||||
raise TypeError("expecting a string")
|
||||
return_doc_impls = self._impl.insert_many(
|
||||
doc_impls, hint, return_docs=True
|
||||
)
|
||||
return [SodaDocument._from_impl(i) for i in return_doc_impls]
|
||||
|
||||
def insertOne(self, doc: Any) -> None:
|
||||
"""
|
||||
Inserts a given document into the collection. The input document can be
|
||||
a dictionary or list or an existing SODA document object.
|
||||
"""
|
||||
doc_impl = self._process_doc_arg(doc)
|
||||
self._impl.insert_one(doc_impl, hint=None, return_doc=False)
|
||||
|
||||
def insertOneAndGet(self, doc: Any, hint: str = None) -> "SodaDocument":
|
||||
"""
|
||||
Similarly to insertOne() this method inserts a given document into the
|
||||
collection. The only difference is that it returns a SODA Document
|
||||
object. Note that for performance reasons the returned document does
|
||||
not contain the content.
|
||||
|
||||
The hint parameter, if specified, supplies a hint to the database when
|
||||
processing the SODA operation. This is expected to be a string in the
|
||||
same format as SQL hints but without any comment characters, for
|
||||
example hint="MONITOR". While you could use this to pass any SQL hint,
|
||||
the hints MONITOR (turn on monitoring) and NO_MONITOR (turn off
|
||||
monitoring) are the most useful. Use of the hint parameter requires
|
||||
Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11).
|
||||
"""
|
||||
doc_impl = self._process_doc_arg(doc)
|
||||
if hint is not None and not isinstance(hint, str):
|
||||
raise TypeError("expecting a string")
|
||||
return_doc_impl = self._impl.insert_one(
|
||||
doc_impl, hint, return_doc=True
|
||||
)
|
||||
return SodaDocument._from_impl(return_doc_impl)
|
||||
|
||||
def listIndexes(self) -> list:
|
||||
"""
|
||||
Return a list of indexes associated with the collection.
|
||||
"""
|
||||
return [json.loads(s) for s in self._impl.list_indexes()]
|
||||
|
||||
@property
|
||||
def metadata(self) -> dict:
|
||||
"""
|
||||
This read-only attribute returns a dictionary containing the metadata
|
||||
that was used to create the collection.
|
||||
"""
|
||||
return json.loads(self._impl.get_metadata())
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the name of the collection.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
def save(self, doc: Any) -> None:
|
||||
"""
|
||||
Saves a document into the collection. This method is equivalent to
|
||||
insertOne() except that if client-assigned keys are used, and the
|
||||
document with the specified key already exists in the collection, it
|
||||
will be replaced with the input document.
|
||||
"""
|
||||
doc_impl = self._process_doc_arg(doc)
|
||||
self._impl.save(doc_impl, hint=None, return_doc=False)
|
||||
|
||||
def saveAndGet(self, doc: Any, hint: str = None) -> "SodaDocument":
|
||||
"""
|
||||
Saves a document into the collection. This method is equivalent to
|
||||
insertOneAndGet() except that if client-assigned keys are used, and the
|
||||
document with the specified key already exists in the collection, it
|
||||
will be replaced with the input document.
|
||||
|
||||
The hint parameter, if specified, supplies a hint to the database when
|
||||
processing the SODA operation. This is expected to be a string in the
|
||||
same format as SQL hints but without any comment characters, for
|
||||
example hint="MONITOR". While you could use this to pass any SQL hint,
|
||||
the hints MONITOR (turn on monitoring) and NO_MONITOR (turn off
|
||||
monitoring) are the most useful. Use of the hint parameter requires
|
||||
Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11).
|
||||
"""
|
||||
doc_impl = self._process_doc_arg(doc)
|
||||
if hint is not None and not isinstance(hint, str):
|
||||
raise TypeError("expecting a string")
|
||||
return_doc_impl = self._impl.save(doc_impl, hint, return_doc=True)
|
||||
return SodaDocument._from_impl(return_doc_impl)
|
||||
|
||||
def truncate(self) -> None:
|
||||
"""
|
||||
Removes all of the documents in the collection, similarly to what is
|
||||
done for rows in a table by the TRUNCATE TABLE statement.
|
||||
"""
|
||||
self._impl.truncate()
|
||||
|
||||
|
||||
class SodaDocument:
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
doc = cls.__new__(cls)
|
||||
doc._impl = impl
|
||||
return doc
|
||||
|
||||
@property
|
||||
def createdOn(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the creation time of the document in
|
||||
ISO 8601 format. Documents created by SodaDatabase.createDocument() or
|
||||
fetched from collections where this attribute is not stored will return
|
||||
None.
|
||||
"""
|
||||
return self._impl.get_created_on()
|
||||
|
||||
def getContent(self) -> Union[dict, list]:
|
||||
"""
|
||||
Returns the content of the document as a dictionary or list. This
|
||||
method assumes that the content is application/json and will raise an
|
||||
exception if this is not the case. If there is no content, however,
|
||||
None will be returned.
|
||||
"""
|
||||
return json.loads(self.getContentAsString())
|
||||
|
||||
def getContentAsBytes(self) -> bytes:
|
||||
"""
|
||||
Returns the content of the document as a bytes object. If there is no
|
||||
content, however, None will be returned.
|
||||
"""
|
||||
content_bytes, encoding = self._impl.get_content()
|
||||
return content_bytes
|
||||
|
||||
def getContentAsString(self) -> str:
|
||||
"""
|
||||
Returns the content of the document as a string. If the document
|
||||
encoding is not known, UTF-8 will be used. If there is no content,
|
||||
however, None will be returned.
|
||||
"""
|
||||
content_bytes, encoding = self._impl.get_content()
|
||||
return content_bytes.decode(encoding)
|
||||
|
||||
@property
|
||||
def key(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the unique key assigned to this
|
||||
document. Documents created by SodaDatabase.createDocument() may not
|
||||
have a value assigned to them and return None.
|
||||
"""
|
||||
return self._impl.get_key()
|
||||
|
||||
@property
|
||||
def lastModified(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the last modified time of the document
|
||||
in ISO 8601 format. Documents created by SodaDatabase.createDocument()
|
||||
or fetched from collections where this attribute is not stored will
|
||||
return None.
|
||||
"""
|
||||
return self._impl.get_last_modified()
|
||||
|
||||
@property
|
||||
def mediaType(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the media type assigned to the
|
||||
document. By convention this is expected to be a MIME type but no
|
||||
checks are performed on this value. If a value is not specified when
|
||||
calling SodaDatabase.createDocument() or the document is fetched from a
|
||||
collection where this component is not stored, the string
|
||||
“application/json” is returned.
|
||||
"""
|
||||
return self._impl.get_media_type()
|
||||
|
||||
@property
|
||||
def version(self) -> str:
|
||||
"""
|
||||
This read-only attribute returns the version assigned to this document.
|
||||
Documents created by SodaDatabase.createDocument() or fetched from
|
||||
collections where this attribute is not stored will return None.
|
||||
"""
|
||||
return self._impl.get_version()
|
||||
|
||||
|
||||
class SodaDocCursor:
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self._impl is None:
|
||||
errors._raise_err(errors.ERR_CURSOR_NOT_OPEN)
|
||||
doc_impl = self._impl.get_next_doc()
|
||||
if doc_impl is not None:
|
||||
return SodaDocument._from_impl(doc_impl)
|
||||
raise StopIteration
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
cursor = cls.__new__(cls)
|
||||
cursor._impl = impl
|
||||
return cursor
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
Close the cursor now, rather than whenever __del__ is called. The
|
||||
cursor will be unusable from this point forward; an Error exception
|
||||
will be raised if any operation is attempted with the cursor.
|
||||
"""
|
||||
if self._impl is None:
|
||||
errors._raise_err(errors.ERR_CURSOR_NOT_OPEN)
|
||||
self._impl.close()
|
||||
self._impl = None
|
||||
|
||||
|
||||
class SodaOperation:
|
||||
def __init__(self, collection: SodaCollection) -> None:
|
||||
self._collection = collection
|
||||
self._key = None
|
||||
self._keys = None
|
||||
self._version = None
|
||||
self._filter = None
|
||||
self._hint = None
|
||||
self._skip = None
|
||||
self._limit = None
|
||||
self._fetch_array_size = None
|
||||
self._lock = False
|
||||
|
||||
def count(self) -> int:
|
||||
"""
|
||||
Returns a count of the number of documents in the collection that match
|
||||
the criteria. If skip() or limit() were called on this object, an
|
||||
exception is raised.
|
||||
"""
|
||||
return self._collection._impl.get_count(self)
|
||||
|
||||
def fetchArraySize(self, value: int) -> "SodaOperation":
|
||||
"""
|
||||
This is a tuning method to specify the number of documents that are
|
||||
internally fetched in batches by calls to getCursor() and
|
||||
getDocuments(). It does not affect how many documents are returned to
|
||||
the application. A value of 0 will use the default value (100). This
|
||||
method is only available in Oracle Client 19.5 and higher.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, int) or value < 0:
|
||||
raise TypeError("expecting integer >= 0")
|
||||
if value == 0:
|
||||
self._fetch_array_size = None
|
||||
else:
|
||||
self._fetch_array_size = value
|
||||
return self
|
||||
|
||||
def filter(self, value: Union[dict, str]) -> "SodaOperation":
|
||||
"""
|
||||
Sets a filter specification for complex document queries and ordering
|
||||
of JSON documents. Filter specifications must be provided as a
|
||||
dictionary or JSON-encoded string and can include comparisons, regular
|
||||
expressions, logical and spatial operators, among others. See the
|
||||
overview of SODA filter specifications for more information.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if isinstance(value, dict):
|
||||
self._filter = json.dumps(value)
|
||||
elif isinstance(value, str):
|
||||
self._filter = value
|
||||
else:
|
||||
raise TypeError("expecting string or dictionary")
|
||||
return self
|
||||
|
||||
def getCursor(self) -> "SodaDocCursor":
|
||||
"""
|
||||
Returns a SodaDocCursor object that can be used to iterate over the
|
||||
documents that match the criteria.
|
||||
"""
|
||||
impl = self._collection._impl.get_cursor(self)
|
||||
return SodaDocCursor._from_impl(impl)
|
||||
|
||||
def getDocuments(self) -> list:
|
||||
"""
|
||||
Returns a list of SodaDocument objects that match the criteria.
|
||||
"""
|
||||
return [d for d in self.getCursor()]
|
||||
|
||||
def getOne(self) -> Union["SodaDocument", None]:
|
||||
"""
|
||||
Returns a single SodaDocument object that matches the criteria. Note
|
||||
that if multiple documents match the criteria only the first one is
|
||||
returned.
|
||||
"""
|
||||
doc_impl = self._collection._impl.get_one(self)
|
||||
if doc_impl is not None:
|
||||
return SodaDocument._from_impl(doc_impl)
|
||||
|
||||
def hint(self, value: str) -> "SodaOperation":
|
||||
"""
|
||||
Specifies a hint that will be provided to the SODA operation when it is
|
||||
performed. This is expected to be a string in the same format as SQL
|
||||
hints but without any comment characters. While you could use this to
|
||||
pass any SQL hint, the hints MONITOR (turn on monitoring) and
|
||||
NO_MONITOR (turn off monitoring) are the most useful. Use of this
|
||||
method requires Oracle Client 21.3 or higher (or Oracle Client 19 from
|
||||
19.11).
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, str):
|
||||
raise TypeError("expecting a string")
|
||||
self._hint = value
|
||||
return self
|
||||
|
||||
def lock(self) -> "SodaOperation":
|
||||
"""
|
||||
Specifies whether the documents fetched from the collection should be
|
||||
locked (equivalent to SQL "select for update"). Use of this method
|
||||
requires Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11).
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
self._lock = True
|
||||
return self
|
||||
|
||||
def key(self, value: str) -> "SodaOperation":
|
||||
"""
|
||||
Specifies that the document with the specified key should be returned.
|
||||
This causes any previous calls made to this method and keys() to be
|
||||
ignored.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, str):
|
||||
raise TypeError("expecting string")
|
||||
self._key = value
|
||||
self._keys = None
|
||||
return self
|
||||
|
||||
def keys(self, value: list) -> "SodaOperation":
|
||||
"""
|
||||
Specifies that documents that match the keys found in the supplied
|
||||
sequence should be returned. This causes any previous calls made to
|
||||
this method and key() to be ignored.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
value_as_list = list(value)
|
||||
for element in value_as_list:
|
||||
if not isinstance(element, str):
|
||||
raise TypeError("expecting sequence of strings")
|
||||
self._keys = value_as_list
|
||||
self._key = None
|
||||
return self
|
||||
|
||||
def limit(self, value: int) -> "SodaOperation":
|
||||
"""
|
||||
Specifies that only the specified number of documents should be
|
||||
returned. This method is only usable for read operations such as
|
||||
getCursor() and getDocuments(). For write operations, any value set
|
||||
using this method is ignored.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, int) or value <= 0:
|
||||
raise TypeError("expecting positive integer")
|
||||
self._limit = value
|
||||
return self
|
||||
|
||||
def remove(self) -> int:
|
||||
"""
|
||||
Removes all of the documents in the collection that match the criteria.
|
||||
The number of documents that have been removed is returned.
|
||||
"""
|
||||
return self._collection._impl.remove(self)
|
||||
|
||||
def replaceOne(self, doc: Any) -> bool:
|
||||
"""
|
||||
Replaces a single document in the collection with the specified
|
||||
document. The input document can be a dictionary or list or an existing
|
||||
SODA document object. A boolean indicating if a document was replaced
|
||||
or not is returned.
|
||||
|
||||
Currently the method key() must be called before this method can be
|
||||
called.
|
||||
"""
|
||||
doc_impl = self._collection._process_doc_arg(doc)
|
||||
return self._collection._impl.replace_one(
|
||||
self, doc_impl, return_doc=False
|
||||
)
|
||||
|
||||
def replaceOneAndGet(self, doc: Any) -> "SodaDocument":
|
||||
"""
|
||||
Similarly to replaceOne(), this method replaces a single document in
|
||||
the collection with the specified document. The only difference is that
|
||||
it returns a SodaDocument object. Note that for performance reasons the
|
||||
returned document does not contain the content.
|
||||
"""
|
||||
doc_impl = self._collection._process_doc_arg(doc)
|
||||
return_doc_impl = self._collection._impl.replace_one(
|
||||
self, doc_impl, return_doc=True
|
||||
)
|
||||
return SodaDocument._from_impl(return_doc_impl)
|
||||
|
||||
def skip(self, value: int) -> "SodaOperation":
|
||||
"""
|
||||
Specifies the number of documents that match the other criteria that
|
||||
will be skipped. This method is only usable for read operations such as
|
||||
getCursor() and getDocuments(). For write operations, any value set
|
||||
using this method is ignored.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, int) or value < 0:
|
||||
raise TypeError("expecting integer >= 0")
|
||||
self._skip = value
|
||||
return self
|
||||
|
||||
def version(self, value: str) -> "SodaOperation":
|
||||
"""
|
||||
Specifies that documents with the specified version should be returned.
|
||||
Typically this is used with key() to implement optimistic locking, so
|
||||
that the write operation called later does not affect a document that
|
||||
someone else has modified.
|
||||
|
||||
As a convenience, the SodaOperation object is returned so that further
|
||||
criteria can be specified by chaining methods together.
|
||||
"""
|
||||
if not isinstance(value, str):
|
||||
raise TypeError("expecting string")
|
||||
self._version = value
|
||||
return self
|
||||
@@ -0,0 +1,356 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# subscr.py
|
||||
#
|
||||
# Contains the Subscription class and Message classes used for managing
|
||||
# subscriptions to database events and the messages that are sent when those
|
||||
# events are detected.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Callable, Union, List
|
||||
from . import connection
|
||||
|
||||
|
||||
class Subscription:
|
||||
def __repr__(self):
|
||||
return f"<oracledb.Subscription on {self.connection!r}>"
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl):
|
||||
subscr = cls.__new__(cls)
|
||||
subscr._impl = impl
|
||||
return subscr
|
||||
|
||||
@property
|
||||
def callback(self) -> Callable:
|
||||
"""
|
||||
Returns the callback that was registered when the subscription was
|
||||
created.
|
||||
"""
|
||||
return self._impl.callback
|
||||
|
||||
@property
|
||||
def connection(self) -> "connection.Connection":
|
||||
"""
|
||||
Returns the connection that was used to register the subscription when
|
||||
it was created.
|
||||
"""
|
||||
return self._impl.connection
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
"""
|
||||
Returns the value of REGID found in the database view
|
||||
USER_CHANGE_NOTIFICATION_REGS or the value of REG_ID found in the
|
||||
database view USER_SUBSCR_REGISTRATIONS. For AQ subscriptions, this
|
||||
value is 0.
|
||||
"""
|
||||
return self._impl.id
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str:
|
||||
"""
|
||||
Returns the IP address used for callback notifications from the
|
||||
database server. If not set during construction, this value is None.
|
||||
"""
|
||||
return self._impl.ip_address
|
||||
|
||||
@property
|
||||
def ipAddress(self) -> str:
|
||||
"""
|
||||
Deprecated. Use property ip_address instead.
|
||||
"""
|
||||
return self.ip_address
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Returns the name used to register the subscription when it was created.
|
||||
"""
|
||||
return self._impl.name
|
||||
|
||||
@property
|
||||
def namespace(self) -> int:
|
||||
"""
|
||||
Returns the namespace used to register the subscription when it was
|
||||
created.
|
||||
"""
|
||||
return self._impl.namespace
|
||||
|
||||
@property
|
||||
def operations(self) -> int:
|
||||
"""
|
||||
Returns the operations that will send notifications for each table or
|
||||
query that is registered using this subscription.
|
||||
"""
|
||||
return self._impl.operations
|
||||
|
||||
@property
|
||||
def port(self) -> int:
|
||||
"""
|
||||
Returns the port used for callback notifications from the database
|
||||
server. If not set during construction, this value is zero.
|
||||
"""
|
||||
return self._impl.port
|
||||
|
||||
@property
|
||||
def protocol(self) -> int:
|
||||
"""
|
||||
Returns the protocol used to register the subscription when it was
|
||||
created.
|
||||
"""
|
||||
return self._impl.protocol
|
||||
|
||||
@property
|
||||
def qos(self) -> int:
|
||||
"""
|
||||
Returns the quality of service flags used to register the subscription
|
||||
when it was created.
|
||||
"""
|
||||
return self._impl.qos
|
||||
|
||||
def registerquery(
|
||||
self, statement: str, args: Union[list, dict] = None
|
||||
) -> int:
|
||||
"""
|
||||
Register the query for subsequent notification when tables referenced
|
||||
by the query are changed. This behaves similarly to cursor.execute()
|
||||
but only queries are permitted and the args parameter, if specified,
|
||||
must be a sequence or dictionary. If the qos parameter included the
|
||||
flag SUBSCR_QOS_QUERY when the subscription was created, then the ID
|
||||
for the registered query is returned; otherwise, None is returned.
|
||||
"""
|
||||
if args is not None and not isinstance(args, (list, dict)):
|
||||
raise TypeError("expecting args to be a dictionary or list")
|
||||
return self._impl.register_query(statement, args)
|
||||
|
||||
@property
|
||||
def timeout(self) -> int:
|
||||
"""
|
||||
Returns the timeout (in seconds) that was specified when the
|
||||
subscription was created. A value of 0 indicates that there is no
|
||||
timeout.
|
||||
"""
|
||||
return self._impl.timeout
|
||||
|
||||
|
||||
class Message:
|
||||
def __init__(self, subscription: Subscription) -> None:
|
||||
self._subscription = subscription
|
||||
self._consumer_name = None
|
||||
self._dbname = None
|
||||
self._queries = []
|
||||
self._queue_name = None
|
||||
self._registered = False
|
||||
self._tables = []
|
||||
self._txid = None
|
||||
self._type = 0
|
||||
self._msgid = None
|
||||
|
||||
@property
|
||||
def consumer_name(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the consumer which generated the notification. It
|
||||
will be populated if the subscription was created with the namespace
|
||||
SUBSCR_NAMESPACE_AQ and the queue is a multiple consumer queue.
|
||||
"""
|
||||
return self._consumer_name
|
||||
|
||||
@property
|
||||
def consumerName(self) -> Union[str, None]:
|
||||
"""
|
||||
Deprecated. Use property consumer_name instead.
|
||||
"""
|
||||
return self.consumer_name
|
||||
|
||||
@property
|
||||
def dbname(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the database that generated the notification.
|
||||
"""
|
||||
return self._dbname
|
||||
|
||||
@property
|
||||
def msgid(self) -> Union[bytes, None]:
|
||||
"""
|
||||
Returns the message id of the AQ message that generated the
|
||||
notification.
|
||||
"""
|
||||
return self._msgid
|
||||
|
||||
@property
|
||||
def queries(self) -> List["MessageQuery"]:
|
||||
"""
|
||||
Returns a list of message query objects that give information about
|
||||
query result sets changed for this notification. This attribute will be
|
||||
an empty list if the qos parameter did not include the flag
|
||||
SUBSCR_QOS_QUERY when the subscription was created.
|
||||
"""
|
||||
return self._queries
|
||||
|
||||
@property
|
||||
def queue_name(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the queue which generated the notification. It will
|
||||
only be populated if the subscription was created with the namespace
|
||||
SUBSCR_NAMESPACE_AQ.
|
||||
"""
|
||||
return self._queue_name
|
||||
|
||||
@property
|
||||
def queueName(self) -> Union[str, None]:
|
||||
"""
|
||||
Deprecated. Use property queue_name instead.
|
||||
"""
|
||||
return self.queue_name
|
||||
|
||||
@property
|
||||
def registered(self) -> bool:
|
||||
"""
|
||||
Returns whether the subscription which generated this notification is
|
||||
still registered with the database. The subscription is automatically
|
||||
deregistered with the database when the subscription timeout value is
|
||||
reached or when the first notification is sent (when the quality of
|
||||
service flag SUBSCR_QOS_DEREG_NFY is used).
|
||||
"""
|
||||
return self._registered
|
||||
|
||||
@property
|
||||
def subscription(self) -> Subscription:
|
||||
"""
|
||||
Returns the subscription object for which this notification was
|
||||
generated.
|
||||
"""
|
||||
return self._subscription
|
||||
|
||||
@property
|
||||
def tables(self) -> List["MessageTable"]:
|
||||
"""
|
||||
Returns a list of message table objects that give information about the
|
||||
tables changed for this notification. This attribute will be an empty
|
||||
list if the qos parameter included the flag SUBSCR_QOS_QUERY when the
|
||||
subscription was created.
|
||||
"""
|
||||
return self._tables
|
||||
|
||||
@property
|
||||
def txid(self) -> Union[bytes, None]:
|
||||
"""
|
||||
Returns the id of the transaction that generated the notification.
|
||||
"""
|
||||
return self._txid
|
||||
|
||||
@property
|
||||
def type(self) -> int:
|
||||
"""
|
||||
Returns the type of message that has been sent.
|
||||
"""
|
||||
return self._type
|
||||
|
||||
|
||||
class MessageQuery:
|
||||
def __init__(self) -> None:
|
||||
self._id = 0
|
||||
self._operation = 0
|
||||
self._tables = []
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
"""
|
||||
Returns the query id of the query for which the result set changed. The
|
||||
value will match the value returned by Subscription.registerquery()
|
||||
when the related query was registered.
|
||||
"""
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def operation(self) -> int:
|
||||
"""
|
||||
Returns the operation that took place on the query result set that was
|
||||
changed. Valid values for this attribute are EVENT_DEREG and
|
||||
EVENT_QUERYCHANGE.
|
||||
"""
|
||||
return self._operation
|
||||
|
||||
@property
|
||||
def tables(self) -> List["MessageTable"]:
|
||||
"""
|
||||
Returns a list of message table objects that give information about the
|
||||
table changes that caused the query result set to change for this
|
||||
notification.
|
||||
"""
|
||||
return self._tables
|
||||
|
||||
|
||||
class MessageRow:
|
||||
def __init__(self) -> None:
|
||||
self._operation = 0
|
||||
self._rowid = None
|
||||
|
||||
@property
|
||||
def operation(self) -> int:
|
||||
"""
|
||||
Returns the operation that took place on the row that was changed.
|
||||
"""
|
||||
return self._operation
|
||||
|
||||
@property
|
||||
def rowid(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the rowid of the row that was changed.
|
||||
"""
|
||||
return self._rowid
|
||||
|
||||
|
||||
class MessageTable:
|
||||
def __init__(self) -> None:
|
||||
self._name = None
|
||||
self._operation = 0
|
||||
self._rows = []
|
||||
|
||||
@property
|
||||
def name(self) -> Union[str, None]:
|
||||
"""
|
||||
Returns the name of the table that was changed.
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def operation(self) -> int:
|
||||
"""
|
||||
Returns the operation that took place on the table that was changed.
|
||||
"""
|
||||
return self._operation
|
||||
|
||||
@property
|
||||
def rows(self) -> List["MessageRow"]:
|
||||
"""
|
||||
Returns a list of message row objects that give information about the
|
||||
rows changed on the table. This value is only filled in if the qos
|
||||
parameter to the Connection.subscribe() method included the flag
|
||||
SUBSCR_QOS_ROWIDS.
|
||||
"""
|
||||
return self._rows
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# utils.py
|
||||
#
|
||||
# Contains utility classes and methods.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from . import errors
|
||||
|
||||
|
||||
class CheckImpls:
|
||||
"""
|
||||
Decorator class which is used on the base implementation method and checks
|
||||
to see which implementation is currently being used (and therefore has no
|
||||
support for the method). An exception is raised letting the user know which
|
||||
implementation does support the method. Currently there are only two
|
||||
implementations (thick and thin) so the assumption is made that the
|
||||
implementation not currently running does support the method.
|
||||
"""
|
||||
|
||||
def __init__(self, feature):
|
||||
self.feature = feature
|
||||
|
||||
def __call__(self, f):
|
||||
feature = self.feature
|
||||
|
||||
def wrapped_f(self, *args, **kwargs):
|
||||
class_name = type(self).__name__
|
||||
driver_type = "thin" if class_name.startswith("Thick") else "thick"
|
||||
errors._raise_err(
|
||||
errors.ERR_FEATURE_NOT_SUPPORTED,
|
||||
feature=feature,
|
||||
driver_type=driver_type,
|
||||
)
|
||||
|
||||
return wrapped_f
|
||||
|
||||
|
||||
def params_initer(f):
|
||||
"""
|
||||
Decorator function which is used on the ConnectParams and PoolParams
|
||||
classes. It creates the implementation object using the implementation
|
||||
class stored on the parameter class. It first, however, calls the original
|
||||
method to ensure that the keyword parameters supplied are valid (the
|
||||
original method itself does nothing).
|
||||
"""
|
||||
|
||||
def wrapped_f(self, *args, **kwargs):
|
||||
f(self, *args, **kwargs)
|
||||
self._impl = self._impl_class()
|
||||
if kwargs:
|
||||
self._impl.set(kwargs)
|
||||
|
||||
return wrapped_f
|
||||
|
||||
|
||||
def params_setter(f):
|
||||
"""
|
||||
Decorator function which is used on the ConnectParams and PoolParams
|
||||
classes. It calls the set() method on the parameter implementation object
|
||||
with the supplied keyword arguments. It first, however, calls the original
|
||||
method to ensure that the keyword parameters supplied are valid (the
|
||||
original method itself does nothing).
|
||||
"""
|
||||
|
||||
def wrapped_f(self, *args, **kwargs):
|
||||
f(self, *args, **kwargs)
|
||||
self._impl.set(kwargs)
|
||||
|
||||
return wrapped_f
|
||||
@@ -0,0 +1,181 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# var.py
|
||||
#
|
||||
# Contains the Var class used for managing variables used during bind and
|
||||
# fetch. These hold the metadata as well as any necessary buffers.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
from typing import Any, Callable, Union
|
||||
from .dbobject import DbObjectType
|
||||
from .base_impl import DbType
|
||||
|
||||
|
||||
class Var:
|
||||
def __repr__(self):
|
||||
value = self._impl.get_all_values()
|
||||
if not self._impl.is_array and len(value) == 1:
|
||||
value = value[0]
|
||||
typ = self._type
|
||||
return f"<oracledb.Var of type {typ.name} with value {repr(value)}>"
|
||||
|
||||
@classmethod
|
||||
def _from_impl(cls, impl, typ=None):
|
||||
var = cls.__new__(cls)
|
||||
var._impl = impl
|
||||
if typ is not None:
|
||||
var._type = typ
|
||||
elif impl.objtype is not None:
|
||||
var._type = DbObjectType._from_impl(impl.objtype)
|
||||
else:
|
||||
var._type = impl.dbtype
|
||||
return var
|
||||
|
||||
@property
|
||||
def actual_elements(self) -> int:
|
||||
"""
|
||||
This read-only attribute returns the actual number of elements in the
|
||||
variable. This corresponds to the number of elements in a PL/SQL
|
||||
index-by table for variables that are created using the method
|
||||
Cursor.arrayvar(). For all other variables this value will be identical
|
||||
to the attribute num_elements.
|
||||
"""
|
||||
if self._impl.is_array:
|
||||
return self._impl.num_elements_in_array
|
||||
return self._impl.num_elements
|
||||
|
||||
@property
|
||||
def actualElements(self) -> int:
|
||||
"""
|
||||
Deprecated. Use property actual_elements instead.
|
||||
"""
|
||||
return self.actual_elements
|
||||
|
||||
@property
|
||||
def buffer_size(self) -> int:
|
||||
"""
|
||||
This read-only attribute returns the size of the buffer allocated for
|
||||
each element in bytes.
|
||||
"""
|
||||
return self._impl.buffer_size
|
||||
|
||||
@property
|
||||
def bufferSize(self) -> int:
|
||||
"""
|
||||
Deprecated. Use property buffer_size intead().
|
||||
"""
|
||||
return self.buffer_size
|
||||
|
||||
@property
|
||||
def convert_nulls(self) -> bool:
|
||||
"""
|
||||
This read-only attribute returns whether null values are converted
|
||||
using the supplied ``outconverter``.
|
||||
"""
|
||||
return self._impl.convert_nulls
|
||||
|
||||
def getvalue(self, pos: int = 0) -> Any:
|
||||
"""
|
||||
Return the value at the given position in the variable. For variables
|
||||
created using the method Cursor.arrayvar() the value returned will be a
|
||||
list of each of the values in the PL/SQL index-by table. For variables
|
||||
bound to DML returning statements, the value returned will also be a
|
||||
list corresponding to the returned data for the given execution of the
|
||||
statement (as identified by the pos parameter).
|
||||
"""
|
||||
return self._impl.get_value(pos)
|
||||
|
||||
@property
|
||||
def inconverter(self) -> Callable:
|
||||
"""
|
||||
This read-only attribute specifies the method used to convert data from
|
||||
Python to the Oracle database. The method signature is converter(value)
|
||||
and the expected return value is the value to bind to the database. If
|
||||
this attribute is None, the value is bound directly without any
|
||||
conversion.
|
||||
"""
|
||||
return self._impl.inconverter
|
||||
|
||||
@property
|
||||
def num_elements(self) -> int:
|
||||
"""
|
||||
This read-only attribute returns the number of elements allocated in an
|
||||
array, or the number of scalar items that can be fetched into the
|
||||
variable or bound to the variable.
|
||||
"""
|
||||
return self._impl.num_elements
|
||||
|
||||
@property
|
||||
def numElements(self) -> int:
|
||||
"""
|
||||
Deprecated. Use property num_elements instead.
|
||||
"""
|
||||
return self.num_elements
|
||||
|
||||
@property
|
||||
def outconverter(self) -> Callable:
|
||||
"""
|
||||
This read-only attribute specifies the method used to convert data from
|
||||
the Oracle database to Python. The method signature is converter(value)
|
||||
and the expected return value is the value to return to Python. If this
|
||||
attribute is None, the value is returned directly without any
|
||||
conversion.
|
||||
"""
|
||||
return self._impl.outconverter
|
||||
|
||||
def setvalue(self, pos: int, value: Any) -> None:
|
||||
"""
|
||||
Set the value at the given position in the variable.
|
||||
"""
|
||||
self._impl.set_value(pos, value)
|
||||
|
||||
@property
|
||||
def size(self) -> int:
|
||||
"""
|
||||
This read-only attribute returns the size of the variable. For strings
|
||||
this value is the size in characters. For all others, this is same
|
||||
value as the attribute buffer_size.
|
||||
"""
|
||||
return self._impl.size
|
||||
|
||||
@property
|
||||
def type(self) -> Union[DbType, DbObjectType]:
|
||||
"""
|
||||
This read-only attribute returns the type of the variable. This will be
|
||||
an Oracle Object Type if the variable binds Oracle objects; otherwise,
|
||||
it will be one of the database type constants.
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def values(self) -> list:
|
||||
"""
|
||||
This read-only attribute returns a copy of the value of all actual
|
||||
positions in the variable as a list. This is the equivalent of calling
|
||||
getvalue() for each valid position and the length will correspond to
|
||||
the value of the actual_elements attribute.
|
||||
"""
|
||||
return self._impl.get_all_values()
|
||||
@@ -0,0 +1,33 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates.
|
||||
#
|
||||
# This software is dual-licensed to you under the Universal Permissive License
|
||||
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
||||
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
||||
# either license.
|
||||
#
|
||||
# If you elect to accept the software under the Apache License, Version 2.0,
|
||||
# the following applies:
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# version.py
|
||||
#
|
||||
# Defines the version of the package. This is the only place where this is
|
||||
# found. The setup.cfg configuration file and the documentation configuration
|
||||
# file doc/src/conf.py both reference this file directly.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
__version__ = "2.0.0"
|
||||
Reference in New Issue
Block a user