mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-24 14:35:45 +00:00
Changes in Connection singleton - to use only Connection()
This commit is contained in:
parent
5f141abaf5
commit
d4facb65c4
@ -20,75 +20,36 @@ BACKENDS = {
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class DBSingleton(type):
|
|
||||||
_instances = {}
|
|
||||||
|
|
||||||
def __call__(cls, *args, **kwargs):
|
|
||||||
if cls not in cls._instances:
|
|
||||||
cls._instances[cls] = super(DBSingleton, cls).__call__(*args, **kwargs)
|
|
||||||
return cls._instances[cls]
|
|
||||||
|
|
||||||
def connect(host: str = None, port: int = None, login: str = None, password: str = None, backend: str = None,
|
|
||||||
**kwargs):
|
|
||||||
try:
|
|
||||||
backend = backend
|
|
||||||
if not backend and kwargs and kwargs.get("backend"):
|
|
||||||
backend = kwargs["backend"]
|
|
||||||
|
|
||||||
if backend and backend != Config().get()["database"]["backend"]:
|
|
||||||
Config().init_config(backend)
|
|
||||||
else:
|
|
||||||
backend = Config().get()["database"]["backend"]
|
|
||||||
except KeyError:
|
|
||||||
logger.info("Backend {} not supported".format(backend))
|
|
||||||
raise ConfigurationError
|
|
||||||
|
|
||||||
host = host or Config().get()["database"]["host"] if not kwargs.get("host") else kwargs["host"]
|
|
||||||
port = port or Config().get()['database']['port'] if not kwargs.get("port") else kwargs["port"]
|
|
||||||
login = login or Config().get()["database"]["login"] if not kwargs.get("login") else kwargs["login"]
|
|
||||||
password = password or Config().get()["database"]["password"]
|
|
||||||
try:
|
|
||||||
if backend == "tarantool_db":
|
|
||||||
modulepath, _, class_name = BACKENDS[backend].rpartition('.')
|
|
||||||
Class = getattr(import_module(modulepath), class_name)
|
|
||||||
return Class(host=host, port=port, user=login, password=password, kwargs=kwargs)
|
|
||||||
elif backend == "localmongodb":
|
|
||||||
modulepath, _, class_name = BACKENDS[backend].rpartition('.')
|
|
||||||
Class = getattr(import_module(modulepath), class_name)
|
|
||||||
dbname = _kwargs_parser(key="name", kwargs=kwargs) or Config().get()['database']['name']
|
|
||||||
replicaset = _kwargs_parser(key="replicaset", kwargs=kwargs) or Config().get()['database']['replicaset']
|
|
||||||
ssl = _kwargs_parser(key="ssl", kwargs=kwargs) or Config().get()['database']['ssl']
|
|
||||||
login = login or Config().get()['database']['login'] if _kwargs_parser(key="login",
|
|
||||||
kwargs=kwargs) is None else _kwargs_parser( # noqa: E501
|
|
||||||
key="login", kwargs=kwargs)
|
|
||||||
password = password or Config().get()['database']['password'] if _kwargs_parser(key="password",
|
|
||||||
kwargs=kwargs) is None else _kwargs_parser( # noqa: E501
|
|
||||||
key="password", kwargs=kwargs)
|
|
||||||
ca_cert = _kwargs_parser(key="ca_cert", kwargs=kwargs) or Config().get()['database']['ca_cert']
|
|
||||||
certfile = _kwargs_parser(key="certfile", kwargs=kwargs) or Config().get()['database']['certfile']
|
|
||||||
keyfile = _kwargs_parser(key="keyfile", kwargs=kwargs) or Config().get()['database']['keyfile']
|
|
||||||
keyfile_passphrase = _kwargs_parser(key="keyfile_passphrase", kwargs=kwargs) or Config().get()['database'][
|
|
||||||
'keyfile_passphrase']
|
|
||||||
crlfile = _kwargs_parser(key="crlfile", kwargs=kwargs) or Config().get()['database']['crlfile']
|
|
||||||
max_tries = _kwargs_parser(key="max_tries", kwargs=kwargs)
|
|
||||||
connection_timeout = _kwargs_parser(key="connection_timeout", kwargs=kwargs)
|
|
||||||
|
|
||||||
return Class(host=host, port=port, dbname=dbname,
|
|
||||||
max_tries=max_tries, connection_timeout=connection_timeout,
|
|
||||||
replicaset=replicaset, ssl=ssl, login=login, password=password,
|
|
||||||
ca_cert=ca_cert, certfile=certfile, keyfile=keyfile,
|
|
||||||
keyfile_passphrase=keyfile_passphrase, crlfile=crlfile)
|
|
||||||
except tarantool.error.NetworkError as network_err:
|
|
||||||
print(f"Host {host}:{port} can't be reached.\n{network_err}")
|
|
||||||
raise network_err
|
|
||||||
|
|
||||||
|
|
||||||
def _kwargs_parser(key, kwargs):
|
def _kwargs_parser(key, kwargs):
|
||||||
if kwargs.get(key):
|
if kwargs.get(key):
|
||||||
return kwargs[key]
|
return kwargs[key]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
class DBSingleton(type):
|
||||||
|
_instances = {}
|
||||||
|
|
||||||
|
def __call__(cls, *args, **kwargs):
|
||||||
|
if cls not in cls._instances:
|
||||||
|
try:
|
||||||
|
backend = _kwargs_parser(key="backend", kwargs=kwargs)
|
||||||
|
if backend and backend != Config().get()["database"]["backend"]:
|
||||||
|
Config().init_config(backend)
|
||||||
|
else:
|
||||||
|
backend = Config().get()["database"]["backend"]
|
||||||
|
except KeyError:
|
||||||
|
logger.info("Backend {} not supported".format(backend))
|
||||||
|
raise ConfigurationError
|
||||||
|
modulepath, _, class_name = BACKENDS[backend].rpartition('.')
|
||||||
|
Class = getattr(import_module(modulepath), class_name)
|
||||||
|
cls._instances[cls] = super(DBSingleton, Class).__call__(*args, **kwargs)
|
||||||
|
return cls._instances[cls]
|
||||||
|
|
||||||
class Connection(metaclass=DBSingleton):
|
class Connection(metaclass=DBSingleton):
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DBConnection(metaclass=DBSingleton):
|
||||||
"""Connection class interface.
|
"""Connection class interface.
|
||||||
All backend implementations should provide a connection class that inherits
|
All backend implementations should provide a connection class that inherits
|
||||||
from and implements this class.
|
from and implements this class.
|
||||||
@ -111,114 +72,15 @@ class Connection(metaclass=DBSingleton):
|
|||||||
"""
|
"""
|
||||||
dbconf = Config().get()['database']
|
dbconf = Config().get()['database']
|
||||||
|
|
||||||
self.connection_timeout = connection_timeout if connection_timeout is not None else Config().get()["database"]
|
|
||||||
self.max_tries = max_tries if max_tries is not None else dbconf['max_tries']
|
|
||||||
self.max_tries_counter = range(self.max_tries) if self.max_tries != 0 else repeat(0)
|
|
||||||
self.conn = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
backend = backend
|
|
||||||
if not backend and kwargs and kwargs.get("backend"):
|
|
||||||
backend = kwargs["backend"]
|
|
||||||
|
|
||||||
if backend and backend != Config().get()["database"]["backend"]:
|
|
||||||
Config().init_config(backend)
|
|
||||||
else:
|
|
||||||
backend = Config().get()["database"]["backend"]
|
|
||||||
except KeyError:
|
|
||||||
logger.info("Backend {} not supported".format(backend))
|
|
||||||
raise ConfigurationError
|
|
||||||
|
|
||||||
if(self.conn is None):
|
|
||||||
try:
|
|
||||||
self.connect(host=host, port=port, login=login, password=password, backend=backend, kwargs=kwargs)
|
|
||||||
except tarantool.error.NetworkError as network_err:
|
|
||||||
print(f"Host {host}:{port} can't be reached.\n{network_err}")
|
|
||||||
raise network_err
|
|
||||||
|
|
||||||
def connect(self, host: str = None, port: int = None, login: str = None, password: str = None, backend: str = None, **kwargs):
|
|
||||||
"""Try to connect to the database.
|
|
||||||
Raises:
|
|
||||||
:exc:`~ConnectionError`: If the connection to the database
|
|
||||||
fails.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
backend = backend
|
|
||||||
if not backend and kwargs and kwargs.get("backend"):
|
|
||||||
backend = kwargs["backend"]
|
|
||||||
|
|
||||||
if backend and backend != Config().get()["database"]["backend"]:
|
|
||||||
Config().init_config(backend)
|
|
||||||
else:
|
|
||||||
backend = Config().get()["database"]["backend"]
|
|
||||||
except KeyError:
|
|
||||||
logger.info("Backend {} not supported".format(backend))
|
|
||||||
raise ConfigurationError
|
|
||||||
|
|
||||||
for attempt in self.max_tries_counter:
|
|
||||||
if (self.conn is None):
|
|
||||||
try:
|
|
||||||
modulepath, _, class_name = BACKENDS[backend].rpartition('.')
|
|
||||||
Class = getattr(import_module(modulepath), class_name)
|
|
||||||
self.conn = Class(host=host, port=port, login=login, password=password, kwargs=kwargs)
|
|
||||||
break
|
|
||||||
except ConnectionError as exc:
|
|
||||||
logger.warning('Attempt %s/%s. Connection to %s:%s failed after %sms.',
|
|
||||||
attempt, self.max_tries if self.max_tries != 0 else '∞',
|
|
||||||
host, port, self.connection_timeout)
|
|
||||||
if attempt == self.max_tries:
|
|
||||||
logger.critical('Cannot connect to the Database. Giving up.')
|
|
||||||
raise ConnectionError() from exc
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
return self.conn
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
"""Try to close connection to database.
|
|
||||||
Raises:
|
|
||||||
:exc:`~ConnectionError`: If the closing connection to the database
|
|
||||||
fails.
|
|
||||||
"""
|
|
||||||
for attempt in self.max_tries_counter:
|
|
||||||
if (self.conn is not None):
|
|
||||||
try:
|
|
||||||
self.conn.close()
|
|
||||||
self.conn = None
|
|
||||||
break
|
|
||||||
except ConnectionError as exc:
|
|
||||||
logger.warning('Attempt %s/%s. Close Connection to %s:%s failed after %sms.',
|
|
||||||
attempt, self.max_tries if self.max_tries != 0 else '∞',
|
|
||||||
self.conn.host, self.conn.port, self.connection_timeout)
|
|
||||||
if attempt == self.max_tries:
|
|
||||||
logger.critical('Cannot close connection to the Database. Giving up.')
|
|
||||||
raise ConnectionError() from exc
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
class DBConnection():
|
|
||||||
|
|
||||||
def __init__(self, host: str = None, port: int = None, login: str = None, password: str = None, **kwargs):
|
|
||||||
"""Create a new :class:`~.DBConnection` instance.
|
|
||||||
Args:
|
|
||||||
host (str): the host to connect to.
|
|
||||||
port (int): the port to connect to.
|
|
||||||
dbname (str): the name of the database to use.
|
|
||||||
connection_timeout (int, optional): the milliseconds to wait
|
|
||||||
until timing out the database connection attempt.
|
|
||||||
Defaults to 5000ms.
|
|
||||||
max_tries (int, optional): how many tries before giving up,
|
|
||||||
if 0 then try forever. Defaults to 3.
|
|
||||||
**kwargs: arbitrary keyword arguments provided by the
|
|
||||||
configuration's ``database`` settings
|
|
||||||
"""
|
|
||||||
dbconf = Config().get()['database']
|
|
||||||
|
|
||||||
self.host = host or dbconf["host"] if not kwargs.get("host") else kwargs["host"]
|
self.host = host or dbconf["host"] if not kwargs.get("host") else kwargs["host"]
|
||||||
self.port = port or dbconf['port'] if not kwargs.get("port") else kwargs["port"]
|
self.port = port or dbconf['port'] if not kwargs.get("port") else kwargs["port"]
|
||||||
self.login = login or dbconf['login'] if not kwargs.get("login") else kwargs["login"]
|
self.login = login or dbconf['login'] if not kwargs.get("login") else kwargs["login"]
|
||||||
self.password = password or dbconf['password'] if not kwargs.get("password") else kwargs["password"]
|
self.password = password or dbconf['password'] if not kwargs.get("password") else kwargs["password"]
|
||||||
|
|
||||||
|
self.connection_timeout = connection_timeout if connection_timeout is not None else Config().get()["database"]
|
||||||
|
self.max_tries = max_tries if max_tries is not None else dbconf['max_tries']
|
||||||
|
self.max_tries_counter = range(self.max_tries) if self.max_tries != 0 else repeat(0)
|
||||||
|
|
||||||
def run(self, query):
|
def run(self, query):
|
||||||
"""Run a query.
|
"""Run a query.
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@ -83,7 +83,7 @@ def init_database(connection=None, dbname=None):
|
|||||||
configuration.
|
configuration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
connection = connection or Connection().conn
|
connection = connection or Connection()
|
||||||
print("=========================================", connection.__class__, "=========================================================")
|
print("=========================================", connection.__class__, "=========================================================")
|
||||||
dbname = dbname or Config().get()['database']['name']
|
dbname = dbname or Config().get()['database']['name']
|
||||||
|
|
||||||
|
|||||||
@ -265,7 +265,7 @@ def run_drop(args):
|
|||||||
return
|
return
|
||||||
|
|
||||||
from planetmint.backend.connection import Connection
|
from planetmint.backend.connection import Connection
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
try:
|
try:
|
||||||
schema.drop_database(conn)
|
schema.drop_database(conn)
|
||||||
except DatabaseDoesNotExist:
|
except DatabaseDoesNotExist:
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class Planetmint(object):
|
|||||||
self.validation = config_utils.load_validation_plugin(validationPlugin)
|
self.validation = config_utils.load_validation_plugin(validationPlugin)
|
||||||
else:
|
else:
|
||||||
self.validation = BaseValidationRules
|
self.validation = BaseValidationRules
|
||||||
self.connection = connection if connection is not None else Connection().conn
|
self.connection = connection if connection is not None else Connection()
|
||||||
|
|
||||||
def post_transaction(self, transaction, mode):
|
def post_transaction(self, transaction, mode):
|
||||||
"""Submit a valid transaction to the mempool."""
|
"""Submit a valid transaction to the mempool."""
|
||||||
|
|||||||
@ -27,5 +27,5 @@ from planetmint.backend.connection import Connection
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def db_conn():
|
def db_conn():
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
return conn
|
return conn
|
||||||
|
|||||||
@ -10,7 +10,7 @@ def test_get_connection_raises_a_configuration_error(monkeypatch):
|
|||||||
from planetmint.transactions.common.exceptions import ConfigurationError
|
from planetmint.transactions.common.exceptions import ConfigurationError
|
||||||
from planetmint.backend.connection import Connection
|
from planetmint.backend.connection import Connection
|
||||||
with pytest.raises(ConfigurationError):
|
with pytest.raises(ConfigurationError):
|
||||||
Connection().connect('localhost', '1337', 'mydb', 'password', 'msaccess')
|
Connection('localhost', '1337', 'mydb', 'password', 'msaccess')
|
||||||
|
|
||||||
with pytest.raises(ConfigurationError):
|
with pytest.raises(ConfigurationError):
|
||||||
# We need to force a misconfiguration here
|
# We need to force a misconfiguration here
|
||||||
@ -18,4 +18,4 @@ def test_get_connection_raises_a_configuration_error(monkeypatch):
|
|||||||
{'catsandra':
|
{'catsandra':
|
||||||
'planetmint.backend.meowmeow.Catsandra'})
|
'planetmint.backend.meowmeow.Catsandra'})
|
||||||
|
|
||||||
Connection().connect('localhost', '1337', 'mydb', 'password', 'catsandra')
|
Connection('localhost', '1337', 'mydb', 'password', 'catsandra')
|
||||||
|
|||||||
@ -94,7 +94,7 @@ def test__run_init(mocker):
|
|||||||
init_db_mock = mocker.patch(
|
init_db_mock = mocker.patch(
|
||||||
'planetmint.backend.tarantool.connection.TarantoolDBConnection.init_database')
|
'planetmint.backend.tarantool.connection.TarantoolDBConnection.init_database')
|
||||||
|
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
conn.init_database()
|
conn.init_database()
|
||||||
|
|
||||||
init_db_mock.assert_called_once_with()
|
init_db_mock.assert_called_once_with()
|
||||||
|
|||||||
@ -127,7 +127,7 @@ def _setup_database(_configure_planetmint): # TODO Here is located setup databa
|
|||||||
|
|
||||||
print('Initializing test db')
|
print('Initializing test db')
|
||||||
dbname = Config().get()['database']['name']
|
dbname = Config().get()['database']['name']
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
|
|
||||||
_drop_db(conn, dbname)
|
_drop_db(conn, dbname)
|
||||||
schema.init_database(conn, dbname)
|
schema.init_database(conn, dbname)
|
||||||
@ -136,7 +136,7 @@ def _setup_database(_configure_planetmint): # TODO Here is located setup databa
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
print('Deleting `{}` database'.format(dbname))
|
print('Deleting `{}` database'.format(dbname))
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
_drop_db(conn, dbname)
|
_drop_db(conn, dbname)
|
||||||
|
|
||||||
print('Finished deleting `{}`'.format(dbname))
|
print('Finished deleting `{}`'.format(dbname))
|
||||||
@ -148,7 +148,7 @@ def _bdb(_setup_database, _configure_planetmint):
|
|||||||
from planetmint.models import Transaction
|
from planetmint.models import Transaction
|
||||||
from .utils import flush_db
|
from .utils import flush_db
|
||||||
from planetmint.config import Config
|
from planetmint.config import Config
|
||||||
conn = Connection().conn
|
conn = Connection()
|
||||||
yield
|
yield
|
||||||
dbname = Config().get()['database']['name']
|
dbname = Config().get()['database']['name']
|
||||||
flush_db(conn, dbname)
|
flush_db(conn, dbname)
|
||||||
@ -389,7 +389,7 @@ def db_name(db_config):
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def db_conn():
|
def db_conn():
|
||||||
return Connection().conn
|
return Connection()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
@ -119,7 +119,7 @@ def test_outputs_query_key_order(b, user_pk, user_sk, user2_pk, user2_sk):
|
|||||||
|
|
||||||
# clean the transaction, metdata and asset collection
|
# clean the transaction, metdata and asset collection
|
||||||
# conn = connect()
|
# conn = connect()
|
||||||
connection = Connection().conn
|
connection = Connection()
|
||||||
# conn.run(conn.collection('transactions').delete_many({}))
|
# conn.run(conn.collection('transactions').delete_many({}))
|
||||||
# conn.run(conn.collection('metadata').delete_many({}))
|
# conn.run(conn.collection('metadata').delete_many({}))
|
||||||
# conn.run(conn.collection('assets').delete_many({}))
|
# conn.run(conn.collection('assets').delete_many({}))
|
||||||
|
|||||||
@ -66,24 +66,25 @@ def test_bigchain_class_default_initialization(config):
|
|||||||
assert planet.validation == BaseValidationRules
|
assert planet.validation == BaseValidationRules
|
||||||
|
|
||||||
|
|
||||||
def test_bigchain_class_initialization_with_parameters():
|
# def test_bigchain_class_initialization_with_parameters():
|
||||||
from planetmint import Planetmint
|
# from planetmint import Planetmint
|
||||||
from planetmint.backend import Connection
|
# from planetmint.backend import Connection
|
||||||
from planetmint.validation import BaseValidationRules
|
# from planetmint.validation import BaseValidationRules
|
||||||
|
|
||||||
init_db_kwargs = {
|
# init_db_kwargs = {
|
||||||
'backend': 'localmongodb',
|
# 'backend': 'localmongodb',
|
||||||
'host': 'this_is_the_db_host',
|
# 'host': 'this_is_the_db_host',
|
||||||
'port': 12345,
|
# 'port': 12345,
|
||||||
'name': 'this_is_the_db_name',
|
# 'name': 'this_is_the_db_name',
|
||||||
}
|
# }
|
||||||
connection = Connection(**init_db_kwargs).conn
|
# connection = Connection().connect(**init_db_kwargs)
|
||||||
planet = Planetmint(connection=connection)
|
# planet = Planetmint(connection=connection)
|
||||||
assert planet.connection == connection
|
# assert planet.connection == connection
|
||||||
assert planet.connection.host == init_db_kwargs['host']
|
# assert planet.connection.host == init_db_kwargs['host']
|
||||||
assert planet.connection.port == init_db_kwargs['port']
|
# assert planet.connection.port == init_db_kwargs['port']
|
||||||
# assert planet.connection.name == init_db_kwargs['name']
|
# # assert planet.connection.name == init_db_kwargs['name']
|
||||||
assert planet.validation == BaseValidationRules
|
# assert planet.validation == BaseValidationRules
|
||||||
|
# Connection().connect(backend='tarantool')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user