TypeDB 3.0 is live! Get started for free.

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:

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

For more information, see the ConceptManager class methods.

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;
typeql

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:

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

For more information, see the ConceptManager class methods.

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:

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

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

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.

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();
    }
}
rust

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:

Example
let old_rule = tx.logic().get_rule("users".to_owned()).resolve()?.ok_or("Rule not found.")?;
rust
For more information, see the get_rule() method in driver API reference.

Get all rules

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

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());
}
rust
For more information, see the get_rules() method in driver API reference.

Add a rule

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

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()?;
rust
For more information, see the put_rule() method in driver API reference.

Rule manipulation

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

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

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.

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.

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();
    }
}
rust

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++