Beginner Tutorial

Step-by-step guide to get started with DBX.

Table of contents

  1. Introduction
  2. Step 1: Create a New Project
  3. Step 2: Your First Database
  4. Step 3: Insert Data
  5. Step 4: Query Data
  6. Step 5: Working with Structured Data
  7. Step 6: Using Transactions
  8. Step 7: SQL Queries
  9. Step 8: Persistent Storage
  10. Complete Example
  11. Next Steps
  12. Common Mistakes
    1. 1. Forgetting to Commit Transactions
    2. 2. Not Handling Errors
    3. 3. Using Wrong Key Format
  13. Exercises
  14. Getting Help

Introduction

This tutorial will guide you through creating your first DBX database, performing basic operations, and running simple SQL queries.

What you’ll learn:

  • Installing DBX
  • Creating a database
  • Inserting and querying data
  • Using transactions
  • Running SQL queries

Prerequisites:

  • Rust 1.70 or later
  • Basic Rust knowledge

Step 1: Create a New Project

Create a new Rust project:

cargo new my_dbx_app
cd my_dbx_app

Add DBX to Cargo.toml:

[dependencies]
dbx-core = "0.0.6-beta"
arrow = "50.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Step 2: Your First Database

Create a simple database in src/main.rs:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    // Create an in-memory database
    let db = Database::open_in_memory()?;
    
    println!("Database created successfully!");
    
    Ok(())
}

Run it:

cargo run

You should see: Database created successfully!


Step 3: Insert Data

Let’s add some data to our database:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    let db = Database::open_in_memory()?;
    
    // Insert users
    db.insert("users", b"user:1", b"Alice")?;
    db.insert("users", b"user:2", b"Bob")?;
    db.insert("users", b"user:3", b"Charlie")?;
    
    println!("Inserted 3 users");
    
    Ok(())
}

Step 4: Query Data

Retrieve data from the database:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    let db = Database::open_in_memory()?;
    
    // Insert data
    db.insert("users", b"user:1", b"Alice")?;
    
    // Query data
    let value = db.get("users", b"user:1")?;
    
    match value {
        Some(data) => {
            let name = String::from_utf8(data).unwrap();
            println!("Found user: {}", name);
        }
        None => println!("User not found"),
    }
    
    Ok(())
}

Step 5: Working with Structured Data

Use Serde to work with structured data:

use dbx_core::Database;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    id: u32,
    name: String,
    email: String,
    age: u32,
}

fn main() -> dbx_core::DbxResult<()> {
    let db = Database::open_in_memory()?;
    
    // Create a user
    let user = User {
        id: 1,
        name: "Alice".to_string(),
        email: "alice@example.com".to_string(),
        age: 25,
    };
    
    // Serialize and insert
    let key = format!("user:{}", user.id);
    let value = serde_json::to_vec(&user).unwrap();
    db.insert("users", key.as_bytes(), &value)?;
    
    // Retrieve and deserialize
    let retrieved = db.get("users", key.as_bytes())?;
    if let Some(data) = retrieved {
        let user: User = serde_json::from_slice(&data).unwrap();
        println!("Retrieved user: {:?}", user);
    }
    
    Ok(())
}

Step 6: Using Transactions

Perform multiple operations atomically:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    let db = Database::open_in_memory()?;
    
    // Begin transaction
    let tx = db.begin_transaction()?;
    
    // Insert multiple records
    tx.insert("users", b"user:1", b"Alice")?;
    tx.insert("users", b"user:2", b"Bob")?;
    tx.insert("users", b"user:3", b"Charlie")?;
    
    // Commit all changes
    tx.commit()?;
    
    println!("Transaction committed successfully!");
    
    Ok(())
}

Step 7: SQL Queries

Run SQL queries on your data:

use dbx_core::Database;
use arrow::array::{Int32Array, StringArray, RecordBatch};
use arrow::datatypes::{DataType, Field, Schema};
use std::sync::Arc;

fn main() -> dbx_core::DbxResult<()> {
    let db = Database::open_in_memory()?;
    
    // Create schema
    let schema = Arc::new(Schema::new(vec![
        Field::new("id", DataType::Int32, false),
        Field::new("name", DataType::Utf8, false),
        Field::new("age", DataType::Int32, false),
    ]));
    
    // Create data
    let batch = RecordBatch::try_new(
        schema.clone(),
        vec![
            Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])),
            Arc::new(StringArray::from(vec![
                "Alice", "Bob", "Charlie", "David", "Eve"
            ])),
            Arc::new(Int32Array::from(vec![25, 30, 35, 28, 32])),
        ],
    ).unwrap();
    
    // Register table
    db.register_table("users", vec![batch]);
    
    // Run SQL query
    let results = db.execute_sql(
        "SELECT name, age FROM users WHERE age > 28"
    )?;
    
    println!("Query results:");
    for batch in results {
        println!("{:?}", batch);
    }
    
    Ok(())
}

Step 8: Persistent Storage

Save data to disk:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    // Create persistent database
    let db = Database::open("./my_database")?;
    
    // Insert data
    db.insert("users", b"user:1", b"Alice")?;
    db.insert("users", b"user:2", b"Bob")?;
    
    // Data is automatically persisted
    println!("Data saved to ./my_database");
    
    Ok(())
}

To read the data later:

use dbx_core::Database;

fn main() -> dbx_core::DbxResult<()> {
    // Open existing database
    let db = Database::open("./my_database")?;
    
    // Query data
    let value = db.get("users", b"user:1")?;
    println!("Retrieved: {:?}", value);
    
    Ok(())
}

Complete Example

Here’s a complete example combining everything:

use dbx_core::Database;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    id: u32,
    name: String,
    email: String,
    age: u32,
}

fn main() -> dbx_core::DbxResult<()> {
    // Create database
    let db = Database::open("./tutorial_db")?;
    
    // Create users
    let users = vec![
        User {
            id: 1,
            name: "Alice".to_string(),
            email: "alice@example.com".to_string(),
            age: 25,
        },
        User {
            id: 2,
            name: "Bob".to_string(),
            email: "bob@example.com".to_string(),
            age: 30,
        },
        User {
            id: 3,
            name: "Charlie".to_string(),
            email: "charlie@example.com".to_string(),
            age: 35,
        },
    ];
    
    // Insert users in a transaction
    let tx = db.begin_transaction()?;
    for user in &users {
        let key = format!("user:{}", user.id);
        let value = serde_json::to_vec(&user).unwrap();
        tx.insert("users", key.as_bytes(), &value)?;
    }
    tx.commit()?;
    
    println!("Inserted {} users", users.len());
    
    // Query a specific user
    let key = b"user:2";
    if let Some(data) = db.get("users", key)? {
        let user: User = serde_json::from_slice(&data).unwrap();
        println!("Found user: {:?}", user);
    }
    
    // Count all users
    let count = db.count("users")?;
    println!("Total users: {}", count);
    
    Ok(())
}

Next Steps

Congratulations! You’ve learned the basics of DBX. Here’s what to explore next:


Common Mistakes

1. Forgetting to Commit Transactions

// Wrong: Transaction not committed
let tx = db.begin_transaction()?;
tx.insert("users", b"user:1", b"Alice")?;
// Missing: tx.commit()?;

// Right: Always commit
let tx = db.begin_transaction()?;
tx.insert("users", b"user:1", b"Alice")?;
tx.commit()?;

2. Not Handling Errors

// Wrong: Unwrapping can panic
let value = db.get("users", b"user:1").unwrap();

// Right: Handle errors properly
match db.get("users", b"user:1") {
    Ok(Some(value)) => println!("Found: {:?}", value),
    Ok(None) => println!("Not found"),
    Err(e) => eprintln!("Error: {}", e),
}

3. Using Wrong Key Format

// Wrong: Inconsistent key format
db.insert("users", b"1", b"Alice")?;
db.insert("users", b"user:2", b"Bob")?;

// Right: Consistent key format
db.insert("users", b"user:1", b"Alice")?;
db.insert("users", b"user:2", b"Bob")?;

Exercises

Try these exercises to practice:

  1. User Management System
    • Create a database with users
    • Implement add, get, update, delete operations
    • Use transactions for batch operations
  2. Simple Blog
    • Store blog posts with title, content, author
    • Query posts by author
    • Count total posts
  3. Product Catalog
    • Store products with name, price, category
    • Use SQL to query products by price range
    • Calculate average price per category

Getting Help


Copyright © 2026 ByteLogicCore. MIT OR Apache-2.0 License.

This site uses Just the Docs, a documentation theme for Jekyll.