def test_module_dispatch_errors_on_missing_func(mock_module): from bigchaindb.backend.utils import ( module_dispatch_registrar, ModuleDispatchRegistrationError, ) mock_dispatch = module_dispatch_registrar(mock_module) with pytest.raises(ModuleDispatchRegistrationError): @mock_dispatch(str) def dispatched(): pass
def test_module_dispatch_registers(mock_module): from bigchaindb.backend.utils import module_dispatch_registrar @singledispatch def dispatcher(t): pass mock_module.dispatched = dispatcher mock_dispatch = module_dispatch_registrar(mock_module) @mock_dispatch(str) def dispatched(t): pass assert mock_module.dispatched.registry[str] == dispatched
def test_module_dispatch_dispatches(mock_module): from bigchaindb.backend.utils import module_dispatch_registrar @singledispatch def dispatcher(t): return False mock_module.dispatched = dispatcher mock_dispatch = module_dispatch_registrar(mock_module) @mock_dispatch(str) def dispatched(t): return True assert mock_module.dispatched(1) is False # Goes to dispatcher() assert mock_module.dispatched('1') is True # Goes to dispatched()
"""Query implementation for MongoDB""" from pymongo import DESCENDING from bigchaindb import backend from bigchaindb.backend.exceptions import DuplicateKeyError from bigchaindb.common.exceptions import MultipleValidatorOperationError from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.localmongodb.connection import LocalMongoDBConnection from bigchaindb.common.transaction import Transaction from bigchaindb.backend import mongodb from bigchaindb.backend.query import VALIDATOR_UPDATE_ID register_query = module_dispatch_registrar(backend.query) @register_query(LocalMongoDBConnection) def store_transaction(conn, signed_transaction): try: return conn.run( conn.collection('transactions').insert_one(signed_transaction)) except DuplicateKeyError: pass @register_query(LocalMongoDBConnection) def store_transactions(conn, signed_transactions): return conn.run( conn.collection('transactions').insert_many(signed_transactions))
"""Utils to initialize and drop the database.""" import logging from pymongo import ASCENDING, DESCENDING, TEXT from bigchaindb import backend from bigchaindb.common import exceptions from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.mongodb.connection import MongoDBConnection logger = logging.getLogger(__name__) register_schema = module_dispatch_registrar(backend.schema) @register_schema(MongoDBConnection) def create_database(conn, dbname): if dbname in conn.conn.database_names(): raise exceptions.DatabaseAlreadyExists('Database `{}` already exists' .format(dbname)) logger.info('Create database `%s`.', dbname) # TODO: read and write concerns can be declared here conn.conn.get_database(dbname) @register_schema(MongoDBConnection) def create_tables(conn, dbname): for table_name in ['bigchain', 'backlog', 'votes', 'assets']: logger.info('Create `%s` table.', table_name)
import logging import time import pymongo from bigchaindb import backend from bigchaindb.backend.changefeed import ChangeFeed from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.mongodb.connection import MongoDBConnection from bigchaindb.backend.exceptions import BackendError logger = logging.getLogger(__name__) register_changefeed = module_dispatch_registrar(backend.changefeed) class MongoDBChangeFeed(ChangeFeed): """This class implements a MongoDB changefeed. We emulate the behaviour of the RethinkDB changefeed by using a tailable cursor that listens for events on the oplog. """ def run_forever(self): for element in self.prefeed: self.outqueue.put(element) while True: try: # XXX: hack to force reconnection. Why? Because the cursor # in `run_changefeed` does not run in the context of a
"""Query implementation for MongoDB""" from time import time from pymongo import ReturnDocument from bigchaindb import backend from bigchaindb.common.exceptions import CyclicBlockchainError from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.mongodb.connection import MongoDBConnection register_query = module_dispatch_registrar(backend.query) @register_query(MongoDBConnection) def write_transaction(conn, signed_transaction): return conn.db['backlog'].insert_one(signed_transaction) @register_query(MongoDBConnection) def update_transaction(conn, transaction_id, doc): return conn.db['backlog']\ .find_one_and_update({'id': transaction_id}, doc, return_document=ReturnDocument.AFTER) @register_query(MongoDBConnection) def delete_transaction(conn, *transaction_id): return conn.db['backlog'].delete_many({'id': {'$in': transaction_id}})
import logging import time import pymongo from pymongo import errors from bigchaindb import backend from bigchaindb.backend.changefeed import ChangeFeed from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.mongodb.connection import MongoDBConnection logger = logging.getLogger(__name__) register_changefeed = module_dispatch_registrar(backend.changefeed) class MongoDBChangeFeed(ChangeFeed): """This class implements a MongoDB changefeed. We emulate the behaviour of the RethinkDB changefeed by using a tailable cursor that listens for events on the oplog. """ def run_forever(self): for element in self.prefeed: self.outqueue.put(element) while True: try: self.run_changefeed() break except (errors.ConnectionFailure, errors.OperationFailure, errors.AutoReconnect,
"""Database configuration functions.""" import logging import rethinkdb as r from bigchaindb.backend import admin from bigchaindb.backend.schema import TABLES from bigchaindb.backend.exceptions import OperationError from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.rethinkdb.connection import RethinkDBConnection logger = logging.getLogger(__name__) register_admin = module_dispatch_registrar(admin) @register_admin(RethinkDBConnection) def get_config(connection, *, table): """Get the configuration of the given table. Args: connection (:class:`~bigchaindb.backend.connection.Connection`): A connection to the database. table (str): The name of the table to get the configuration for. Returns: dict: The configuration of the given table """ return connection.run(r.table(table).config())