Exemplo n.º 1
0
void
sord_free(SordModel* sord)
{
	if (!sord)
		return;

	// Free nodes
	SordQuad tup;
	SordIter* i = sord_begin(sord);
	for (; !sord_iter_end(i); sord_iter_next(i)) {
		sord_iter_get(i, tup);
		for (int t = 0; t < TUP_LEN; ++t) {
			sord_drop_quad_ref(sord, tup[t], (SordQuadIndex)t);
		}
	}
	sord_iter_free(i);

	// Free quads
	ZixBTreeIter* t = zix_btree_begin(sord->indices[DEFAULT_ORDER]);
	for (; !zix_btree_iter_is_end(t); zix_btree_iter_increment(t)) {
		free(zix_btree_get(t));
	}
	zix_btree_iter_free(t);

	// Free indices
	for (unsigned o = 0; o < NUM_ORDERS; ++o)
		if (sord->indices[o])
			zix_btree_free(sord->indices[o]);

	free(sord);
}
Exemplo n.º 2
0
SordIter*
sord_find(SordModel* sord, const SordQuad pat)
{
	if (!pat[0] && !pat[1] && !pat[2] && !pat[3])
		return sord_begin(sord);

	SearchMode      mode;
	int             n_prefix;
	const SordOrder index_order = sord_best_index(sord, pat, &mode, &n_prefix);

	SORD_FIND_LOG("Find " TUP_FMT "  index=%s  mode=%d  n_prefix=%d\n",
	              TUP_FMT_ARGS(pat), order_names[index_order], mode, n_prefix);

	if (pat[0] && pat[1] && pat[2] && pat[3])
		mode = SINGLE;  // No duplicate quads (Sord is a set)

	ZixBTree* const db  = sord->indices[index_order];
	ZixBTreeIter*   cur = NULL;
	zix_btree_lower_bound(db, pat, &cur);
	if (zix_btree_iter_is_end(cur)) {
		SORD_FIND_LOG("No match found\n");
		zix_btree_iter_free(cur);
		return NULL;
	}
	const SordNode** const key = (const SordNode**)zix_btree_get(cur);
	if (!key || ( (mode == RANGE || mode == SINGLE)
	              && !sord_quad_match_inline(pat, key) )) {
		SORD_FIND_LOG("No match found\n");
		zix_btree_iter_free(cur);
		return NULL;
	}

	return sord_iter_new(sord, cur, pat, index_order, mode, n_prefix);
}
Exemplo n.º 3
0
static int
check_properties(SordModel* model, URIs* uris)
{
	int       st = 0;
	SordIter* i  = sord_begin(model);
	for (; !sord_iter_end(i); sord_iter_next(i)) {
		SordQuad quad;
		sord_iter_get(i, quad);

		const SordNode* subj = quad[SORD_SUBJECT];
		const SordNode* pred = quad[SORD_PREDICATE];
		const SordNode* obj  = quad[SORD_OBJECT];

		bool is_any_property = false;
		SordIter* t = sord_search(model, pred, uris->rdf_type, NULL, NULL);
		for (; !sord_iter_end(t); sord_iter_next(t)) {
			if (is_descendant_of(model, uris,
			                     sord_iter_get_node(t, SORD_OBJECT),
			                     uris->rdf_Property,
			                     uris->rdfs_subClassOf)) {
				is_any_property = true;
				break;
			}
		}
		sord_iter_free(t);

		const bool is_ObjectProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_ObjectProperty, 0);
		const bool is_FunctionalProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_FunctionalProperty, 0);
		const bool is_InverseFunctionalProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_InverseFunctionalProperty, 0);
		const bool is_DatatypeProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_DatatypeProperty, 0);

		if (!is_any_property) {
			st = error("Use of undefined property", quad);
		}

		if (!sord_ask(model, pred, uris->rdfs_label, NULL, NULL)) {
			st = errorf("Property <%s> has no label\n",
			            sord_node_get_string(pred));
		}

		if (is_DatatypeProperty &&
		    sord_node_get_type(obj) != SORD_LITERAL) {
			st = error("Datatype property with non-literal value", quad);
		}

		if (is_ObjectProperty &&
		    sord_node_get_type(obj) == SORD_LITERAL) {
			st = error("Object property with literal value", quad);
		}

		if (is_FunctionalProperty &&
		    sord_count(model, subj, pred, NULL, NULL) > 1) {
			st = error("Functional property with several objects", quad);
		}

		if (is_InverseFunctionalProperty &&
		    sord_count(model, NULL, pred, obj, NULL) > 1) {
			st = error("Inverse functional property with several subjects", quad);
		}

		if (sord_node_equals(pred, uris->rdf_type) &&
		    !sord_ask(model, obj, uris->rdf_type, uris->rdfs_Class, NULL) &&
		    !sord_ask(model, obj, uris->rdf_type, uris->owl_Class, NULL)) {
			st = error("Type is not a rdfs:Class or owl:Class", quad);
		}

		if (sord_node_get_type(obj) == SORD_LITERAL &&
		    !literal_is_valid(model, uris, obj, sord_node_get_datatype(obj))) {
			st = error("Literal does not match datatype", quad);
		}

		SordIter* r = sord_search(model, pred, uris->rdfs_range, NULL, NULL);
		for (; !sord_iter_end(r); sord_iter_next(r)) {
			const SordNode* range = sord_iter_get_node(r, SORD_OBJECT);
			if (!check_type(model, uris, obj, range)) {
				st = error("Object not in property range", quad);
				fprintf(stderr, "note: Range is <%s>\n",
				        sord_node_get_string(range));
			}
		}
		sord_iter_free(r);

		SordIter* d = sord_search(model, pred, uris->rdfs_domain, NULL, NULL);
		if (d) {
			const SordNode* domain = sord_iter_get_node(d, SORD_OBJECT);
			if (!check_type(model, uris, subj, domain)) {
				st = error("Subject not in property domain", quad);
				fprintf(stderr, "note: Domain is <%s>\n",
				        sord_node_get_string(domain));
			}
			sord_iter_free(d);
		}
	}
	sord_iter_free(i);

	return st;
}