/* Copyright 2011 David Robillard Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** @file sord.h API for Sord, a lightweight RDF model library. */ #ifndef SORD_SORD_H #define SORD_SORD_H #include #include #include #include #include "serd/serd.h" #ifdef SORD_SHARED # ifdef __WIN32__ # define SORD_LIB_IMPORT __declspec(dllimport) # define SORD_LIB_EXPORT __declspec(dllexport) # else # define SORD_LIB_IMPORT __attribute__((visibility("default"))) # define SORD_LIB_EXPORT __attribute__((visibility("default"))) # endif # ifdef SORD_INTERNAL # define SORD_API SORD_LIB_EXPORT # else # define SORD_API SORD_LIB_IMPORT # endif #else # define SORD_API #endif #ifdef __cplusplus extern "C" { #endif /** @defgroup sord Sord A lightweight RDF model library. Sord stores RDF (subject object predicate context) quads, where the context may be omitted (to represent triples in the default graph). @{ */ /** Sord World. The World represents all library state, including interned strings. */ typedef struct _SordWorld* SordWorld; /** Sord Model. A model is an indexed set of Quads (i.e. it can contain several RDF graphs). It may be searched using various patterns depending on which indices are enabled. */ typedef struct _SordModel* SordModel; /** Model Iterator. */ typedef struct _SordIter* SordIter; /** RDF Node. A Node is a component of a Quad. Nodes may be URIs, blank nodes, or (in the case of quad objects only) string literals. Literal nodes may have an associate language or datatype (but not both). */ typedef struct _SordNode* SordNode; /** Quad of IDs (statement), or a quad pattern. Nodes are ordered (S P O G). The ID of the default graph is 0. */ typedef SordNode SordQuad[4]; /** Index into a SordQuad. */ typedef enum { SORD_SUBJECT = 0, /**< Subject */ SORD_PREDICATE = 1, /**< Predicate (a.k.a. "key") */ SORD_OBJECT = 2, /**< Object (a.k.a. "value") */ SORD_GRAPH = 3 /**< Graph (a.k.a. "context") */ } SordQuadIndex; /** Type of a node. */ typedef enum { SORD_URI = 1, /**< URI */ SORD_BLANK = 2, /**< Blank node identifier */ SORD_LITERAL = 3 /**< Literal (string with optional lang or datatype) */ } SordNodeType; /** Indexing option. */ typedef enum { SORD_SPO = 1, /**< Subject, Predicate, Object */ SORD_SOP = 1 << 1, /**< Subject, Object, Predicate */ SORD_OPS = 1 << 2, /**< Object, Predicate, Subject */ SORD_OSP = 1 << 3, /**< Object, Subject, Predicate */ SORD_PSO = 1 << 4, /**< Predicate, Subject, Object */ SORD_POS = 1 << 5 /**< Predicate, Object, Subject */ } SordIndexOption; /** @name World @{ */ /** Create a new Sord World. It is safe to use multiple worlds in one process, though no data (e.g. nodes) can be shared between worlds, and this should be avoided if possible for performance reasons. */ SORD_API SordWorld sord_world_new(void); /** Free @c world. */ SORD_API void sord_world_free(SordWorld world); /** @} @name Node @{ */ /** Find a URI, creating a new one if necessary iff @c create is true. Use sord_get_uri_counted instead if the length of @c str is known. */ SORD_API SordNode sord_new_uri(SordWorld world, const uint8_t* str); /** Find a URI, creating a new one if necessary iff @c create is true. */ SORD_API SordNode sord_new_uri_counted(SordWorld world, const uint8_t* str, size_t str_len); /** Find a blank, creating a new one if necessary iff @c create is true. Use sord_get_blank_counted instead if the length of @c str is known. */ SORD_API SordNode sord_new_blank(SordWorld world, const uint8_t* str); /** Find a blank, creating a new one if necessary iff @c create is true. */ SORD_API SordNode sord_new_blank_counted(SordWorld world, const uint8_t* str, size_t str_len); /** Find a literal, creating a new one if necessary iff @c create is true. Use sord_get_literal_counted instead if the length of @c str is known. */ SORD_API SordNode sord_new_literal(SordWorld world, SordNode datatype, const uint8_t* str, const char* lang); /** Find a literal, creating a new one if necessary iff @c create is true. */ SORD_API SordNode sord_new_literal_counted(SordWorld world, SordNode datatype, const uint8_t* str, size_t str_len, const char* lang, uint8_t lang_len); /** Copy a node. */ SORD_API SordNode sord_node_copy(SordNode node); /** Free a node. */ SORD_API void sord_node_free(SordWorld world, SordNode node); /** Return the type of a node (SORD_URI, SORD_BLANK, or SORD_LITERAL). */ SORD_API SordNodeType sord_node_get_type(SordNode node); /** Return the string value of a node. */ SORD_API const uint8_t* sord_node_get_string(SordNode node); /** Return the string value of a node, and set @c len to its length. */ SORD_API const uint8_t* sord_node_get_string_counted(SordNode node, size_t* len); /** Return the language of a literal node (or NULL). */ SORD_API const char* sord_node_get_language(SordNode node); /** Return the datatype URI of a literal node (or NULL). */ SORD_API SordNode sord_node_get_datatype(SordNode node); /** Return true iff @c a is equal to @c b. Note this is much faster than comparing the node's strings. */ SORD_API bool sord_node_equals(const SordNode a, const SordNode b); /** @} @name Model @{ */ /** Create a new store. @param world The world in which to make this store. @param indices SordIndexOption flags (e.g. SORD_SPO|SORD_OPS). Be sure to enable an index where the most significant node(s) are not variables in your queries (e.g. to make (? P O) queries, enable either SORD_OPS or SORD_POS). @param graphs If true, store (and index) graph contexts. */ SORD_API SordModel sord_new(SordWorld world, unsigned indices, bool graphs); /** Close and free @c sord. */ SORD_API void sord_free(SordModel model); /** Get the world associated with @c model. */ SORD_API SordWorld sord_get_world(SordModel model); /** Return the number of nodes stored in @c sord. Nodes are included in this count iff they are a part of a quad in @c sord. */ SORD_API int sord_num_nodes(SordWorld world); /** Return the number of quads stored in @c sord. */ SORD_API int sord_num_quads(SordModel model); /** Return an iterator to the start of the store. */ SORD_API SordIter sord_begin(SordModel model); /** Return an iterator that will iterate over each graph URI. */ SORD_API SordIter sord_graphs_begin(SordModel model); /** Search for a triple pattern. @return an iterator to the first match, or NULL if no matches found. */ SORD_API SordIter sord_find(SordModel model, const SordQuad pat); /** Add a quad to the store. */ SORD_API bool sord_add(SordModel model, const SordQuad quad); /** Remove a quad from the store. Note that is it illegal to remove while iterator over @c model. */ SORD_API void sord_remove(SordModel model, const SordQuad quad); /** @} @name Iteration @{ */ /** Set @c id to the quad pointed to by @c iter. */ SORD_API void sord_iter_get(SordIter iter, SordQuad quad); /** Return the store pointed to by @c iter. */ SORD_API SordModel sord_iter_get_model(SordIter iter); /** Increment @c iter to point to the next statement. */ SORD_API bool sord_iter_next(SordIter iter); /** Return true iff @c iter is at the end of its range. */ SORD_API bool sord_iter_end(SordIter iter); /** Free @c iter. */ SORD_API void sord_iter_free(SordIter iter); /** @} @name Utilities @{ */ /** Match two quads (using ID comparison only). This function is a straightforward and fast equivalence match with wildcard support (ID 0 is a wildcard). It does not actually read node data. @return true iff @c x and @c y match. */ SORD_API bool sord_quad_match(const SordQuad x, const SordQuad y); /** @} @name Serialisation @{ */ SORD_API bool sord_read_file(SordModel model, const uint8_t* uri, const SordNode graph, const uint8_t* blank_prefix); SORD_API bool sord_read_file_handle(SordModel model, FILE* fd, const uint8_t* base_uri, const SordNode graph, const uint8_t* blank_prefix); SORD_API bool sord_read_string(SordModel model, const uint8_t* str, const uint8_t* base_uri); SORD_API bool sord_write_file(SordModel model, SerdEnv* env, const uint8_t* uri, const SordNode graph, const uint8_t* blank_prefix); SORD_API bool sord_write_file_handle(SordModel model, SerdEnv* env, FILE* fd, const uint8_t* base_uri, const SordNode graph, const uint8_t* blank_prefix); SORD_API uint8_t* sord_write_string(SordModel model, SerdEnv* env, const uint8_t* base_uri); /** @} @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* SORD_SORD_H */