relay-knowledge 1.1.17

Graph-database-based knowledge graph project.
Documentation
use super::{
    index_has_columns, table_column_is_not_null, table_columns_have_no_defaults, table_exists,
    table_has_columns, table_has_exact_columns, table_has_exact_plain_columns,
    table_has_exact_primary_key_index_surface, table_has_no_triggers,
    table_has_primary_key_columns, table_has_unique_columns,
};

#[test]
fn schema_introspection_checks_order_constraints_and_nullability() {
    let connection = rusqlite::Connection::open_in_memory().expect("connection should open");
    connection
        .execute_batch(
            "CREATE TABLE sample (
                 scope TEXT NOT NULL,
                 identity TEXT NOT NULL,
                 row_key INTEGER NOT NULL,
                 PRIMARY KEY (scope, identity),
                 UNIQUE (row_key)
             );",
        )
        .expect("sample schema should create");

    assert!(table_exists(&connection, "sample").expect("table should inspect"));
    assert!(
        table_has_columns(&connection, "sample", &["identity", "scope"])
            .expect("column membership should inspect")
    );
    assert!(
        table_has_exact_columns(&connection, "sample", &["scope", "identity", "row_key"])
            .expect("column order should inspect")
    );
    assert!(
        table_has_primary_key_columns(&connection, "sample", &["scope", "identity"])
            .expect("primary key should inspect")
    );
    assert!(
        table_column_is_not_null(&connection, "sample", "row_key")
            .expect("nullability should inspect")
    );
    assert!(
        table_has_unique_columns(&connection, "sample", &["row_key"])
            .expect("unique key should inspect")
    );
}

#[test]
fn schema_introspection_rejects_partial_and_expression_indexes() {
    let connection = rusqlite::Connection::open_in_memory().expect("connection should open");
    connection
        .execute_batch(
            "CREATE TABLE sample (identity TEXT NOT NULL, row_key INTEGER);
             CREATE UNIQUE INDEX partial_unique
             ON sample(row_key) WHERE(row_key IS NOT NULL);
             CREATE INDEX partial_lookup
             ON sample(identity) WHERE(identity <> '');
             CREATE INDEX expression_lookup
             ON sample(lower(identity));
             CREATE INDEX complete_lookup ON sample(identity);",
        )
        .expect("adversarial indexes should create");

    assert!(
        !table_has_unique_columns(&connection, "sample", &["row_key"])
            .expect("partial unique key should inspect")
    );
    assert!(
        !index_has_columns(&connection, "partial_lookup", &["identity"])
            .expect("partial lookup should inspect")
    );
    assert!(
        !index_has_columns(&connection, "expression_lookup", &["identity"])
            .expect("expression lookup should inspect")
    );
    assert!(
        index_has_columns(&connection, "complete_lookup", &["identity"])
            .expect("complete lookup should inspect")
    );
}

#[test]
fn progress_owner_introspection_rejects_hidden_columns_defaults_indexes_and_triggers() {
    let connection = rusqlite::Connection::open_in_memory().expect("connection should open");
    connection
        .execute_batch(
            "CREATE TABLE exact_owner (scope TEXT NOT NULL PRIMARY KEY, cursor TEXT);
             CREATE TABLE generated_owner (
                 scope TEXT NOT NULL PRIMARY KEY,
                 cursor TEXT,
                 page_guard INTEGER GENERATED ALWAYS AS (length(scope)) STORED
             );
             CREATE TABLE default_owner (
                 scope TEXT NOT NULL PRIMARY KEY,
                 cursor TEXT DEFAULT(NULL)
             );",
        )
        .expect("progress-owner fixtures should create");
    assert!(
        table_has_exact_plain_columns(&connection, "exact_owner", &["scope", "cursor"])
            .expect("plain columns should inspect")
    );
    assert!(
        !table_has_exact_plain_columns(&connection, "generated_owner", &["scope", "cursor"])
            .expect("generated columns should inspect")
    );
    assert!(
        !table_columns_have_no_defaults(&connection, "default_owner")
            .expect("defaults should inspect")
    );
    assert!(
        table_has_exact_primary_key_index_surface(&connection, "exact_owner", &["scope"])
            .expect("exact PK index surface should inspect")
    );
    connection
        .execute_batch(
            "CREATE INDEX extra_owner_index ON exact_owner(cursor);
             CREATE TRIGGER exact_owner_update AFTER UPDATE ON exact_owner BEGIN
                 SELECT 1;
             END;",
        )
        .expect("extra mutation surfaces should create");
    assert!(
        !table_has_exact_primary_key_index_surface(&connection, "exact_owner", &["scope"])
            .expect("extra index should inspect")
    );
    assert!(!table_has_no_triggers(&connection, "exact_owner").expect("trigger should inspect"));
}