Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
14 KiB
14 KiB
SurrealDB 2.3 Quick Start Guide
Status: Production Ready ✅ Version: SurrealDB 2.3 Updated: November 15, 2025
This guide shows how to quickly get started with SurrealDB 2.3 in syntaxis with different deployment contexts.
Quick Install & Run
Option 1: Embedded In-Memory (Fastest, No Server)
# No installation needed - uses embedded library
# Update configs/database.toml:
[surrealdb]
url = "mem://" # In-memory database
namespace = "syntaxis"
database = "projects"
use workspace_core::SurrealDatabase;
#[tokio::main]
async fn main() -> Result<()> {
// Create in-memory database
let db = SurrealDatabase::new_memory().await?;
// Start using database immediately
let projects = db.list_projects().await?;
println!("Projects: {}", projects.len());
Ok(())
}
Option 2: Embedded File-Based (Persistent, No Server)
# Update configs/database.toml:
[surrealdb]
url = "file:///tmp/surrealdb.db" # RocksDB persistent storage
namespace = "syntaxis"
database = "projects"
let db = SurrealDatabase::new_file("/tmp/surrealdb.db").await?;
Option 3: Server Mode (Full Features, Requires Setup)
Install SurrealDB
# macOS
brew install surrealdb
# Linux/WSL
cargo install surreal
# Windows
choco install surrealdb
# Verify
surreal version
Start Server
# Simple in-memory server
surreal start --bind 127.0.0.1:8000 memory
# File-based with persistence
surreal start --bind 127.0.0.1:8000 file:///tmp/surrealdb.db
# With authentication
surreal start \
--bind 127.0.0.1:8000 \
--username admin \
--password your_password \
file:///tmp/surrealdb.db
Connect from Application
// Update configs/database.toml:
// [surrealdb]
// url = "ws://localhost:8000"
// username = "admin"
// password = "your_password"
use workspace_core::SurrealDatabase;
#[tokio::main]
async fn main() -> Result<()> {
let db = SurrealDatabase::new_server(
"ws://localhost:8000",
"syntaxis",
"projects",
Some("admin"),
Some("your_password"),
).await?;
Ok(())
}
Core Operations
1. Create a Project
use workspace_core::{SurrealDatabase, DbProject};
use chrono::Utc;
use uuid::Uuid;
let db = SurrealDatabase::new_memory().await?;
let project = DbProject {
id: Uuid::new_v4().to_string(),
name: "My Project".to_string(),
version: "0.1.0".to_string(),
description: "A SurrealDB project".to_string(),
project_type: "MultiLang".to_string(),
current_phase: "Creation".to_string(),
created_at: Utc::now().to_rfc3339(),
updated_at: Utc::now().to_rfc3339(),
};
db.create_project(&project).await?;
println!("✓ Project created: {}", project.id);
2. Retrieve Projects
// Get all projects
let projects = db.list_projects().await?;
println!("Total projects: {}", projects.len());
// Get specific project
if let Some(project) = db.get_project(&project_id).await? {
println!("Project: {} (Phase: {})", project.name, project.current_phase);
} else {
println!("Project not found");
}
// Get projects by phase
for project in &projects {
if project.current_phase == "Development" {
println!(" - {} (in Development)", project.name);
}
}
3. Add Checklist Items
use workspace_core::DbChecklistItem;
let item = DbChecklistItem {
id: Uuid::new_v4().to_string(),
project_id: project.id.clone(),
phase: "Creation".to_string(),
task_id: "setup-1".to_string(),
description: "Initialize project structure".to_string(),
completed: false,
completed_at: None,
created_at: Utc::now().to_rfc3339(),
task_type: "Setup".to_string(),
task_priority: "High".to_string(),
task_due: Some("2025-12-31".to_string()),
task_estimation: Some("2d".to_string()),
task_deps: "[]".to_string(), // Comma-separated IDs
task_note: Some("Remember to test thoroughly".to_string()),
task_name: Some("Setup".to_string()),
};
db.create_checklist_item(&item).await?;
println!("✓ Added checklist item");
4. Track Progress
// Get checklist items for a phase
let items = db.get_checklist_items_by_phase(&project_id, "Creation").await?;
let completed = items.iter().filter(|i| i.completed).count();
println!("Progress: {}/{}", completed, items.len());
// Get completion percentage
let percentage = db.get_completion_percentage(&project_id, "Creation").await?;
println!("Phase completion: {:.1}%", percentage);
5. Record Phase Transition
use workspace_core::DbPhaseTransition;
let transition = DbPhaseTransition {
id: Uuid::new_v4().to_string(),
project_id: project.id.clone(),
from_phase: "Creation".to_string(),
to_phase: "Development".to_string(),
timestamp: Utc::now().to_rfc3339(),
reason: Some("Initial setup complete".to_string()),
};
db.record_phase_transition(&transition).await?;
println!("✓ Phase transitioned: Creation → Development");
6. Security Assessment
use workspace_core::DbSecurityAssessment;
let assessment = DbSecurityAssessment {
id: Uuid::new_v4().to_string(),
project_id: project.id.clone(),
profile: "OWASP".to_string(),
risk_level: "Medium".to_string(),
passed_rules: 45,
failed_rules: 5,
critical_issues: 0,
assessment_date: Utc::now().to_rfc3339(),
};
db.create_security_assessment(&assessment).await?;
println!("✓ Security assessment recorded");
Deployment Modes
Mode 1: Development (In-Memory)
# Perfect for: Testing, CI/CD, development without server
# In Rust:
let db = SurrealDatabase::new_memory().await?;
# No setup needed!
Pros:
- No server setup
- Very fast
- Perfect for testing
Cons:
- Data lost on restart
- Single process only
Mode 2: Local Development (File-Based)
# For local development with persistence
# Start server
surreal start --bind 127.0.0.1:8000 file://~/.local/share/surrealdb.db
# In configuration
[surrealdb]
url = "ws://localhost:8000"
Pros:
- Persistent data
- Can run alongside multiple processes
- Full server features
Cons:
- Requires server running
- Single machine only
Mode 3: Docker (Development/Testing)
# Start with Docker Compose
docker-compose -f docker-compose.surrealdb.yml up -d
# Check if running
docker-compose logs surrealdb
# Configuration
[surrealdb]
url = "ws://surrealdb:8000" # Container hostname
username = "admin"
password = "workspace_password_123"
Pros:
- Isolated environment
- Reproducible setup
- Matches production
Cons:
- Requires Docker
- Slightly more overhead
Mode 4: Kubernetes (Production)
# Deploy to Kubernetes cluster
cd k8s && ./deploy.sh
# Configuration
[surrealdb]
url = "ws://surrealdb.workspace:8000" # K8s service DNS
username = "admin"
password = "${SURREALDB_PASSWORD}" # From k8s secret
tls_enabled = true
Pros:
- Production-grade
- Scalable
- Managed infrastructure
Cons:
- Complex setup
- Requires K8s knowledge
Configuration Examples
Example 1: Local Development
File: configs/database.toml
[database]
engine = "surrealdb"
[surrealdb]
url = "mem://" # In-memory, no server needed
namespace = "syntaxis"
database = "projects"
max_connections = 5
Example 2: Docker Development
File: configs/database.toml
[database]
engine = "surrealdb"
[surrealdb]
url = "ws://surrealdb:8000"
username = "admin"
password = "dev_password"
namespace = "syntaxis"
database = "projects"
max_connections = 10
Example 3: Production (Kubernetes)
File: configs/database.toml
[database]
engine = "surrealdb"
[surrealdb]
url = "ws://surrealdb.workspace:8000"
username = "admin"
password = "${SURREALDB_PASSWORD}" # Environment variable
namespace = "syntaxis"
database = "projects"
max_connections = 20
timeout_secs = 60
tls_enabled = true
tls_ca_cert = "/etc/surrealdb/ca.pem"
Testing with SurrealDB
In-Memory Tests
#[tokio::test]
async fn test_project_lifecycle() {
// No setup needed - in-memory database
let db = SurrealDatabase::new_memory().await.unwrap();
// Create project
let project = DbProject {
id: "test-1".to_string(),
name: "Test Project".to_string(),
// ... other fields ...
};
let created = db.create_project(&project).await.unwrap();
assert_eq!(created.name, "Test Project");
// Verify retrieval
let retrieved = db.get_project("test-1").await.unwrap();
assert!(retrieved.is_some());
}
Server-Mode Tests
#[tokio::test]
async fn test_with_server() {
// Requires: surreal start --bind 127.0.0.1:8000 memory
let db = SurrealDatabase::new_server(
"ws://localhost:8000",
"syntaxis",
"projects",
None,
None,
).await.unwrap();
// Run your tests...
}
File-Based Tests
#[tokio::test]
async fn test_persistence() {
let db_path = "/tmp/test_surrealdb.db";
let db = SurrealDatabase::new_file(db_path).await.unwrap();
// Create data
let project = DbProject { /* ... */ };
db.create_project(&project).await.unwrap();
// Reload and verify persistence
let db2 = SurrealDatabase::new_file(db_path).await.unwrap();
let retrieved = db2.get_project(&project.id).await.unwrap();
assert!(retrieved.is_some());
}
Switching Between Backends
SQLite to SurrealDB
# Step 1: Update configuration
# configs/database.toml - change engine from "sqlite" to "surrealdb"
# Step 2: Start SurrealDB server
surreal start --bind 127.0.0.1:8000 file:///data/surrealdb.db
# Step 3: Run application with new config
RUST_LOG=info cargo run
# Step 4: Migration (if needed)
# See: SURREALDB_2_3_MIGRATION.md
Quick Switching Script
#!/bin/bash
# Switch between database backends
case "$1" in
sqlite)
echo "Switching to SQLite..."
cp configs/database.toml configs/database.toml.backup
cp configs/database-default.toml configs/database.toml
echo "✓ Using SQLite"
;;
surrealdb)
echo "Switching to SurrealDB..."
cp configs/database.toml configs/database.toml.backup
cp configs/database-surrealdb.toml configs/database.toml
echo "Starting SurrealDB server..."
surreal start --bind 127.0.0.1:8000 memory &
echo "✓ Using SurrealDB"
;;
*)
echo "Usage: $0 {sqlite|surrealdb}"
;;
esac
Troubleshooting
"Connection refused" Error
# Check if SurrealDB is running
ps aux | grep surreal
# If not, start it
surreal start --bind 127.0.0.1:8000 memory
# Test connection
curl http://localhost:8000/health
# Should return: {"status":"ok"}
"Authentication failed" Error
// Make sure credentials match server startup
let db = SurrealDatabase::new_server(
"ws://localhost:8000",
"syntaxis",
"projects",
Some("admin"), // Must match --username
Some("your_password"), // Must match --password
).await?;
"Database already in use" Error
# Port 8000 is already in use
# Use a different port
surreal start --bind 127.0.0.1:8001 memory
# Update configuration
[surrealdb]
url = "ws://localhost:8001" # New port
Slow Queries
# Enable query logging
surreal start --log debug --bind 127.0.0.1:8000 memory
# Check output for slow queries in logs
Common Patterns
Pattern 1: Batch Operations
async fn create_multiple_items(
db: &dyn Database,
items: Vec<DbChecklistItem>,
) -> Result<()> {
for item in items {
db.create_checklist_item(&item).await?;
}
Ok(())
}
Pattern 2: Error Handling
use workspace_core::error::LifecycleError;
match db.get_project(&id).await {
Ok(Some(project)) => println!("Found: {}", project.name),
Ok(None) => println!("Project not found"),
Err(LifecycleError::Database(msg)) => eprintln!("DB error: {}", msg),
Err(e) => eprintln!("Other error: {}", e),
}
Pattern 3: Configuration-Driven
use workspace_core::DatabaseConfig;
let config = DatabaseConfig::load_from_file("configs/database.toml")?;
let db = match config.engine.as_str() {
"surrealdb" => {
let surreal_config = config.surrealdb.ok_or("No SurrealDB config")?;
SurrealDatabase::new_server(
&surreal_config.url,
&surreal_config.namespace,
&surreal_config.database,
surreal_config.username,
surreal_config.password,
).await?
}
"sqlite" => {
// ... SQLite setup ...
}
_ => return Err("Unknown database engine".into()),
};
Performance Tips
1. Use Connection Pooling
[surrealdb]
max_connections = 20 # Tune based on load
timeout_secs = 60 # Increase for slow networks
2. Batch Operations
// Good: Multiple operations
for item in items {
db.create_checklist_item(&item).await?;
}
// Could be optimized with batch API (if available)
3. Index Critical Fields
-- In SurrealDB SQL
DEFINE INDEX idx_project_phase ON TABLE projects COLUMNS current_phase;
DEFINE INDEX idx_item_project ON TABLE checklist_items COLUMNS project_id;
Next Steps
-
Choose Deployment Mode
- Development:
mem://(in-memory, fastest) - Testing:
file://(persistent, local) - Production: Server mode with Docker/K8s
- Development:
-
Configure Application
- Copy appropriate config template
- Update
configs/database.toml - Set environment variables if needed
-
Test Connection
- Run:
cargo run -p syntaxis-cli - Execute:
syntaxis-cli checklist show - Verify: Data is being stored
- Run:
-
Learn More
- SURREALDB_SETUP_GUIDE.md - Detailed setup
- SURREALDB_2_3_MIGRATION.md - Migration guide
- PERSISTENCE_QUICK_START.md - Generic DB usage
References
- Official: https://surrealdb.com/
- Docs: https://surrealdb.com/docs
- GitHub: https://github.com/surrealdb/surrealdb
- Docker: https://hub.docker.com/r/surrealdb/surrealdb
Status: ✅ Production Ready Last Updated: November 15, 2025 SurrealDB Version: 2.3