PYTHON-800 - Add CodecOptions class.
This commit is contained in:
parent
8a64f261fd
commit
b87fb790a2
@ -14,8 +14,10 @@
|
||||
|
||||
"""Tools to parse mongo client options."""
|
||||
|
||||
from bson.binary import OLD_UUID_SUBTYPE
|
||||
from bson.py3compat import iteritems
|
||||
from pymongo.auth import _build_credentials_tuple
|
||||
from pymongo.codec_options import CodecOptions
|
||||
from pymongo.common import validate
|
||||
from pymongo.errors import ConfigurationError
|
||||
from pymongo.pool import PoolOptions
|
||||
@ -34,6 +36,14 @@ def _parse_credentials(username, password, database, options):
|
||||
mechanism, source, username, password, options)
|
||||
|
||||
|
||||
def _parse_codec_options(options):
|
||||
"""Parse BSON codec options."""
|
||||
as_class = options.get('document_class', dict)
|
||||
tz_aware = options.get('tz_aware', False)
|
||||
uuid_rep = options.get('uuidrepresentation', OLD_UUID_SUBTYPE)
|
||||
return CodecOptions(as_class, tz_aware, uuid_rep)
|
||||
|
||||
|
||||
def _parse_read_preference(options):
|
||||
"""Parse read preference options."""
|
||||
if 'read_preference' in options:
|
||||
@ -113,21 +123,20 @@ class ClientOptions(object):
|
||||
|
||||
self.__credentials = _parse_credentials(
|
||||
username, password, database, options)
|
||||
self.__codec_options = _parse_codec_options(options)
|
||||
self.__pool_options = _parse_pool_options(options)
|
||||
self.__read_preference = _parse_read_preference(options)
|
||||
self.__replica_set_name = options.get('replicaset')
|
||||
self.__write_concern = _parse_write_concern(options)
|
||||
# TODO: BSONOptions
|
||||
self.__uuid_subtype = options.get('uuidrepresentation')
|
||||
|
||||
@property
|
||||
def credentials(self):
|
||||
"""A MongoCredentials instance or None."""
|
||||
"""A :class:`~pymongo.auth.MongoCredentials` instance or None."""
|
||||
return self.__credentials
|
||||
|
||||
@property
|
||||
def pool_options(self):
|
||||
"""A PoolOptions instance."""
|
||||
"""A :class:`~pymongo.pool.PoolOptions` instance."""
|
||||
return self.__pool_options
|
||||
|
||||
@property
|
||||
@ -141,11 +150,11 @@ class ClientOptions(object):
|
||||
return self.__replica_set_name
|
||||
|
||||
@property
|
||||
def uuid_subtype(self):
|
||||
"""BSON UUID representation."""
|
||||
return self.__uuid_subtype
|
||||
def codec_options(self):
|
||||
"""A :class:`~pymongo.codec_options.CodecOptions` instance."""
|
||||
return self.__codec_options
|
||||
|
||||
@property
|
||||
def write_concern(self):
|
||||
"""A WriteConcern instance."""
|
||||
"""A :class:`~pymongo.write_concern.WriteConcern` instance."""
|
||||
return self.__write_concern
|
||||
|
||||
66
pymongo/codec_options.py
Normal file
66
pymongo/codec_options.py
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 2014 MongoDB, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
"""Tools for specifying BSON codec options."""
|
||||
|
||||
from collections import MutableMapping
|
||||
|
||||
from bson.binary import OLD_UUID_SUBTYPE
|
||||
|
||||
|
||||
class CodecOptions(object):
|
||||
"""Encapsulates BSON options used in CRUD operations.
|
||||
|
||||
:Parameters:
|
||||
- `as_class`: BSON documents returned in queries will be decoded
|
||||
to an instance of this class. Must be a subclass of
|
||||
:class:`~collections.MutableMapping`. Defaults to :class:`dict`.
|
||||
- `tz_aware`: If ``True``, BSON datetimes will be decoded to timezone
|
||||
aware instances of :class:`~datetime.datetime`. Otherwise they will be
|
||||
naive. Defaults to ``False``.
|
||||
- `uuid_representation`: The BSON representation to use when encoding
|
||||
and decoding instances of :class:`~uuid.UUID`. Defaults to
|
||||
:data:`~bson.binary.OLD_UUID_SUBTYPE`.
|
||||
"""
|
||||
|
||||
__slots__ = ("__as_class", "__tz_aware", "__uuid_rep")
|
||||
|
||||
def __init__(self, as_class=dict,
|
||||
tz_aware=False, uuid_representation=OLD_UUID_SUBTYPE):
|
||||
if not issubclass(as_class, MutableMapping):
|
||||
raise TypeError("document_class must be a "
|
||||
"subclass of MutableMapping")
|
||||
if not isinstance(tz_aware, bool):
|
||||
raise TypeError("tz_aware must be a boolean")
|
||||
if not isinstance(uuid_representation, int):
|
||||
raise TypeError("uuid_representation must be an integer")
|
||||
|
||||
self.__as_class = as_class
|
||||
self.__tz_aware = tz_aware
|
||||
self.__uuid_rep = uuid_representation
|
||||
|
||||
@property
|
||||
def as_class(self):
|
||||
"""Read only property for as_class."""
|
||||
return self.__as_class
|
||||
|
||||
@property
|
||||
def tz_aware(self):
|
||||
"""Read only property for tz_aware."""
|
||||
return self.__tz_aware
|
||||
|
||||
@property
|
||||
def uuid_representation(self):
|
||||
"""Read only property for uuid_subtype."""
|
||||
return self.__uuid_rep
|
||||
@ -98,8 +98,8 @@ class Collection(common.BaseObject):
|
||||
|
||||
.. mongodoc:: collections
|
||||
"""
|
||||
super(Collection, self).__init__(database.read_preference,
|
||||
database.uuid_subtype,
|
||||
super(Collection, self).__init__(database.codec_options,
|
||||
database.read_preference,
|
||||
database.write_concern)
|
||||
|
||||
if not isinstance(name, string_type):
|
||||
|
||||
@ -19,6 +19,7 @@ import collections
|
||||
import warnings
|
||||
|
||||
from pymongo.auth import MECHANISMS
|
||||
from pymongo.codec_options import CodecOptions
|
||||
from pymongo.errors import ConfigurationError
|
||||
from pymongo.read_preferences import (make_read_preference,
|
||||
read_pref_mode_from_name,
|
||||
@ -302,6 +303,13 @@ def validate_auth_mechanism_properties(option, value):
|
||||
return props
|
||||
|
||||
|
||||
def validate_document_class(option, value):
|
||||
if not issubclass(value, collections.MutableMapping):
|
||||
raise ConfigurationError("%s must be a sublass of "
|
||||
"collections.MutableMapping" % (option,))
|
||||
return value
|
||||
|
||||
|
||||
# journal is an alias for j,
|
||||
# wtimeoutms is an alias for wtimeout,
|
||||
VALIDATORS = {
|
||||
@ -331,6 +339,8 @@ VALIDATORS = {
|
||||
'authmechanism': validate_auth_mechanism,
|
||||
'authsource': validate_string,
|
||||
'authmechanismproperties': validate_auth_mechanism_properties,
|
||||
'document_class': validate_document_class,
|
||||
'tz_aware': validate_boolean,
|
||||
'uuidrepresentation': validate_uuid_representation,
|
||||
}
|
||||
|
||||
@ -374,12 +384,17 @@ class BaseObject(object):
|
||||
SHOULD NOT BE USED BY DEVELOPERS EXTERNAL TO MONGODB.
|
||||
"""
|
||||
|
||||
def __init__(self, read_preference, uuid_subtype, write_concern):
|
||||
def __init__(self, codec_options, read_preference, write_concern):
|
||||
|
||||
self.__codec_options = codec_options
|
||||
self.__read_pref = read_preference
|
||||
self.__uuid_subtype = uuid_subtype or OLD_UUID_SUBTYPE
|
||||
self.__write_concern = WriteConcern(**write_concern)
|
||||
|
||||
@property
|
||||
def codec_options(self):
|
||||
"""An instance of :class:`~pymongo.codec_options.CodecOptions`."""
|
||||
return self.__codec_options
|
||||
|
||||
def __set_write_concern(self, value):
|
||||
"""Property setter for write_concern."""
|
||||
if not isinstance(value, collections.Mapping):
|
||||
@ -498,11 +513,14 @@ class BaseObject(object):
|
||||
subtype 4. It can also be used to force legacy byte order and subtype
|
||||
compatibility with the Java and C# drivers. See the :mod:`bson.binary`
|
||||
module for all options."""
|
||||
return self.__uuid_subtype
|
||||
return self.__codec_options.uuid_representation
|
||||
|
||||
def __set_uuid_subtype(self, value):
|
||||
"""Sets the BSON Binary subtype to be used when storing UUIDs."""
|
||||
self.__uuid_subtype = validate_uuid_subtype("uuid_subtype", value)
|
||||
uuid_representation = validate_uuid_subtype("uuid_subtype", value)
|
||||
self.__codec_options = CodecOptions(self.__codec_options.as_class,
|
||||
self.__codec_options.tz_aware,
|
||||
uuid_representation)
|
||||
|
||||
uuid_subtype = property(__get_uuid_subtype, __set_uuid_subtype)
|
||||
|
||||
|
||||
@ -76,8 +76,8 @@ class Database(common.BaseObject):
|
||||
|
||||
db.__my_collection__
|
||||
"""
|
||||
super(Database, self).__init__(connection.read_preference,
|
||||
connection.uuid_subtype,
|
||||
super(Database, self).__init__(connection.codec_options,
|
||||
connection.read_preference,
|
||||
connection.write_concern)
|
||||
|
||||
if not isinstance(name, string_type):
|
||||
|
||||
@ -282,20 +282,20 @@ class MongoClient(common.BaseObject):
|
||||
condition_class = kwargs.pop('_condition_class', None)
|
||||
|
||||
kwargs['max_pool_size'] = max_pool_size
|
||||
kwargs['document_class'] = document_class
|
||||
kwargs['tz_aware'] = tz_aware
|
||||
opts.update(kwargs)
|
||||
self.__options = options = ClientOptions(
|
||||
username, password, dbase, opts)
|
||||
|
||||
self.__default_database_name = dbase
|
||||
self.__cursor_manager = CursorManager(self)
|
||||
self.__document_class = document_class
|
||||
self.__tz_aware = common.validate_boolean('tz_aware', tz_aware)
|
||||
|
||||
# Cache of existing indexes used by ensure_index ops.
|
||||
self.__index_cache = {}
|
||||
|
||||
super(MongoClient, self).__init__(options.read_preference,
|
||||
options.uuid_subtype,
|
||||
super(MongoClient, self).__init__(options.codec_options,
|
||||
options.read_preference,
|
||||
options.write_concern.document)
|
||||
|
||||
self.__all_credentials = {}
|
||||
@ -521,7 +521,7 @@ class MongoClient(common.BaseObject):
|
||||
.. versionchanged:: 3.0
|
||||
Now read-only.
|
||||
"""
|
||||
return self.__document_class
|
||||
return self.__options.codec_options.as_class
|
||||
|
||||
def get_document_class(self):
|
||||
"""Default class to use for documents returned from this client.
|
||||
@ -532,13 +532,13 @@ class MongoClient(common.BaseObject):
|
||||
' document_class property',
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
return self.__document_class
|
||||
return self.__options.codec_options.as_class
|
||||
|
||||
@property
|
||||
def tz_aware(self):
|
||||
"""Does this client return timezone-aware datetimes?
|
||||
"""
|
||||
return self.__tz_aware
|
||||
return self.__options.codec_options.tz_aware
|
||||
|
||||
@property
|
||||
def max_bson_size(self):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user