<div><br></div><div>Hi,</div><div><br></div><div>when contexts are used, you'll need to implement the corresponding context callbacks.</div><div><br></div><div>First, your get_feature() needs to return a non-zero literal e.g. "1" for LIBRDF_MODEL_FEATURE_CONTEXTS URI to enable contexts support i.e. librdf_model_supports_contexts() to return true.</div>
<div><br></div><div>Then, find_statements_in_context() is essential for good performance queries --- the fallback is to do linear searches on context_serialize() results.</div><div><br></div><div>Lauri</div><br><br><div class="gmail_quote">
On Tue, Jul 2, 2013 at 10:10 AM, Andrew Reslan <span dir="ltr"><<a href="mailto:andrew.reslan@mac.com" target="_blank">andrew.reslan@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">Lauri<div><br></div><div>Hi, I would like to thank you for your help and report that I have been running with my custom storage in test for a four weeks now and after a few minor bug fixes it has been running without issues.</div>
<div><br></div><div>I would now like to support named graphs via the SPARQL query interface, I am assuming that these map to contexts at the storage layer, I can't quite figure out how to support these properly, I have implemented the get-contexts callback, but I must need to support contexts in the find_statements somehow?</div>
<div><br></div><div>Any input appreciated.</div><div><br></div><div>Andy</div><div><div class="h5"><div><br></div><div><br></div><div><div><div>On 6 May 2013, at 07:50, Lauri Aalto <<a href="mailto:laalto@gmail.com" target="_blank">laalto@gmail.com</a>> wrote:</div>
<br><blockquote type="cite"><div><br></div><div>Hi Andrew,</div><div><br></div><div>as you probably already have figured out, writing a custom librdf storage module is really about writing some function callbacks declared in rdf_storage_module.h.</div>
<div><br></div><div>When I wrote my first custom rdf_storage module, I used rdf_storage_sqlite.c as a reference. Eventually everything was written from scratch. You're probably fine using any of the rdf_storage_*.c as reference.</div>
<div><br></div><div>Registering the new storage is straghtforward with</div><div><br></div><div> REDLAND_API</div><div> int librdf_storage_register_factory(librdf_world *world, const char *name, const char *label, void (*factory) (librdf_storage_factory*));</div>
<div><br></div><div>where factory is your function callback that populates librdf_storage_factory with supported functions' pointers. After this, calling librdf_new_storage() with your storage_name calls your init() callback to create a new storage instance.</div>
<div><br></div><div>(It's also possible to load storage modules dynamically if librdf is built without --disable-modular. See code flagged with LIBRDF_MODULAR for more information. The static registration mentioned above is simpler to get started with.)</div>
<div><br></div><div>For unsupported functions, just leave the corresponding function pointer in librdf_storage_factory NULL and librdf itself will, in most cases, either return an appropriate error code or obtain the results with other, possibly less optimized callbacks, e.g. get_arcs_in() using find_statements().</div>
<div><br></div><div>A read-only query-only storage strictly only needs the lifecycle functions:</div><div><br></div><div> init()</div><div> terminate()</div><div> open()</div><div> close()</div><div><br></div>
<div>and the query function</div><div><br></div><div> find_statements().</div><div><br></div><div>But to avoid segfaults for unsupported functions where librdf indirects using the function pointer without checking for non-NULL, you also need:</div>
<div><br></div><div> size() - return negative for unsupported</div><div> contains_statement() - can use find_statements() and check for non-empty stream</div><div> serialise() - can use find_statements() with all statement parts empty</div>
<div><br></div><div><br></div><div>Lauri</div><div><br></div><div class="gmail_quote">On Sun, May 5, 2013 at 10:24 PM, Andrew Reslan <span dir="ltr"><<a href="mailto:andrew.reslan@mac.com" target="_blank">andrew.reslan@mac.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I want to integrate a new storage implementation.<br>
<br>
This will be a readonly store, data will be side loaded (initially), access to the data would be via a query API on the storage layer, data persistence/read/write details will be handled by the underlying storage framework.<br>
<br>
Which of the existing storage implementations would provide the simplest template as a starting point for integration?<br>
<br>
It would also be really useful to know which operations to implement for a query only store and the best way to implement "unsupported" operations so that clients fail gracefully if they try to write to the store.<br>
<br>
It looks like I will need to register the new implementation with the framework, what is the mechanism for doing this?<br>
<br>
Any pointers appreciated.<br>
_______________________________________________<br>
redland-dev mailing list<br>
<a href="mailto:redland-dev@lists.librdf.org" target="_blank">redland-dev@lists.librdf.org</a><br>
<a href="http://lists.librdf.org/mailman/listinfo/redland-dev" target="_blank">http://lists.librdf.org/mailman/listinfo/redland-dev</a><br>
</blockquote></div><br>
</blockquote></div><br></div></div></div></div></blockquote></div><br>