diff options
author | David Robillard <d@drobilla.net> | 2018-05-12 13:28:47 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-05-27 21:10:20 +0200 |
commit | 582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a (patch) | |
tree | b866ca44592cc07a34fcad8ce18c29259fb39199 /serd | |
parent | f48dac14b6533b4cdd4804513216f4f11de36d9a (diff) | |
download | serd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.tar.gz serd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.tar.bz2 serd-582bfbe1cb0a6aa833f56c5bd8cf42abe5c5d13a.zip |
WIP: Add model
Diffstat (limited to 'serd')
-rw-r--r-- | serd/serd.h | 320 |
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); + +/** + @} @} */ |