Hi Michael, This looks interesting. I didn't have time to look at the code yet, so I'm just answering/commenting on your questions.
Michael Zach (TNXLabs) wrote: > Hi, I am answering my own Qs here: > > Q1: well, my implementation is working fine. Its getting the best of both > worlds, storing everything in the db or letting the binary part of > attachments go into a regular file, depending on a global/space preference > set. Well, this is the right approach. Even better than what we had in mind initially, as you allow mixed fs/db storage for each space. > I am using the HibernateAttachmentStore and extend it as > HibernatePlusFileAttachmentStore. > Before I save/update the XWikiAttachmentContent, I check if there is a > preference called "HibernatePlusFileAttachmentStore" set for the current > space or the whole wiki. It contains the path to a folder to store the > binary part of the attachments in. If this pref exists, I stream the byte[] > into a file, which gets a > ".[$docId_asHex;$timestamp_asHex;$attachment_version]" inserted before the > file extension into its filename to make it unique. then I replace the > binary content of the XWikiAttachmentContent with a "file:"+path_to_file > String. > When reading an attachment, its viceversa: looking into the > XWikiAttachmentContent blob if it starts with "file:". if it does, I read > the filepath in and then fill the byte[] with the file's content. otherwise > I just handle on the blop from the db as usual. This is a security issue, as someone can disable FS storage in a space and upload a file containing file:/etc/passwd and gain access to a protected file (not sure /etc/passwd works, but you get the idea). You should also check the storage preference. Another problem is deleting the old file when uploading a new version; if you want the archives to be stored on the filesystem, too, you should also change the AttachmentArchive storage; if you don't want that, then make sure you remove the previous file when storing a new version. > This way everything is working fine and I can enable the filesystem storage > on a global and per space basis. And best of all I can start with it with an > existing wiki as well, as it just works even if there are already > attachments stored in the db. > > If you are interested: > source: > http://www.tnxlabs.com/download/xwiki/HibernatePlusFileAttachmentStore.java > binary: > http://www.tnxlabs.com/download/xwiki/xwiki-core-hibernateplusfile-1.0.jar > > Just put the jar into your xwiki/WEB-INF/lib > and in your xwiki.cfg set the property > xwiki.store.attachment.class=com.xpn.xwiki.store.hibernateplusfile.HibernatePlusFileAttachmentStore > > Then after restarting xwiki everything still works as usual until you insert > an object of class called "HibernatePlusFileAttachmentStore" into the > global/space preferences of your xwiki. > If it contains the path to a folder, this will be used to store attachments > from now on. > If it contains nothing, "0", "null" or "disabled" then the filesystem > storage will be turned off for this area and any new attachments go into the > db. > > You are wlecome to experiment with this solution and give me feedback! Any > interest to put it into the official sourcetree? Yes, after someone will review the code. > I will come up with a few macros and tools to tidy up the filesystem > storage, move it and migrate between db and filesystem. > > > Q2: > String space = attachment.getDoc().getSpace(); > String spacePreference = context.getWiki().getWebPreference("somePref", > space, null, context); > String globalPreference = context.getWiki().getXWikiPreference("somePref", > null, context); > > Q3: > implementing the XWikiAttachmentStoreInterface seems enough If the goal was to have access to the files from the filesystem, then yes. But if the goal was to reduce the DB size, then you should also update the versioning and recycle bin attachment stores. > Q4: I found none. Then this is a bad design... Our fault here. > Q5: context.getWiki().flushCache() will flush = clear the cache Yes, but this is bad for the performance. > > Michael Zach (TNXLabs) wrote: >> Hello all, >> >> I have been looking for a way to store attachments (the binary 'content' >> data only) as regular files on the servers filesystem. I already read >> through the archives and found out so far that this is possible via >> writing my own implementation of the >> com.xpn.xwiki.store.XWikiAttachmentStoreInterface and then set have them >> used via settings in xwiki.cfg. (see this thread in the markmail archives: >> http://markmail.org/message/zyd2tpfj2x45hyxt ) >> >> What I do is just taking out the XWikiAttachmentContent content property's >> byte[], stream it into a file and replace the property value with the path >> to this file. so I need no changes to the hibernate mappings etc. ... and >> when reading it in, doing a file read accordingly ... >> So I store everything as usual with Hibernate, just the pure content is >> stored as file (with an unique id embedded in the filename) >> >> Q1) ... any better idea? (its working fine so far ;o) >> >> Q2) I am looking for a way to set the store implementations on a per-space >> basis. >> Or: How can the store implementation see to which space the attachment's >> parent page belongs and read in any config (string) for this space? >> >> Q3) Any other Interfaces I should provide a filesystem based implemention >> for? So far it seems I dont need to make any changes to the Recyclebin and >> Versioning store implementations. >> >> Q4) Is there a way to turn off caching for attachments only? I turned off >> caching totally with >> xwiki.store.cache=0 >> xwiki.store.cache.capacity=0 >> and this is a performance nightmare. But I need to turn off only the >> caching of attachments. Is this possible? >> >> Thank you in advance for any bit of input ;o) >> >> Michael >> >> > -- Sergiu Dumitriu http://purl.org/net/sergiu/ _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs

