New ACM paper, free-tier cloud, and open-source license

Schema objects

In this guide, you’ll see how to use driver API methods and stateful objects to programmatically manipulate types and rules in a database schema using one of the TypeDB drivers. This page assumes you’ve already followed instructions from the Define query page.

Understanding schema objects

Schema objects represent types and rules in the schema of a TypeDB database. Driver APIs provide a set of methods to programmatically manipulate these objects.

Type objects

A type object has many useful methods to traverse the type hierarchy, find related types, and manipulate types definitions/properties. To manipulate a type with driver API methods, you need to get a stateful object that represents the type in the database.

Get type objects

To get a type object from a TypeDB database, you can use a TypeQL Get query or one of the driver API methods.

Get a type object by its label

Use type’s label to retrieve the type object. For example, to get a stateful object of the user entity type, use:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
let user_type = tx.concept().get_entity_type("user".to_owned()).resolve()?.unwrap();

For more information, see the ConceptManager class methods.

Example
user_type = tx.concepts.get_entity_type("user").resolve()

For more information, see the ConceptManager class methods.

Example
let userType = await tx.concepts.getEntityType("user");

For more information, see the ConceptManager class methods.

Example
EntityType userType = tx.concepts().getEntityType("user").resolve();

For more information, see the ConceptManager class methods.

Example
IEntityType userType = tx.Concepts.GetEntityType("user").Resolve()!;

For more information, see the IConceptManager class methods.

Example
std::unique_ptr<TypeDB::EntityType> userType = tx.concepts.getEntityType("user").get();

For more information, see the ConceptManager class methods.

Example
Concept* userType = concept_promise_resolve(concepts_get_entity_type(tx, "user"));

For more information, see the Concept struct functions.

Query for types

Send a Get query with a pattern to retrieve types and process the response to get type objects. For example, to get all entity types, send the following Get query:

Example of a Get query for entity types
match
$x sub entity;
get $x;

Create type objects

To add a new type into the schema of a database, use a TypeQL Define query or one of the put type methods. For example, to add an entity type with the label admin by using put type method, use the following code:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
admin_type = tx.concepts.put_entity_type("admin").resolve()

For more information, see the ConceptManager class methods.

Example
admin_type = tx.concepts.put_entity_type("admin").resolve()

For more information, see the ConceptManager class methods.

Example
let adminType = await tx.concepts.putEntityType("admin");

For more information, see the ConceptManager class methods.

Example
EntityType adminType = tx.concepts().putEntityType("admin").resolve();

For more information, see the ConceptManager class methods.

Example
IEntityType adminType = tx.Concepts.PutEntityType("admin").Resolve()!;

For more information, see the IConceptManager class methods.

Example
std::unique_ptr<TypeDB::EntityType> adminType = tx.concepts.putEntityType("admin").get();

For more information, see the ConceptManager class methods.

Example
Concept* adminType = concept_promise_resolve(concepts_put_entity_type(tx, "admin"));

For more information, see the Concept struct functions.

Type manipulation

A stateful type object has many useful methods to manipulate the type or traverse the type hierarchy of a schema:

  • get/set label,

  • get/set supertype,

  • get subtypes,

  • get ownerships,

  • get roles played,

  • etc.

For example, see how to change a supertype for the admin type we added previously:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
drop(admin_type.set_supertype(&tx, user_type.clone()).resolve());

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
admin_type.set_supertype(tx, user_type)

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
await adminType.setSupertype(tx, userType);

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
adminType.setSupertype(tx, userType).resolve();

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
adminType.SetSupertype(tx, userType);

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
adminType.get()->setSupertype(tx, userType.get()).wait();

For more information on methods, available for manipulating Type objects, see the Schema class methods.

Example
entity_type_set_supertype(tx, adminType, userType);

For more information on methods, available for manipulating Type objects, see the Schema section functions.

Full example

See below a more comprehensive example of type objects manipulation. In this example we retrieve the user type object, create the admin type and set user as a supertype for admin. Then we retrieve all subtypes of the entity root types (effectively all entity types) and print their labels.

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

let databases = DatabaseManager::new(driver);
let db = databases.get(DB_NAME)?;
{
    let session = Session::new(db, SessionType::Schema)?;
    {
        let tx = session.transaction(TransactionType::Write)?;
        let user_type = tx.concept().get_entity_type("user".to_owned()).resolve()?.ok_or("No root entity")?;
        let mut admin_type = tx.concept().put_entity_type("admin".to_owned()).resolve()?;
        drop(admin_type.set_supertype(&tx, user_type).resolve());
        let entities = tx
            .concept()
            .get_entity_type("entity".to_owned())
            .resolve()?
            .ok_or("No root entity")?
            .get_subtypes(&tx, Transitivity::Transitive)?;
        for subtype in entities {
            println!("{}", subtype?.label);
        }
        let _ = tx.commit().resolve();
    }
}
with driver.session(DB_NAME, SessionType.SCHEMA) as session:
    with session.transaction(TransactionType.WRITE) as tx:
        user_type = tx.concepts.get_entity_type("user").resolve()
        admin_type = tx.concepts.put_entity_type("admin").resolve()
        admin_type.set_supertype(tx, user_type)
        root_entity = tx.concepts.get_root_entity_type()
        subtypes = list(root_entity.get_subtypes(tx, Transitivity.TRANSITIVE))
        for subtype in subtypes:
            print(subtype.get_label().name)
        tx.commit()
try {
    session = await driver.session(DB_NAME, SessionType.SCHEMA);
    try {
        tx = await session.transaction(TransactionType.WRITE);
        let user = await tx.concepts.getEntityType("user");
        let admin = await tx.concepts.putEntityType("admin");
        await admin.setSupertype(tx, user);
        let rootEntity = await tx.concepts.getRootEntityType();
        let subtypes = await rootEntity.getSubtypes(tx, Concept.Transitivity.TRANSITIVE);
        await subtypes.forEach(subtype => console.log(subtype.label.toString()));
        await tx.commit();
    }
    finally {if (tx.isOpen()) {await tx.close()};}
}
finally {await session?.close();}
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.SCHEMA)) {
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
        EntityType userType = tx.concepts().getEntityType("user").resolve();
        EntityType adminType = tx.concepts().putEntityType("admin").resolve();
        adminType.setSupertype(tx, userType).resolve();
        EntityType root_entity = tx.concepts().getRootEntityType();
        root_entity.getSubtypes(tx, Concept.Transitivity.TRANSITIVE).forEach(result -> System.out.println(result.getLabel().name()));
        tx.commit();
    }
}
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Schema)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
        IEntityType userType = tx.Concepts.GetEntityType("user").Resolve()!;
        IEntityType adminType = tx.Concepts.PutEntityType("admin").Resolve()!;
        adminType.SetSupertype(tx, userType);
        IEnumerable<IType> entities = tx.Concepts.RootEntityType.GetSubtypes(tx, IConcept.Transitivity.Transitive);
        foreach (IType entity in entities) {
            Console.WriteLine(entity.Label);
        }
        tx.Commit();
    }
}
TypeDB::Options options;
TypeDB::Session session = driver.session(DB_NAME, TypeDB::SessionType::SCHEMA, options);
{
    TypeDB::Transaction tx = session.transaction(TypeDB::TransactionType::WRITE, options);
    std::unique_ptr<TypeDB::EntityType> userType = tx.concepts.getEntityType("user").get();
    std::unique_ptr<TypeDB::EntityType> adminType = tx.concepts.putEntityType("admin").get();
    adminType.get()->setSupertype(tx, userType.get()).wait();
    TypeDB::ConceptIterable<TypeDB::EntityType> entities = tx.concepts.getRootEntityType().get()->getSubtypes(tx, TypeDB::Transitivity::TRANSITIVE);
    for (std::unique_ptr<TypeDB::EntityType>& entity : entities) {
        std::cout << entity.get()->getLabel() << std::endl;
    }
    tx.commit();
}
Options* opts = options_new();
session = session_new(databaseManager, DB_NAME, Schema, opts);
tx = transaction_new(session, Write, opts);
if ((tx == NULL) || FAILED()) {
    handle_error("Transaction failed to start.");
    goto cleanup;
}
Concept* userType = concept_promise_resolve(concepts_get_entity_type(tx, "user"));
Concept* adminType = concept_promise_resolve(concepts_put_entity_type(tx, "admin"));
entity_type_set_supertype(tx, adminType, userType);
ConceptIterator* entities = entity_type_get_subtypes(tx, concepts_get_root_entity_type(), Transitive);
Concept* entity;
while ((entity = concept_iterator_next(entities)) != NULL) {
    printf("%s\n", thing_type_get_label(entity));
}
void_promise_resolve(transaction_commit(tx));
if (FAILED()) {
    handle_error("Transaction commit failed.");
    goto cleanup;
}
session_close(session);

For an additional example of programmatic type manipulations, see the Schema editing page.

Rule objects

A rule object has label, when, and then properties and just a few methods.

To manipulate a rule with driver API methods, you need to get a stateful object that represents the rule in the database.

Get a rule

Rules can be defined with a TypeQL query (see Define query), but they can’t be retrieved with one. To get a rule object from a TypeDB database, you need to use the Logic class methods of a driver API.

Get a rule object by its label

Use rule’s label to retrieve the rule object. For example, to get a stateful object of the rule with the label Employee, use:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
let old_rule = tx.logic().get_rule("users".to_owned()).resolve()?.ok_or("Rule not found.")?;
For more information, see the get_rule() method in driver API reference.
Example
old_rule = tx.logic.get_rule("users").resolve()
For more information, see the get_rule() method in driver API reference.
Example
let oldRule = (await tx.logic.getRule("users")).label;
For more information, see the get_rule() method in driver API reference.
Example
Rule oldRule = tx.logic().getRule("users").resolve();
For more information, see the getRule() method in driver API reference.
Example
IRule oldRule = tx.Logic.GetRule("users").Resolve()!;
For more information, see the GetRule() method in driver API reference.
Example
TypeDB::Rule oldRule = tx.logic.getRule("users").get().value();
For more information, see the getRule() method in driver API reference.
Example
Rule* oldRule = rule_promise_resolve(logic_manager_get_rule(tx, "users"));
For more information, see the get_rule() function in driver API reference.

Get all rules

Use get rules method to retrieve all rules in a schema:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
let rules = tx.logic().get_rules()?;
for rule in rules {
    println!("{}", rule.clone()?.label);
    println!("{}", rule.clone()?.when.to_string());
    println!("{}", rule.clone()?.then.to_string());
}
For more information, see the get_rules() method in driver API reference.
Example
rules = tx.logic.get_rules()
for rule in rules:
    print(rule.label)
    print(rule.when)
    print(rule.then)
For more information, see the get_rules() method in driver API reference.
Example
let rules = await tx.logic.getRules();
for await (const rule of rules) {
    console.log(rule.label);
    console.log(rule.when);
    console.log(rule.then);
}
For more information, see the getRules() method in driver API reference.
Example
tx.logic().getRules().forEach(result -> {
    System.out.println(result.getLabel());
    System.out.println(result.getWhen().toString());
    System.out.println(result.getThen().toString());
});
For more information, see the getRules() method in driver API reference.
Example
IEnumerable<IRule> rules = tx.Logic.GetRules();
foreach (IRule rule in rules) {
    Console.WriteLine(rule.Label);
    Console.WriteLine(rule.When);
    Console.WriteLine(rule.Then);
}
For more information, see the GetRules() method in driver API reference.
Example
TypeDB::RuleIterable rules = tx.logic.getRules();
for (TypeDB::Rule& rule : rules) {
    std::cout << rule.label() << std::endl;
    std::cout << rule.when() << std::endl;
    std::cout << rule.then() << std::endl;
}
For more information, see the getRules() method in driver API reference.
Example
RuleIterator* rules = logic_manager_get_rules(tx);
Rule* rule;
while ((rule = rule_iterator_next(rules)) != NULL) {
    printf("%s\n%s\n%s\n", rule_get_label(rule), rule_get_when(rule), rule_get_then(rule));
}
For more information, see the get_rules() function in driver API reference.

Add a rule

Use the following methods to add a rule to the schema of a database:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
let condition = typeql::parse_pattern("{$u isa user, has email $e; $e contains '@typedb.com';}")?
    .into_conjunction();
let conclusion = typeql::parse_pattern("$u has name 'Employee'")?.into_statement();
let mut new_rule = tx.logic().put_rule("Employee".to_string(), condition, conclusion).resolve()?;
For more information, see the put_rule() method in driver API reference.
Example
new_rule = tx.logic.put_rule("Employee",
                             "{$u isa user, has email $e; $e contains '@typedb.com';}",
                             "$u has name 'Employee'").resolve()
For more information, see the put_rule() method in driver API reference.
Example
let newRule = await tx.logic.putRule("Employee","{$u isa user, has email $e; $e contains '@typedb.com';}","$u has name 'Employee'");
For more information, see the putRule() method in driver API reference.
Example
Pattern condition = TypeQL.parsePattern("{$u isa user, has email $e; $e contains '@typedb.com';}");
Pattern conclusion = TypeQL.parsePattern("$u has name 'Employee'");
Rule newRule = tx.logic().putRule("Employee", condition, conclusion).resolve();
For more information, see the putRule() method in driver API reference.
Example
IRule newRule = tx.Logic.PutRule("Employee", "{$u isa user, has email $e; $e contains '@vaticle.com';}","$u has name 'Employee'").Resolve()!;
For more information, see the PutRule() method in driver API reference.
Example
TypeDB::Rule newRule = tx.logic.putRule("Employee", "{$u isa user, has email $e; $e contains '@typedb.com';}","$u has name 'Employee'").get();
For more information, see the putRule() method in driver API reference.
Example
Rule* newRule = rule_promise_resolve(logic_manager_put_rule(tx, "Employee", "{$u isa user, has email $e; $e contains '@vaticle.com';}", "$u has name 'Employee'"));
For more information, see the put_rule() function in driver API reference.

Rule manipulation

A stateful rule object has just a few methods: get/set label, delete, and is_deleted.

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Example
let _ = new_rule.delete(&tx).resolve();

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule class methods.
Example
new_rule.delete(tx).resolve()

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule class methods.
Example
await newRule.delete(tx);

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule class methods.
Example
newRule.delete(tx).resolve();

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule class methods.
Example
newRule.Delete(tx).Resolve();

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the IRule class methods.
Example
newRule.deleteRule(tx).get();

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule class methods.
Example
rule_delete(tx, newRule);

The above example deletes the type, which type object is stored in the variable, from the schema of a database. You need to commit transaction to persist the changes.

For more information on methods, available for manipulating Rule objects, see the Rule section functions.

Full example

See below a comprehensive example of rules manipulation: retrieving all rules, printing label, condition (when) and conclusion(then), adding a new rule, retrieving a rule by its label, and deleting a rule.

See below a more comprehensive example of rule objects manipulation. In this example we retrieve the users rule object and print its label, condition, and conclusion. Then we add a new rule Employee and retrieve all rules to print their labels.

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

let db = databases.get(DB_NAME)?;
{
    let session = Session::new(db, SessionType::Schema)?;
    {
        let tx = session.transaction(TransactionType::Write)?;
        let rules = tx.logic().get_rules()?;
        for rule in rules {
            println!("{}", rule.clone()?.label);
            println!("{}", rule.clone()?.when.to_string());
            println!("{}", rule.clone()?.then.to_string());
        }
        let condition = typeql::parse_pattern("{$u isa user, has email $e; $e contains '@typedb.com';}")?
            .into_conjunction();
        let conclusion = typeql::parse_pattern("$u has name 'Employee'")?.into_statement();
        let mut new_rule = tx.logic().put_rule("Employee".to_string(), condition, conclusion).resolve()?;
        let _ = new_rule.delete(&tx).resolve();
        let old_rule = tx.logic().get_rule("users".to_owned()).resolve()?.ok_or("Rule not found.")?;
        let _ = tx.commit().resolve();
    }
}
with driver.session(DB_NAME, SessionType.SCHEMA) as session:
    with session.transaction(TransactionType.WRITE) as tx:
        rules = tx.logic.get_rules()
        for rule in rules:
            print(rule.label)
            print(rule.when)
            print(rule.then)
        new_rule = tx.logic.put_rule("Employee",
                                     "{$u isa user, has email $e; $e contains '@typedb.com';}",
                                     "$u has name 'Employee'").resolve()
        new_rule.delete(tx).resolve()
        old_rule = tx.logic.get_rule("users").resolve()
        print(old_rule.label)
        tx.commit()
try {
    session = await driver.session(DB_NAME, SessionType.SCHEMA);
    try {
        tx = await session.transaction(TransactionType.WRITE);
        for await (const rule of tx.logic.getRules()) {
            console.log(rule.label);
            console.log(rule.when);
            console.log(rule.then);
        }
        let newRule = await tx.logic.putRule("Employee","{$u isa user, has email $e; $e contains '@typedb.com';}","$u has name 'Employee'");
        console.log((await tx.logic.getRule("users")).label);
        await newRule.delete(tx);
        await tx.commit();
    }
    finally {if (tx.isOpen()) {await tx.close()};}
}
finally {await session?.close();}
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.SCHEMA)) {
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
        tx.logic().getRules().forEach(result -> {
            System.out.println(result.getLabel());
            System.out.println(result.getWhen().toString());
            System.out.println(result.getThen().toString());
        });
        Pattern condition = TypeQL.parsePattern("{$u isa user, has email $e; $e contains '@typedb.com';}");
        Pattern conclusion = TypeQL.parsePattern("$u has name 'Employee'");
        Rule newRule = tx.logic().putRule("Employee", condition, conclusion).resolve();
        Rule oldRule = tx.logic().getRule("users").resolve();
        System.out.println(oldRule.getLabel());
        newRule.delete(tx).resolve();
        tx.commit();
    }
}
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Schema)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
        IEnumerable<IRule> rules = tx.Logic.GetRules();
        foreach (IRule rule in rules) {
            Console.WriteLine(rule.Label);
            Console.WriteLine(rule.When);
            Console.WriteLine(rule.Then);
        }
        IRule newRule = tx.Logic.PutRule("Employee", "{$u isa user, has email $e; $e contains '@vaticle.com';}","$u has name 'Employee'").Resolve()!;
        IRule oldRule = tx.Logic.GetRule("users").Resolve()!;
        Console.WriteLine(oldRule.Label);
        newRule.Delete(tx).Resolve();
        tx.Commit();
    }
}
TypeDB::Options options;
TypeDB::Session session = driver.session(DB_NAME, TypeDB::SessionType::SCHEMA, options);
{
    TypeDB::Transaction tx = session.transaction(TypeDB::TransactionType::WRITE, options);
    TypeDB::RuleIterable rules = tx.logic.getRules();
    for (TypeDB::Rule& rule : rules) {
        std::cout << rule.label() << std::endl;
        std::cout << rule.when() << std::endl;
        std::cout << rule.then() << std::endl;
    }
    TypeDB::Rule newRule = tx.logic.putRule("Employee", "{$u isa user, has email $e; $e contains '@typedb.com';}","$u has name 'Employee'").get();
    TypeDB::Rule oldRule = tx.logic.getRule("users").get().value();
    std::cout << oldRule.label() << std::endl;
    newRule.deleteRule(tx).get();
    tx.commit();
}
Options* opts = options_new();
session = session_new(databaseManager, DB_NAME, Schema, opts);
tx = transaction_new(session, Write, opts);
if ((tx == NULL) || FAILED()) {
    handle_error("Transaction failed to start.");
    goto cleanup;
}
RuleIterator* rules = logic_manager_get_rules(tx);
Rule* rule;
while ((rule = rule_iterator_next(rules)) != NULL) {
    printf("%s\n%s\n%s\n", rule_get_label(rule), rule_get_when(rule), rule_get_then(rule));
}
Rule* newRule = rule_promise_resolve(logic_manager_put_rule(tx, "Employee", "{$u isa user, has email $e; $e contains '@vaticle.com';}", "$u has name 'Employee'"));
Rule* oldRule = rule_promise_resolve(logic_manager_get_rule(tx, "users"));
printf("%s\n", rule_get_label(oldRule));
rule_delete(tx, newRule);
void_promise_resolve(transaction_commit(tx));
if (FAILED()) {
    handle_error("Transaction commit failed.");
    goto cleanup;
}
session_close(session);

Learn more

Learn more about TypeDB drivers: list of available drivers, installation guides, API reference.

For more information about driver API methods, see the API reference of the relevant driver:

rustRust
javaJava
cppC++

Provide Feedback