aboutsummaryrefslogtreecommitdiffstats
path: root/serd
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-12 13:28:47 +0200
committerDavid Robillard <d@drobilla.net>2018-05-27 21:10:20 +0200
commit582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a (patch)
treeb866ca44592cc07a34fcad8ce18c29259fb39199 /serd
parentf48dac14b6533b4cdd4804513216f4f11de36d9a (diff)
downloadserd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.tar.gz
serd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.tar.bz2
serd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.zip
WIP: Add model
Diffstat (limited to 'serd')
-rw-r--r--serd/serd.h320
1 files changed, 320 insertions, 0 deletions
diff --git a/serd/serd.h b/serd/serd.h
index f148acb4..e7b47693 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -63,6 +63,33 @@ extern "C" {
typedef struct SerdWorldImpl SerdWorld;
/**
+ Model.
+
+ A model is an indexed set of statements. It may be searched using various
+ patterns depending on which indices are enabled.
+*/
+typedef struct SerdModelImpl SerdModel;
+
+/**
+ Model Inserter.
+
+ An inserter is used for writing statements to a model using the Serd sink
+ interface. This makes it simple to write to a model directly using a
+ SerdReader, or any other code that writes statements to a SerdStatementSink.
+*/
+typedef struct SerdInserterImpl SerdInserter;
+
+/**
+ Model Iterator.
+*/
+typedef struct SerdIterImpl SerdIter;
+
+/**
+ Statement.
+*/
+typedef struct SerdStatementImpl SerdStatement;
+
+/**
Environment.
Represents the state required to resolve a CURIE or relative URI, e.g. the
@@ -97,6 +124,7 @@ typedef enum {
SERD_ERR_UNKNOWN, /**< Unknown error */
SERD_ERR_BAD_SYNTAX, /**< Invalid syntax */
SERD_ERR_BAD_ARG, /**< Invalid argument */
+ SERD_ERR_BAD_ITER, /**< Use of invalidated iterator */
SERD_ERR_NOT_FOUND, /**< Not found */
SERD_ERR_ID_CLASH, /**< Encountered clashing blank node IDs */
SERD_ERR_BAD_CURIE, /**< Invalid CURIE (e.g. prefix does not exist) */
@@ -216,6 +244,40 @@ typedef enum {
} SerdNodeFlag;
/**
+ Field in a statement.
+*/
+typedef enum {
+ SERD_SUBJECT = 0, /**< Subject */
+ SERD_PREDICATE = 1, /**< Predicate ("key") */
+ SERD_OBJECT = 2, /**< Object ("value") */
+ SERD_GRAPH = 3 /**< Graph ("context") */
+} SerdField;
+
+/**
+ Flags for model features.
+*/
+typedef enum {
+ SERD_MODEL_GRAPHS = 1 /**< Support multiple graphs in model. */
+} SerdModelFlag;
+
+/**
+ Bitwise OR of SerdModelFlag values.
+*/
+typedef uint32_t SerdModelFlags;
+
+/**
+ Indexing option.
+*/
+typedef enum {
+ SERD_SPO = 1, /**< Subject, Predicate, Object */
+ SERD_SOP = 1 << 1, /**< Subject, Object, Predicate */
+ SERD_OPS = 1 << 2, /**< Object, Predicate, Subject */
+ SERD_OSP = 1 << 3, /**< Object, Subject, Predicate */
+ SERD_PSO = 1 << 4, /**< Predicate, Subject, Object */
+ SERD_POS = 1 << 5 /**< Predicate, Object, Subject */
+} SerdIndexOption;
+
+/**
Bitwise OR of SerdNodeFlag values.
*/
typedef uint32_t SerdNodeFlags;
@@ -1098,6 +1160,264 @@ serd_writer_finish(SerdWriter* writer);
/**
@}
+ @name Model
+ @{
+*/
+
+/**
+ Create a new model.
+
+ @param world The world in which to make this model.
+
+ @param indices SerdIndexOption flags (e.g. SERD_SPO|SERD_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 SERD_OPS or SERD_POS).
+
+ @param flags Model options.
+*/
+SERD_API
+SerdModel*
+serd_model_new(SerdWorld* world, unsigned indices, SerdModelFlags flags);
+
+/**
+ Close and free `model`.
+*/
+SERD_API
+void
+serd_model_free(SerdModel* model);
+
+/**
+ Get the world associated with `model`.
+*/
+SERD_API
+SerdWorld*
+serd_model_get_world(SerdModel* model);
+
+/**
+ Return the number of quads stored in `model`.
+*/
+SERD_API
+size_t
+serd_model_num_quads(const SerdModel* model);
+
+/**
+ Return an iterator to the start of `model`.
+*/
+SERD_API
+SerdIter*
+serd_model_begin(const SerdModel* model);
+
+/**
+ Search for statements by a quad pattern.
+ @return an iterator to the first match, or NULL if no matches found.
+*/
+SERD_API
+SerdIter*
+serd_model_find(SerdModel* model,
+ const SerdNode* s,
+ const SerdNode* p,
+ const SerdNode* o,
+ const SerdNode* g);
+
+/**
+ Search for a single node that matches a pattern.
+ Exactly one of `s`, `p`, `o` must be NULL.
+ This function is mainly useful for predicates that only have one value.
+ The returned node must be freed using serd_node_free().
+ @return the first matching node, or NULL if no matches are found.
+*/
+SERD_API
+const SerdNode*
+serd_model_get(SerdModel* model,
+ const SerdNode* s,
+ const SerdNode* p,
+ const SerdNode* o,
+ const SerdNode* g);
+
+/**
+ Return true iff a statement exists.
+*/
+SERD_API
+bool
+serd_model_ask(SerdModel* model,
+ const SerdNode* s,
+ const SerdNode* p,
+ const SerdNode* o,
+ const SerdNode* g);
+
+/**
+ Return the number of matching statements.
+*/
+SERD_API
+size_t
+serd_model_count(SerdModel* model,
+ const SerdNode* s,
+ const SerdNode* p,
+ const SerdNode* o,
+ const SerdNode* g);
+
+/**
+ Add a statement to a model from nodes.
+
+ This function fails if there are any active iterators on `model`.
+*/
+SERD_API
+SerdStatus
+serd_model_add(SerdModel* model,
+ const SerdNode* s,
+ const SerdNode* p,
+ const SerdNode* o,
+ const SerdNode* g);
+
+/**
+ Add a statement to a model.
+
+ This function fails if there are any active iterators on `model`.
+*/
+SERD_API
+SerdStatus
+serd_model_add_statement(SerdModel* model, const SerdStatement* statement);
+
+/**
+ Remove a quad from a model via an iterator.
+
+ Calling this function invalidates all iterators on `model` except `iter`.
+
+ @param model The model which `iter` points to.
+ @param iter Iterator to the element to erase, which is incremented to the
+ next value on return.
+*/
+SERD_API
+SerdStatus
+serd_model_erase(SerdModel* model, SerdIter* iter);
+
+/**
+ @}
+ @name Inserter
+ @{
+*/
+
+/**
+ Create an inserter for writing statements to a model.
+*/
+SERD_API
+SerdInserter*
+serd_inserter_new(SerdModel* model,
+ SerdEnv* env,
+ const SerdNode* default_graph);
+
+/**
+ Free an inserter.
+*/
+SERD_API
+void
+serd_inserter_free(SerdInserter* inserter);
+
+/**
+ Return a sink interface that adds statements via `inserter`.
+*/
+SERD_API
+const SerdSinkInterface*
+serd_inserter_get_sink_interface(SerdInserter* inserter);
+
+/**
+ @}
+ @name Statement
+ @{
+*/
+
+/**
+ Return the given node in `statement`.
+*/
+SERD_API
+const SerdNode*
+serd_statement_get_node(const SerdStatement* statement, SerdField field);
+
+/**
+ Return the subject in `statement`.
+*/
+SERD_API
+const SerdNode*
+serd_statement_get_subject(const SerdStatement* statement);
+
+/**
+ Return the predicate in `statement`.
+*/
+SERD_API
+const SerdNode*
+serd_statement_get_predicate(const SerdStatement* statement);
+
+/**
+ Return the object in `statement`.
+*/
+SERD_API
+const SerdNode*
+serd_statement_get_object(const SerdStatement* statement);
+
+/**
+ Return the graph in `statement`.
+*/
+SERD_API
+const SerdNode*
+serd_statement_get_graph(const SerdStatement* statement);
+
+/**
+ Return true iff `statement` matches the given pattern.
+
+ The matching rules are the same used for querying: nodes match if they are
+ equivalent, and NULL acts as a wildcard that matches any node.
+*/
+SERD_API
+bool
+serd_statement_matches(const SerdStatement* statement,
+ const SerdNode* subject,
+ const SerdNode* predicate,
+ const SerdNode* object,
+ const SerdNode* graph);
+
+/**
+ @}
+ @name Iteration
+ @{
+*/
+
+/**
+ Return the statement pointed to by `iter`.
+*/
+SERD_API
+const SerdStatement*
+serd_iter_get(const SerdIter* iter);
+
+/**
+ Return the store pointed to by `iter`.
+*/
+SERD_API
+const SerdModel*
+serd_iter_get_model(const SerdIter* iter);
+
+/**
+ Increment `iter` to point to the next statement.
+*/
+SERD_API
+bool
+serd_iter_next(SerdIter* iter);
+
+/**
+ Return true iff `iter` is at the end of its range.
+*/
+SERD_API
+bool
+serd_iter_end(const SerdIter* iter);
+
+/**
+ Free `iter`.
+*/
+SERD_API
+void
+serd_iter_free(SerdIter* iter);
+
+/**
+ @}
@}
*/