-
Notifications
You must be signed in to change notification settings - Fork 42
GridFS
GridFS is part of Mongo and lets you store files using a similar API.
To use GridFS you just have to create a new instance, passing it a Db
reference found in your dbConn
@app.Route("/upload")
newFile(@app.Attr() MongoDb dbConn)
{
var gridFS = new GridFS (dbConn.innerConn);
...
}
The easiest way to upload a file is through an Html <form>
, if you don't mind reloading your page you could use the action
and submit
combo
<form enctype="multipart/form-data" method="POST" action="upload">
Choose a file to upload: <input name="file" type="file"><br>
<input type="submit" value="Submit">
</form>
Then you can receive it in Redstone and store it in GridFS
@app.Route("/upload", methods: const [app.POST], allowMultipartRequest: true)
newFile(@app.Attr() MongoDb dbConn, @app.Body(app.FORM) Map form) async
{
//Get the form input field "file"
//Redstone decodes <input type="file"> fields to an HttpBodyFileUpload for you
HttpBodyFileUpload file = form ['file'];
var gridFS = new GridFS (dbConn.innerConn);
//Create a GridFS file with content
var input = new Stream.fromIterable([file.content]);
var gridIn = gridFS.createFile(input, file.filename);
//Save content type (you'll need this to properly serve the file latter)
gridIn.contentType = file.contentType.value;
//Save file
await gridIn.save();
return {'success' : true, 'id' : gridIn.id.toHexString()};
}
If you prefer you can send the file through Dart code and avoid page reload. The easiest get it to work with Redstone is to send the whole FormElement
. You'll probably use querySelector
to get the <form>
element and subscribe to an event. Whatever your method, you can send it to your Redstone server like this
FormElement form = YOUR_FORM_ELEMENT;
String path = "upload";
HttpRequest.request (path,
method: "POST",
sendData: new FormData (form)).then ((HttpRequest req)
{
//Handle request here
});
//TODO: Add comments and explanations
@app.Route("/getfile/:fileID")
getFile(@app.Attr() MongoDb dbConn, String fileID) async
{
GridFS gridFS = new GridFS (dbConn.innerConn);
ObjectId objID = new ObjectId.fromHexString (fileID);
GridOut gridOut = await gridFS.findOne (where.id(objID));
//Get data
var stream = getData (gridOut);
// You'll have to set the content-type of the file
return new shelf.Response.ok(stream, headers: { "Content-Type": gridOut.contentType });
});
}
Where getData
is
Stream<List<int>> getData (GridOut gridOut)
{
StreamController<List<int>> controller = new StreamController<List<int>>();
var n = 0;
gridOut.fs.chunks.find(where.eq("files_id", gridOut.id).sortBy('n'))
.forEach((Map chunk)
{
BsonBinary data = chunk["data"];
controller.add (data.byteList);
n++;
})
.then((_)
{
print ("$n Chunks!");
controller.close();
});
return controller.stream;
}
-
Quick Start Guide
-
Reference
-
Serialization
-
Databases
-
MVC
-
Web Sockets