C Advanced API
Domain builders
Declare a domain with a loading-time predicate installer through the C Advanced API.Use a domain installer when the predicate vocabulary is assembled by C code rather than kept in a fixed array. For a fixed vocabulary, use stable registration; both paths register a domain by name before loading a policy.
Types
Defined on this page
| Type | Purpose |
|---|---|
maelys_datalog_domain_builder_t | Opaque loading candidate passed to an installer. |
maelys_datalog_domain_installer_t | Callback that adds predicate declarations. |
Used from other pages
These types are defined on the linked pages; this page uses them in the roles below.
| Type | Use on this page | Defined in |
|---|---|---|
maelys_datalog_domain_t | Input domain declaration for advanced registration. | Stable Registries |
maelys_datalog_predicate_t | Input predicate declaration supplied by the installer. | Stable Registries |
Functions
| Function | Purpose |
|---|---|
maelys_datalog_domain_register_advanced() | Register a domain with a fixed table or an installer. |
maelys_datalog_domain_builder_add() | Add one predicate while the installer runs. |
Build a domain at policy load
Registration records the domain name and callback; it does not run the callback. Loading a policy creates a bounded candidate registry and invokes the installer. The candidate is published only if every declaration succeeds. Even if the callback ignores a failed domain_builder_add(), the failure remains sticky and loading fails.
typedef struct maelys_datalog_domain_builder maelys_datalog_domain_builder_t;typedef maelys_datalog_status_t (*maelys_datalog_domain_installer_t)(maelys_datalog_domain_builder_t *);maelys_datalog_status_t
maelys_datalog_domain_register_advanced(
const maelys_datalog_domain_t *domain,
const char *description,
maelys_datalog_domain_installer_t installer
);maelys_datalog_status_tOK on registration; an incompatible registration or invalid combination is rejected. The callback has not run yet.
maelys_datalog_status_t
maelys_datalog_domain_builder_add(
maelys_datalog_domain_builder_t *builder,
const maelys_datalog_predicate_t *predicate
);maelys_datalog_status_tOK when the declaration is accepted; otherwise loading discards the entire candidate.
Example — document access
The shared stable example uses a fixed array. This alternative registers the same predicate declarations through an installer, without changing the policy or request facts:
static const maelys_datalog_predicate_t document_predicates[] = {
{"user", 1u, MAELYS_DATALOG_PREDICATE_EDB},
{"owns", 2u, MAELYS_DATALOG_PREDICATE_EDB},
{"delegated", 2u, MAELYS_DATALOG_PREDICATE_EDB},
{"blocked", 1u, MAELYS_DATALOG_PREDICATE_EDB},
{"can_read", 2u, MAELYS_DATALOG_PREDICATE_IDB},
{"has_any_document", 1u, MAELYS_DATALOG_PREDICATE_IDB | MAELYS_DATALOG_PREDICATE_QUERY},
{"allow", 2u, MAELYS_DATALOG_PREDICATE_IDB | MAELYS_DATALOG_PREDICATE_QUERY},
};
static maelys_datalog_status_t install_documents(maelys_datalog_domain_builder_t *builder) {
for (size_t i = 0; i < sizeof(document_predicates) / sizeof(document_predicates[0]); ++i) {
maelys_datalog_status_t rc = maelys_datalog_domain_builder_add(builder, &document_predicates[i]);
if (rc != MAELYS_DATALOG_STATUS_OK) return rc;
}
return MAELYS_DATALOG_STATUS_OK;
}
static maelys_datalog_status_t register_documents(void) {
const maelys_datalog_domain_t domain = {"documents", NULL, 0u, NULL, 0u};
return maelys_datalog_domain_register_advanced(
&domain, "Document access", install_documents);
}Exactly one of domain.predicates and installer must provide declarations. Policy-source atoms, if any, remain in domain.atoms; the callback does not replace that list. Here blocked("mallory") is a request fact, so no source atom is needed. Domains remain process-global; a context does not isolate them. Registration copies declaration text, but the installer’s executable code must stay available while policies may be loaded.