Skip to content

agnesoft/agdb

Repository files navigation

agdb logo

agdb

The graph database.

db       api       studio       server       cloud

rust ts js js python java c cpp csharp

license Crates.io release coverage codecov

agdb logo  Agnesoft Graph Database

Quickstart Db | Quickstart Client | QUERIES | DECISION TREE

Why not SQL?

The Agnesoft Graph Database (aka agdb) is persistent, optionally memory mapped graph database with native object 'no-text' queries. It can be used as a main persistent storage, data analytics platform as well as fast in-memory cache. Its typed schema-less data store allows for flexible and seamless data updates with no downtime or costly migrations. All queries are constructed via a builder pattern or directly as objects with no special language or text parsing.

agdb logo  Key Features

  • Data plotted on a graph
  • Typed key-value properties attached to graph elements (nodes & edges)
  • Persistent platform agnostic file based storage (transferable between platforms)
  • ACID compliant
  • Object queries with builder pattern (no text, no query language)
  • Memory mapped for fast querying
  • Server mode
  • OpenAPI clients in any programming language
  • Cloud hosted SaaS database
  • Db itself has no dependencies

agdb logo  At a glance [Db]

cargo add agdb

Basic usage demonstrating creating a database, inserting graph elements with data and querying them back with select and search. The function using this code must handle agdb::DbError and agdb::QueryError error types for operator ? to work:

use agdb::{Db, DbId, QueryBuilder, UserValue, DbUserValue, Comparison::Equal};

let mut db = Db::new("db_file.agdb")?;

db.exec_mut(QueryBuilder::insert().nodes().aliases("users").query())?;

#[derive(Debug, UserValue)]
struct User { db_id: Option<DbId>, name: String, }
let users = vec![User { db_id: None, name: "Alice".to_string(), },
                 User { db_id: None, name: "Bob".to_string(), },
                 User { db_id: None, name: "John".to_string(), }];

let users_ids = db.exec_mut(QueryBuilder::insert().nodes().values(&users).query())?;

db.exec_mut(
    QueryBuilder::insert()
        .edges()
        .from("users")
        .to(&users_ids)
        .query(),
)?;

This code creates a database called user_db.agdb with a simple graph of 4 nodes. The first node is aliased users and 3 user nodes for Alice, Bob and John are then connected with edges to the users node. The arbitrary name property is attached to the user nodes. Rather than inserting values directly with keys (which is also possible) we use our own type and derive from agdb::UserValue to allow it to be used with the database.

You can select the graph elements (both nodes & edges) with their ids to get them back with their associated data (key-value properties). Lets select our users and convert the result into the list (notice we select only values relevant to our User type with passing User::db_keys()):

let users: Vec<User> = db
    .exec(
        QueryBuilder::select()
            .values(User::db_keys())
            .ids(&users_ids)
            .query(),
    )?
    .try_into()?;

println!("{:?}", users);
// [User { db_id: Some(DbId(2)), username: "Alice" },
//  User { db_id: Some(DbId(3)), username: "Bob" },
//  User { db_id: Some(DbId(4)), username: "John" }]

You can also search through the graph to get back only certain elements based on conditions. For example:

let user: User = db
    .exec(
        QueryBuilder::select()
            .elements::<User>()
            .search()
            .from("users")
            .where_()
            .key("name")
            .value(Equal("Bob".into()))
            .query(),
    )?
    .try_into()?;

println!("{:?}", user);
// User { db_id: Some(DbId(3)), username: "Bob" }

For database concepts and primitive data types see concepts. For comprehensive overview of all queries see the queries reference or continue with more in-depth efficient agdb.

agdb logo  Crate Features

agdb

Feature Default Description
derive yes Enables derive macro to enable custom user types to be directly used with the database.
opeanapi no Enables ToSchema macro on query structs so they can be exported to json OpeanAPI/Swagger schema.
serde no Enables serialiation/deserialization of queries and QueryResult using serde.

agdb_api

Feature Default Description
reqwest no Enables referential implementation of the HttpClient trait for agdb API client using reqwest.

agdb logo  Decision Tree

flowchart TD;
    A[Embedded or server?] --> Embedded
    A --> B[Client or hosting?]
    Embedded --> Studio[<a href='https://agdb.agnesoft.com/docs/references/studio'>Studio</a>]
    Embedded --> Queries[<a href='https://agdb.agnesoft.com/docs/references/queries'>Queries</a>]
    B --> Client
    B --> Hosting
    Client --> API[<a href='https://agdb.agnesoft.com/api-docs/openapi'>API</a>]
    Client --> Studio
    Client --> Queries
    Hosting --> Server[<a href='https://agdb.agnesoft.com/docs/references/server'>Server</a>]
    Hosting --> Cloud[<a href='https://agdb.agnesoft.com/enterprise/cloud'>Cloud</a>]
Loading

agdb logo  Roadmap

The following are planned features:

Feature Description
Agdb Studio Graphical interface to agdb
Python Client Convenience client using bindings genereated from OpenAPI.
Java Client Convenience client using bindings genereated from OpenAPI.
C# Client Convenience client using bindings genereated from OpenAPI.
C Client Convenience client using bindings genereated from OpenAPI.
C++ Client Convenience client using bindings genereated from OpenAPI.
Data replication & consensus protocol Allow replication by connecting several database nodes together with a RAFT protocol.
Agdb Playground Free public cloud-based playground to tinker with agdb.
#[no_std] The agdb does not require any dependencies and thus should be (in theory) no_std friendly but it will likely require some development & testing.
Public Cloud Offering Commercial & supported agdb instance hosted in a public cloud.

agdb logo  Reference