Example #1
0
    def _new_connection(cls):
        """ Return a new connection to this class' database. """
        kwargs = cls._connection_info()

        kwargs.update({
                'max_pool_size': cls.config_max_pool_size,
                'auto_start_request': cls.config_auto_start_request,
                'use_greenlets': cls.config_use_greenlets,
                'tz_aware': cls.config_tz_aware,
                'w': cls.config_write_concern,
                'ssl': cls.config_ssl,
                })

        if _version._gte('2.1.0') and _version._lt('2.2.0'):
            # This causes an error for the 2.1.x versions of Pymongo, so we
            # remove it
            kwargs.pop('auto_start_request')
            kwargs.pop('use_greenlets')
        elif _version._gte('3.0.0'):
            kwargs.pop('auto_start_request')
            kwargs.pop('max_pool_size')
            kwargs.pop('use_greenlets')

        if cls.config_replica:
            kwargs['replicaSet'] = cls.config_replica
            logging.getLogger(__name__).info("Creating new MongoDB connection "
                    "to '{}:{}' replica: {}".format(cls.config_host,
                        cls.config_port, cls.config_replica))
        else:
            logging.getLogger(__name__).info("Creating new MongoDB connection "
                "to '{}:{}'".format(cls.config_host, cls.config_port))

        return cls.config_connection_cls(**kwargs)
Example #2
0
    def _ensure_indexes(cls):
        """ Guarantees indexes are created once per connection instance. """
        ensured = getattr(cls, '_ensured', None)
        if ensured:
            return

        if cls.config_indexes:
            for index in cls.config_indexes:
                logging.getLogger(__name__).info("Ensuring index: {}"
                        .format(index))
                if isinstance(index, Index):
                    index.ensure(cls)
                else:  # pragma: no cover
                    # This code is no longer reachable with the new Indexes,
                    # but I don't want to remove it yet
                    caching_key = 'cache_for' if _version._gte('2.3') else 'ttl'
                    kwargs = {caching_key: (60 * 60 * 24)}
                    cls.collection.ensure_index(getattr(cls, index),
                            background=True, **kwargs)

        logging.getLogger(__name__).info("Indexing ensured.")
        cls._ensured = True

        # Create a reload hook for the first time we run
        if ensured is None:
            @pyconfig.reload_hook
            def _reload():
                """ Allow index recreation if configuration settings change via
                    pyconfig.
                """
                cls._ensured = False
Example #3
0
def test_replica_errors_for_versions_before_2_1():
    if _version._gte('2.1'):
        raise SkipTest

    class Replica(Mongo):
        config_host = 'localhost'
        config_port = 27017
        config_replica = 'test'
Example #4
0
def test_mongo_client_with_ssl_before_2_1():
    if _version._gte('2.1'):
        raise SkipTest("Only test this with version 2.1 or earlier.")

    class SSLMongo(Mongo):
        config_host = 'localhost'
        config_port = 27017
        config_ssl = True
Example #5
0
 def next(self):
     if six.PY3 and _version._gte('3'):
         doc = super().next()
     elif six.PY3 and _version._lt('3'):
         doc = super().__next__()
     else:
         doc = super(Cursor, self).next()
     doc = self._doc_cls(doc)
     return doc
Example #6
0
def setup():
    # Set up a float counter in the sidecar collection.
    import pymongo
    if _version._gte('2.4'):
        conn = pymongo.MongoClient('127.0.0.1')
    else:
        conn = pymongo.Connection('127.0.0.1')
    coll = conn[database_name()][SIDECAR]
    coll.insert({'_id': 'FloatDoc', 'value':float(100)})
Example #7
0
def test_replica_works_for_versions_between_2_1_and_2_4():
    if _version._lt('2.1') or _version._gte('2.4'):
        raise SkipTest

    with mock.patch('pymongo.ReplicaSetConnection') as replica:
        class Replica(Mongo):
            config_host = 'localhost'
            config_port = 27017
            config_replica = 'test'

        with Replica:
            pass

        replica.assert_called_once()
Example #8
0
def test_replica_works_for_versions_after_2_4():
    if _version._lt('2.4'):
        raise SkipTest

    if _version._gte('3'):
        raise SkipTest

    with mock.patch('pymongo.MongoReplicaSetClient') as replica:
        class Replica(Mongo):
            config_host = 'localhost'
            config_port = 27017
            config_replica = 'test'

        with Replica:
            pass

        replica.assert_called_once()
Example #9
0
    def __new__(mcs, name, bases, cls_dict):
        """ Return the Mongo class. """
        # This ensures that a late-declared class does not inherit an existing
        # connection object.
        cls_dict['_connection'] = None

        # Choose the correct connection class
        if cls_dict.get('config_connection_cls', UNSET) is UNSET:
            # Are we using a replica?
            # XXX: Getting the connection type at class creation time rather
            # than connection instantiation time means that disabling
            # config_replica (setting to None) at runtime has no effect. I
            # doubt anyone would ever do this, but you never know.
            _replica = cls_dict.get('config_replica', UNSET)
            # Handle attribute descriptors responsibly
            if _replica and hasattr(_replica, '__get__'):
                try:
                    _replica = _replica.__get__(None, None)
                except:
                    raise TypeError("'%s.config_replica' appears to be a "
                            "descriptor and its value could not be "
                            "retrieved reliably." % name)
            # Handle replica set connections
            if _replica:
                if _version._lt('2.1'):
                    raise TypeError("Need pymongo.version >= 2.1 for replica "
                            "sets.")
                elif _version._gte('2.4'):
                    conn = pymongo.MongoReplicaSetClient
                else:
                    conn = pymongo.ReplicaSetConnection
            else:
                # Get the correct regular connection
                if _version._gte('2.4'):
                    conn = pymongo.MongoClient
                else:
                    conn = pymongo.Connection
            # Set our connection type
            cls_dict['config_connection_cls'] = conn

        # Specially handle base class
        if name == 'Mongo' and bases == (object,):
            # Create thread local self
            cls_dict['_self'] = threading.local()
            return type.__new__(mcs, name, bases, cls_dict)

        if cls_dict.get('config_uri', UNSET) is UNSET:
            # Ensure we have minimum configuration params
            if cls_dict.get('config_host', UNSET) is UNSET:
                raise TypeError("missing required 'config_host'")

            if cls_dict.get('config_port', UNSET) is UNSET:
                raise TypeError("missing required 'config_port'")

        # Validate if pymongo version supports SSL.
        if (cls_dict.get('config_ssl', False) is True and
                _version._lt('2.1')):
            raise TypeError("Need pymongo.version >= 2.1 to use "
                    "SSL.")

        # Create new class
        cls = type.__new__(mcs, name, bases, cls_dict)

        # This reload hook uses a closure to access the class
        @pyconfig.reload_hook
        def _reload():
            """ A hook for reloading the connection settings with pyconfig. """
            cls.reconnect()

        return cls