Skip to content

Commit 0997fbf

Browse files
author
Mike Dirolf
committed
some tests and fixes for new gridfs api
1 parent 0baad44 commit 0997fbf

File tree

4 files changed

+427
-479
lines changed

4 files changed

+427
-479
lines changed

doc/api/gridfs/grid_file.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414

1515
.. autoattribute:: _id
1616

17-
.. autoclass:: GridFile(file-spec, database[, mode='r'[, collection='fs']])
17+
.. autoclass:: GridFile
1818
:members:

gridfs/grid_file.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,24 @@
3838
_SEEK_END = 2
3939

4040

41+
"""Default chunk size, in bytes."""
42+
DEFAULT_CHUNK_SIZE = 256 * 1024
43+
44+
4145
def _create_property(field_name, docstring,
4246
read_only=False, closed_only=False):
4347
"""Helper for creating properties to read/write to files.
4448
"""
4549
def getter(self):
46-
if closed_only and not self.__closed:
50+
if closed_only and not self._closed:
4751
raise AttributeError("can only get %r on a closed file" %
4852
field_name)
49-
return self.__file.get(field_name, None)
53+
return self._file.get(field_name, None)
5054
def setter(self, value):
51-
if self.__closed:
55+
if self._closed:
5256
raise AttributeError("cannot set %r on a closed file" %
5357
field_name)
54-
self.__file[field_name] = value
58+
self._file[field_name] = value
5559

5660
if read_only:
5761
docstring = docstring + "\n\nThis attribute is read-only."""
@@ -107,32 +111,40 @@ def __init__(self, root_collection, **kwargs):
107111
if not isinstance(root_collection, Collection):
108112
raise TypeError("root_collection must be an instance of Collection")
109113

110-
# Convert from kwargs to a file document
114+
# Handle alternative naming
111115
if "content_type" in kwargs:
112116
kwargs["contentType"] = kwargs.pop("content_type")
113117
if "chunk_size" in kwargs:
114118
kwargs["chunkSize"] = kwargs.pop("chunk_size")
119+
120+
# Move bonus kwargs into metadata
121+
to_move = []
115122
for key in kwargs:
116123
if key not in ["_id", "filename", "contentType",
117124
"chunkSize", "aliases", "metadata"]:
118-
kwargs["metadata"] = kwargs.get("metadata", {})
125+
to_move.append(key)
126+
if to_move:
127+
kwargs["metadata"] = kwargs.get("metadata", {})
128+
for key in to_move:
119129
kwargs["metadata"][key] = kwargs.pop(key)
120-
if "_id" not in kwargs:
121-
kwargs["_id"] = ObjectId()
130+
131+
# Defaults
132+
kwargs["_id"] = kwargs.get("_id", ObjectId())
133+
kwargs["chunkSize"] = kwargs.get("chunkSize", DEFAULT_CHUNK_SIZE)
122134

123135
self.__coll = root_collection
124136
self.__chunks = root_collection.chunks
125-
self.__file = kwargs
137+
self._file = kwargs
126138
self.__buffer = StringIO()
127139
self.__position = 0
128140
self.__chunk_number = 0
129-
self.__closed = False
141+
self._closed = False
130142

131143
@property
132144
def closed(self):
133145
"""Is this file closed?
134146
"""
135-
return self.__closed
147+
return self._closed
136148

137149
_id = _create_property("_id", "The ``'_id'`` value for this file.",
138150
read_only=True)
@@ -158,7 +170,7 @@ def __flush_data(self, data):
158170
return
159171
assert(len(data) <= self.chunk_size)
160172

161-
chunk = {"files_id": self.__file["_id"],
173+
chunk = {"files_id": self._file["_id"],
162174
"n": self.__chunk_number,
163175
"data": Binary(data)}
164176

@@ -181,20 +193,20 @@ def __flush(self):
181193
md5 = self.__coll.database.command("filemd5", self._id,
182194
root=self.__coll.name)["md5"]
183195

184-
self.__file["md5"] = md5
185-
self.__file["length"] = self.__position
186-
self.__file["uploadDate"] = datetime.datetime.utcnow()
187-
return self.__coll.files.insert(self.__file)
196+
self._file["md5"] = md5
197+
self._file["length"] = self.__position
198+
self._file["uploadDate"] = datetime.datetime.utcnow()
199+
return self.__coll.files.insert(self._file)
188200

189201
def close(self):
190202
"""Flush the file and close it.
191203
192204
A closed file cannot be written any more. Calling
193205
:meth:`close` more than once is allowed.
194206
"""
195-
if not self.__closed:
207+
if not self._closed:
196208
self.__flush()
197-
self.__closed = True
209+
self._closed = True
198210

199211
# TODO should support writing unicode to a file. this means that files will
200212
# need to have an encoding attribute.
@@ -210,7 +222,7 @@ def write(self, data):
210222
:Parameters:
211223
- `data`: string of bytes to be written to the file
212224
"""
213-
if self.__closed:
225+
if self._closed:
214226
raise ValueError("cannot write to a closed file")
215227

216228
if not isinstance(data, str):
@@ -270,9 +282,9 @@ def __init__(self, root_collection, file_id):
270282
raise TypeError("root_collection must be an instance of Collection")
271283

272284
self.__chunks = root_collection.chunks
273-
self.__file = root_collection.files.find_one({"_id": file_id})
285+
self._file = root_collection.files.find_one({"_id": file_id})
274286

275-
if not self.__file:
287+
if not self._file:
276288
raise NoFile("no file in gridfs collection %r with _id %r" %
277289
(root_collection, file_id))
278290

@@ -315,7 +327,7 @@ def read(self, size=-1):
315327
size = remainder
316328

317329
data = self.__buffer
318-
chunk_number = (len(bytes) + self.__position) / self.chunk_size
330+
chunk_number = (len(data) + self.__position) / self.chunk_size
319331

320332
while len(data) < size:
321333
chunk = self.__chunks.find_one({"files_id": self._id,

0 commit comments

Comments
 (0)