/openmdao.lib/src/openmdao/lib/casehandlers/pymongo_bson/dbref.py

https://github.com/thearn/OpenMDAO-Framework
Python | 147 lines | 73 code | 13 blank | 61 comment | 2 complexity | 7f97a83755524be52a3d5304d680fc79 MD5 | raw file
  1. # Copyright 2009-2014 MongoDB, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Tools for manipulating DBRefs (references to MongoDB documents)."""
  15. from copy import deepcopy
  16. from openmdao.lib.casehandlers.pymongo_bson.son import SON
  17. class DBRef(object):
  18. """A reference to a document stored in MongoDB.
  19. """
  20. # DBRef isn't actually a BSON "type" so this number was arbitrarily chosen.
  21. _type_marker = 100
  22. def __init__(self, collection, id, database=None, _extra={}, **kwargs):
  23. """Initialize a new :class:`DBRef`.
  24. Raises :class:`TypeError` if `collection` or `database` is not
  25. an instance of :class:`basestring` (:class:`str` in python 3).
  26. `database` is optional and allows references to documents to work
  27. across databases. Any additional keyword arguments will create
  28. additional fields in the resultant embedded document.
  29. :Parameters:
  30. - `collection`: name of the collection the document is stored in
  31. - `id`: the value of the document's ``"_id"`` field
  32. - `database` (optional): name of the database to reference
  33. - `**kwargs` (optional): additional keyword arguments will
  34. create additional, custom fields
  35. .. versionchanged:: 1.8
  36. Now takes keyword arguments to specify additional fields.
  37. .. versionadded:: 1.1.1
  38. The `database` parameter.
  39. .. mongodoc:: dbrefs
  40. """
  41. if not isinstance(collection, basestring):
  42. raise TypeError("collection must be an "
  43. "instance of %s" % (basestring.__name__,))
  44. if database is not None and not isinstance(database, basestring):
  45. raise TypeError("database must be an "
  46. "instance of %s" % (basestring.__name__,))
  47. self.__collection = collection
  48. self.__id = id
  49. self.__database = database
  50. kwargs.update(_extra)
  51. self.__kwargs = kwargs
  52. @property
  53. def collection(self):
  54. """Get the name of this DBRef's collection as unicode.
  55. """
  56. return self.__collection
  57. @property
  58. def id(self):
  59. """Get this DBRef's _id.
  60. """
  61. return self.__id
  62. @property
  63. def database(self):
  64. """Get the name of this DBRef's database.
  65. Returns None if this DBRef doesn't specify a database.
  66. .. versionadded:: 1.1.1
  67. """
  68. return self.__database
  69. def __getattr__(self, key):
  70. try:
  71. return self.__kwargs[key]
  72. except KeyError:
  73. raise AttributeError(key)
  74. # Have to provide __setstate__ to avoid
  75. # infinite recursion since we override
  76. # __getattr__.
  77. def __setstate__(self, state):
  78. self.__dict__.update(state)
  79. def as_doc(self):
  80. """Get the SON document representation of this DBRef.
  81. Generally not needed by application developers
  82. """
  83. doc = SON([("$ref", self.collection),
  84. ("$id", self.id)])
  85. if self.database is not None:
  86. doc["$db"] = self.database
  87. doc.update(self.__kwargs)
  88. return doc
  89. def __repr__(self):
  90. extra = "".join([", %s=%r" % (k, v)
  91. for k, v in self.__kwargs.iteritems()])
  92. if self.database is None:
  93. return "DBRef(%r, %r%s)" % (self.collection, self.id, extra)
  94. return "DBRef(%r, %r, %r%s)" % (self.collection, self.id,
  95. self.database, extra)
  96. def __eq__(self, other):
  97. if isinstance(other, DBRef):
  98. us = (self.__database, self.__collection,
  99. self.__id, self.__kwargs)
  100. them = (other.__database, other.__collection,
  101. other.__id, other.__kwargs)
  102. return us == them
  103. return NotImplemented
  104. def __ne__(self, other):
  105. return not self == other
  106. def __hash__(self):
  107. """Get a hash value for this :class:`DBRef`.
  108. .. versionadded:: 1.1
  109. """
  110. return hash((self.__collection, self.__id, self.__database,
  111. tuple(sorted(self.__kwargs.items()))))
  112. def __deepcopy__(self, memo):
  113. """Support function for `copy.deepcopy()`.
  114. .. versionadded:: 1.10
  115. """
  116. return DBRef(deepcopy(self.__collection, memo),
  117. deepcopy(self.__id, memo),
  118. deepcopy(self.__database, memo),
  119. deepcopy(self.__kwargs, memo))