| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- # Licensed to the Apache Software Foundation (ASF) under one or more
- # contributor license agreements. See the NOTICE file distributed with
- # this work for additional information regarding copyright ownership.
- # The ASF licenses this file to You 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
- #
- # http://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.
- import logging
- import uuid
- import weakref
- from phoenixdb import errors
- from phoenixdb.avatica.client import OPEN_CONNECTION_PROPERTIES
- from phoenixdb.cursor import Cursor
- from phoenixdb.errors import ProgrammingError
- __all__ = ['Connection']
- logger = logging.getLogger(__name__)
- class Connection(object):
- """Database connection.
- You should not construct this object manually, use :func:`~phoenixdb.connect` instead.
- """
- cursor_factory = None
- """
- The default cursor factory used by :meth:`cursor` if the parameter is not specified.
- """
- def __init__(self, client, cursor_factory=None, **kwargs):
- self._client = client
- self._closed = False
- if cursor_factory is not None:
- self.cursor_factory = cursor_factory
- else:
- self.cursor_factory = Cursor
- self._cursors = []
- # Extract properties to pass to OpenConnectionRequest
- self._connection_args = {}
- # The rest of the kwargs
- self._filtered_args = {}
- for k in kwargs:
- if k in OPEN_CONNECTION_PROPERTIES:
- self._connection_args[k] = kwargs[k]
- else:
- self._filtered_args[k] = kwargs[k]
- self.open()
- self.set_session(**self._filtered_args)
- def __del__(self):
- if not self._closed:
- self.close()
- def __enter__(self):
- return self
- def __exit__(self, exc_type, exc_value, traceback):
- if not self._closed:
- self.close()
- def open(self):
- """Opens the connection."""
- self._id = str(uuid.uuid4())
- self._client.open_connection(self._id, info=self._connection_args)
- def close(self):
- """Closes the connection.
- No further operations are allowed, either on the connection or any
- of its cursors, once the connection is closed.
- If the connection is used in a ``with`` statement, this method will
- be automatically called at the end of the ``with`` block.
- """
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- for cursor_ref in self._cursors:
- cursor = cursor_ref()
- if cursor is not None and not cursor._closed:
- cursor.close()
- self._client.close_connection(self._id)
- self._client.close()
- self._closed = True
- @property
- def closed(self):
- """Read-only attribute specifying if the connection is closed or not."""
- return self._closed
- def commit(self):
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- self._client.commit(self._id)
- def rollback(self):
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- self._client.rollback(self._id)
- def cursor(self, cursor_factory=None):
- """Creates a new cursor.
- :param cursor_factory:
- This argument can be used to create non-standard cursors.
- The class returned must be a subclass of
- :class:`~phoenixdb.cursor.Cursor` (for example :class:`~phoenixdb.cursor.DictCursor`).
- A default factory for the connection can also be specified using the
- :attr:`cursor_factory` attribute.
- :returns:
- A :class:`~phoenixdb.cursor.Cursor` object.
- """
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- cursor = (cursor_factory or self.cursor_factory)(self)
- self._cursors.append(weakref.ref(cursor, self._cursors.remove))
- return cursor
- def set_session(self, autocommit=None, readonly=None):
- """Sets one or more parameters in the current connection.
- :param autocommit:
- Switch the connection to autocommit mode.
- :param readonly:
- Switch the connection to read-only mode.
- """
- props = {}
- if autocommit is not None:
- props['autoCommit'] = bool(autocommit)
- if readonly is not None:
- props['readOnly'] = bool(readonly)
- props = self._client.connection_sync(self._id, props)
- self._autocommit = props.auto_commit
- self._readonly = props.read_only
- self._transactionisolation = props.transaction_isolation
- @property
- def autocommit(self):
- """Read/write attribute for switching the connection's autocommit mode."""
- return self._autocommit
- @autocommit.setter
- def autocommit(self, value):
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- props = self._client.connection_sync(self._id, {'autoCommit': bool(value)})
- self._autocommit = props.auto_commit
- @property
- def readonly(self):
- """Read/write attribute for switching the connection's readonly mode."""
- return self._readonly
- @readonly.setter
- def readonly(self, value):
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- props = self._client.connection_sync(self._id, {'readOnly': bool(value)})
- self._readonly = props.read_only
- @property
- def transactionisolation(self):
- return self._transactionisolation
- @transactionisolation.setter
- def transactionisolation(self, value):
- if self._closed:
- raise ProgrammingError('the connection is already closed')
- props = self._client.connection_sync(self._id, {'transactionIsolation': bool(value)})
- self._transactionisolation = props.transaction_isolation
- for name in errors.__all__:
- setattr(Connection, name, getattr(errors, name))
|