Source code for girder.models

import pymongo
import pymongo.cursor
import urllib.parse

from girder import logprint
from girder.utility import config

_dbClients = {}


if not hasattr(pymongo.cursor.Cursor, 'count'):
    import warnings

    def _cursorCount(self, with_limit_and_skip=False):
        warnings.warn(
            'count is deprecated. Use Collection.count_documents instead.',
            DeprecationWarning,
            stacklevel=2,
        )
        params = {}
        if with_limit_and_skip and getattr(self, '_limit', getattr(self, '_Cursor__limit', None)):
            params['limit'] = getattr(self, '_limit', getattr(self, '_Cursor__limit', None))
        if with_limit_and_skip and getattr(self, '_skip', getattr(self, '_Cursor__skip', None)):
            params['skip'] = getattr(self, '_skip', getattr(self, '_Cursor__skip', None))
        return getattr(self, '_collection', getattr(
            self, '_Cursor__collection', None)).count_documents(
                getattr(self, '_spec', getattr(self, '_Cursor__spec', None)), **params)

    pymongo.cursor.Cursor.count = _cursorCount


[docs]def getDbConfig(): """Get the database configuration values from the cherrypy config.""" cfg = config.getConfig() if 'database' in cfg: return cfg['database'] else: return {}
[docs]def getDbConnection(uri=None, replicaSet=None, quiet=False, **kwargs): """ Get a MongoClient object that is connected to the configured database. We lazy-instantiate a module-level singleton, the MongoClient objects manage their own connection pools internally. Any extra kwargs you pass to this method will be passed through to the MongoClient. :param uri: if specified, connect to this mongo db rather than the one in the config. :param replicaSet: if uri is specified, use this replica set. :param quiet: if true, don't logprint warnings and success. :type quiet: bool """ global _dbClients origKey = (uri, replicaSet) if origKey in _dbClients: return _dbClients[origKey] dbConf = getDbConfig() if uri is None or uri == '': uri = dbConf.get('uri') replicaSet = dbConf.get('replica_set') clientOptions = { # This is the maximum time between when we fetch data from a cursor. # If it times out, the cursor is lost and we can't reconnect. If it # isn't set, we have issues with replica sets when the primary goes # down. This value can be overridden in the mongodb uri connection # string with the socketTimeoutMS. 'socketTimeoutMS': 60000, 'connectTimeoutMS': 20000, 'serverSelectionTimeoutMS': 20000, 'readPreference': 'secondaryPreferred', 'replicaSet': replicaSet, 'w': 'majority' } # All other options in the [database] section will be passed directly as # options to the mongo client for opt, val in dict(dbConf).items(): if opt not in {'uri', 'replica_set'}: clientOptions[opt] = val # Finally, kwargs take precedence clientOptions.update(kwargs) # if the connection URI overrides any option, honor it above our own # settings. uriParams = urllib.parse.parse_qs(urllib.parse.urlparse(uri).query) for key in uriParams: if key in clientOptions: del clientOptions[key] if uri is None: dbUriRedacted = 'mongodb://localhost:27017/girder' if not quiet: logprint.warning('WARNING: No MongoDB URI specified, using ' 'the default value') client = pymongo.MongoClient(dbUriRedacted, **clientOptions) else: parts = uri.split('@') if len(parts) == 2: dbUriRedacted = 'mongodb://' + parts[1] else: dbUriRedacted = uri client = pymongo.MongoClient(uri, **clientOptions) if not quiet: desc = '' if replicaSet: desc += ', replica set: %s' % replicaSet logprint.info('Connecting to MongoDB: %s%s' % (dbUriRedacted, desc)) # Make sure we can connect to the mongo server at startup client.server_info() _dbClients[origKey] = _dbClients[(uri, replicaSet)] = client return client