Skip to content

Commit 9ddabb9

Browse files
author
Mike Dirolf
committed
add gridfs get_version method PYTHON-115
1 parent 08830fb commit 9ddabb9

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

gridfs/__init__.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,33 +122,60 @@ def get(self, file_id):
122122
"""
123123
return GridOut(self.__collection, file_id)
124124

125-
def get_last_version(self, filename):
125+
def get_version(self, filename, version=-1):
126126
"""Get a file from GridFS by ``"filename"``.
127127
128-
Returns the most recently uploaded file in GridFS with the
129-
name `filename` as an instance of
130-
:class:`~gridfs.grid_file.GridOut`. Raises
131-
:class:`~gridfs.errors.NoFile` if no such file exists.
128+
Returns a version of the file in GridFS with the name
129+
`filename` as an instance of
130+
:class:`~gridfs.grid_file.GridOut`. Version ``-1`` will be the
131+
most recently uploaded, ``-2`` the second most recently
132+
uploaded, etc. Version ``0`` will be the first version
133+
uploaded, ``1`` the second version, etc. So if three versions
134+
have been uploaded, then version ``0`` is the same as version
135+
``-3``, version ``1`` is the same as version ``-2``, and
136+
version ``2`` is the same as version ``-1``.
137+
138+
Raises :class:`~gridfs.errors.NoFile` if no such version of
139+
that file exists.
132140
133141
An index on ``{filename: 1, uploadDate: -1}`` will
134142
automatically be created when this method is called the first
135143
time.
136144
137145
:Parameters:
138146
- `filename`: ``"filename"`` of the file to get
147+
- `version` (optional): version of the file to get (defualts
148+
to -1, the most recent version uploaded)
139149
140-
.. versionadded:: 1.6
150+
.. versionadded:: 1.8.1+
141151
"""
142152
self.__files.ensure_index([("filename", ASCENDING),
143153
("uploadDate", DESCENDING)])
144154

145155
cursor = self.__files.find({"filename": filename})
146-
cursor.limit(-1).sort("uploadDate", DESCENDING)
156+
if version < 0:
157+
skip = abs(version) - 1
158+
cursor.limit(-1).skip(skip).sort("uploadDate", DESCENDING)
159+
else:
160+
cursor.limit(-1).skip(version).sort("uploadDate", ASCENDING)
147161
try:
148162
grid_file = cursor.next()
149163
return GridOut(self.__collection, grid_file["_id"])
150164
except StopIteration:
151-
raise NoFile("no file in gridfs with filename %r" % filename)
165+
raise NoFile("no version %d for filename %r" % (version, filename))
166+
167+
def get_last_version(self, filename):
168+
"""Get the most recent version of a file in GridFS by ``"filename"``.
169+
170+
Equivalent to calling :meth:`get_version` with the default
171+
`version` (``-1``).
172+
173+
:Parameters:
174+
- `filename`: ``"filename"`` of the file to get
175+
176+
.. versionadded:: 1.6
177+
"""
178+
return self.get_version(filename)
152179

153180
# TODO add optional safe mode for chunk removal?
154181
def delete(self, file_id):

test/test_gridfs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,25 @@ def test_get_last_version(self):
178178
self.fs.delete(a)
179179
self.assertRaises(NoFile, self.fs.get_last_version, "test")
180180

181+
def test_get_version(self):
182+
self.fs.put("foo", filename="test")
183+
time.sleep(0.01)
184+
self.fs.put("bar", filename="test")
185+
time.sleep(0.01)
186+
self.fs.put("baz", filename="test")
187+
time.sleep(0.01)
188+
189+
self.assertEqual("foo", self.fs.get_version("test", 0).read())
190+
self.assertEqual("bar", self.fs.get_version("test", 1).read())
191+
self.assertEqual("baz", self.fs.get_version("test", 2).read())
192+
193+
self.assertEqual("baz", self.fs.get_version("test", -1).read())
194+
self.assertEqual("bar", self.fs.get_version("test", -2).read())
195+
self.assertEqual("foo", self.fs.get_version("test", -3).read())
196+
197+
self.assertRaises(NoFile, self.fs.get_version, "test", 3)
198+
self.assertRaises(NoFile, self.fs.get_version, "test", -4)
199+
181200
def test_put_filelike(self):
182201
oid = self.fs.put(StringIO("hello world"), chunk_size=1)
183202
self.assertEqual(11, self.db.fs.chunks.count())

0 commit comments

Comments
 (0)