{"action":"opened","issue":{"url":"https://api.github.com/repos/doctrine/mongodb-odm/issues/1697","repository_url":"https://api.github.com/repos/doctrine/mongodb-odm","labels_url":"https://api.github.com/repos/doctrine/mongodb-odm/issues/1697/labels{/name}","comments_url":"https://api.github.com/repos/doctrine/mongodb-odm/issues/1697/comments","events_url":"https://api.github.com/repos/doctrine/mongodb-odm/issues/1697/events","html_url":"https://github.com/doctrine/mongodb-odm/issues/1697","id":283780593,"number":1697,"title":"[2.0] Re-implement GridFS","user":{"login":"alcaeus","id":383198,"avatar_url":"https://avatars2.githubusercontent.com/u/383198?v=4","gravatar_id":"","url":"https://api.github.com/users/alcaeus","html_url":"https://github.com/alcaeus","followers_url":"https://api.github.com/users/alcaeus/followers","following_url":"https://api.github.com/users/alcaeus/following{/other_user}","gists_url":"https://api.github.com/users/alcaeus/gists{/gist_id}","starred_url":"https://api.github.com/users/alcaeus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alcaeus/subscriptions","organizations_url":"https://api.github.com/users/alcaeus/orgs","repos_url":"https://api.github.com/users/alcaeus/repos","events_url":"https://api.github.com/users/alcaeus/events{/privacy}","received_events_url":"https://api.github.com/users/alcaeus/received_events","type":"User","site_admin":false},"labels":[{"id":62678352,"url":"https://api.github.com/repos/doctrine/mongodb-odm/labels/documentation","name":"documentation","color":"bfe5bf","default":false},{"id":29991996,"url":"https://api.github.com/repos/doctrine/mongodb-odm/labels/feature","name":"feature","color":"009800","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/doctrine/mongodb-odm/milestones/4","html_url":"https://github.com/doctrine/mongodb-odm/milestone/4","labels_url":"https://api.github.com/repos/doctrine/mongodb-odm/milestones/4/labels","id":646188,"number":4,"title":"2.0.0","description":"","creator":{"login":"jmikola","id":244663,"avatar_url":"https://avatars3.githubusercontent.com/u/244663?v=4","gravatar_id":"","url":"https://api.github.com/users/jmikola","html_url":"https://github.com/jmikola","followers_url":"https://api.github.com/users/jmikola/followers","following_url":"https://api.github.com/users/jmikola/following{/other_user}","gists_url":"https://api.github.com/users/jmikola/gists{/gist_id}","starred_url":"https://api.github.com/users/jmikola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmikola/subscriptions","organizations_url":"https://api.github.com/users/jmikola/orgs","repos_url":"https://api.github.com/users/jmikola/repos","events_url":"https://api.github.com/users/jmikola/events{/privacy}","received_events_url":"https://api.github.com/users/jmikola/received_events","type":"User","site_admin":false},"open_issues":26,"closed_issues":13,"state":"open","created_at":"2014-05-01T16:04:48Z","updated_at":"2017-12-21T05:57:47Z","due_on":null,"closed_at":null},"comments":0,"created_at":"2017-12-21T05:57:47Z","updated_at":"2017-12-21T05:57:47Z","closed_at":null,"author_association":"MEMBER","body":"GridFS has been removed from 2.0.x-dev to limit the complexity of the switch to `ext-mongodb`. GridFS support needs to be readded for 2.0.\r\n\r\nHere are the notes from previous hangouts collecting ideas for a new implementation of GridFS support:\r\n\r\n## Mapping:\r\n\r\n```\r\n/**\r\n * @ODM\\File(bucketName=””, chunkSizeBytes=””, readConcern=””)\r\n * @ODM\\WriteConcern() - optional\r\n * @ODM\\ReadPreference() - optional\r\n */\r\nprivate $file;\r\n```\r\n\r\nODM will no longer inject additional properties like md5 or uploadDate to an owning document  - thanks to this we’ll enable having more than one @ODM\\File annotated field in a document.\r\n\r\nA field mapped as File can accept several types. From user perspective, they can assign a string or stream to the field for ODM to transform it during persist (similar to collections that are array  - they are transformed to a persistent collection). When the data is hydrated (or said transformation happens) ODM will use specialized class that wraps MongoDB\\GridFS\\Bucket, limiting its original API to what is needed to interact with particular file and exposing access to properties like MD5 hash, chunkFileSize et al. Effectively the class will look similar to:\r\n\r\n```\r\nclass GridFSFile\r\n{\r\n    public function __construct(Bucket $bucket, ObjectId $id, array $options);\r\n\r\n    public function downloadToStream();\r\n\r\n    public function openDownloadStream();\r\n\r\n    public function getMD5Hash();\r\n\r\n    // other getters for file’s metadata\r\n}\r\n```\r\n\r\nWhether we want to expose methods like delete or rename is subject to a discussion, best would be to base it on real life usages which, unfortunately, are not known to me. Removing a file could also happen any time user changes value of a field mapped as File, controlled by a mapping property.\r\n\r\n**UPDATE**: Actually we might provide another implementation of said GridFSFile that would accept a string or a stream. This way end-user could rely on an (internal) interface and storage would be transparent to him:\r\n\r\n```\r\nclass NotPersistedFile implements File\r\n{\r\n    private function __construct();\r\n\r\n    public static function fromPath($path);\r\n\r\n    public static function fromStream();\r\n\r\n    // other methods from the interface (thus GridFSFile)\r\n}\r\n```\r\n\r\n## Issues with current GridFS implementation\r\n* Files are mutable - we should no longer allow changing the contents of a file document and instead treat them as write-once.\r\n* It’s possible to store data in the root document in fs.files - this is not supported by the new driver and needs to go\r\n* Mapping a single property as file feels wrong, the whole document is the “file”. What is mapped with `@File` is merely a placeholder for whatever currently holds the data (e.g. a string containing a path)\r\n* The “pass a string, get an object” mechanism of the file property leads to an inconsistent API. Instead, users should be able to construct the file object themselves to have a clean API. See https://gist.github.com/alcaeus/4114209a272c869c45cf7b6ed176ec06 for a sample implementation around that problem\r\n* The fields stored by MongoDB (e.g. length, md5, etc.) need to be mapped separately - this should not be necessary. Standardizing the documents involved in GridFS would solve that problem\r\n* The fields mentioned above are not filled automatically after a flush operation, instead the document needs to be refreshed once\r\n\r\n## Wish list for ODM 2.0 GridFS API\r\n* By default, don’t allow arbitrary fields in the fs.files document to be mapped\r\n* Consider allowing a legacyMode (or similarly named) flag to allow other fields to be mapped (preferably with NotSaved)\r\n* Reserved fields for in the fs.files document should be NotSaved (e.g. length, md5, filename)\r\n* Use an interface and corresponding trait for the fs.files document\r\n* The top-level fs.files document can be mapped with a GridFSDocument or FileDocument annotation.\r\nBehaviorally, it is a subset of the generic Document type\r\n* Allow a custom class to be specified as the EmbedOne targetDocument for the “metadata” property\r\n* When you first create a GridFS file from a readable stream, we return a proxy for the fs.files document\r\n* Thereafter, the fs.files document class does not allow the stream to be modified\r\n* WriteConcern and ReadPreference are top-level document mappings. Hopefully we also add ReadConcern.\r\n"}}
{"actor":{"display_login":"alcaeus"}}