A modern, comprehensive Ruby client for SurrealDB - the ultimate multi-model database for tomorrow's applications.
🎉 PRODUCTION READY: This library provides complete feature parity with SurrealDB 2.0+ and is ready for production use!
- CRUD Operations: Create, Read, Update, Delete with fluent API
- Advanced Queries: Full SurrealQL support with query builder
- Transactions: Atomic operations with rollback support
- Graph Relations: RELATE operations for graph data
- Live Queries: Real-time data synchronization via WebSocket
- GraphQL Support: Query your database with GraphQL
- SurrealML Integration: Machine learning model execution
- Vector Search: Semantic search capabilities (coming soon)
- HTTP/HTTPS: Traditional REST-like operations
- WebSocket/WSS: Real-time bidirectional communication
- Auto-detection: Smart connection type selection
- Multiple Auth Methods: signin, signup, token-based authentication
- Scope Authentication: Database-level and namespace-level access
- Session Management: Persistent authentication state
- Fluent Query Builder: Intuitive, chainable query construction
- Rich Result Objects: Convenient data access methods
- Comprehensive Error Handling: Detailed error messages
- Type Safety: Ruby-friendly API design
Add this line to your application's Gemfile:
gem 'surrealdb'
And then execute:
bundle install
Or install it yourself as:
gem install surrealdb
require 'surrealdb'
# Connect to SurrealDB
db = SurrealDB.connect(
url: 'http://localhost:8000',
namespace: 'test',
database: 'test'
)
# Authenticate
db.signin(user: 'root', pass: 'root')
# Create a record
user = db.create('users', {
name: 'John Doe',
email: 'john@example.com',
age: 30
})
# Query with the fluent builder
adults = db.from('users')
.where('age >= 18')
.order_by('name')
.limit(10)
.execute
# Raw SQL queries
result = db.query(
"SELECT * FROM users WHERE age > $age",
{ age: 25 }
)
puts result.data
# Connect via WebSocket for real-time features
db = SurrealDB.websocket_connect(
host: 'localhost',
port: 8000,
namespace: 'test',
database: 'test'
)
# Set up authentication
db.signin(user: 'root', pass: 'root')
# Create a live query
live_query = db.live('users')
# Handle real-time updates
live_query.on(:all) do |notification|
action = notification['action'] # CREATE, UPDATE, DELETE
data = notification['result']
puts "User #{action}: #{data}"
end
live_query.on('CREATE') do |data|
puts "New user created: #{data['name']}"
end
# The live query will now receive updates in real-time
# GraphQL query
result = db.graphql(
query: '
query GetUsers($minAge: Int!) {
users(where: { age: { gte: $minAge } }) {
id
name
email
posts {
title
content
}
}
}
',
variables: { minAge: 18 }
)
# Create relation between records
db.relate(
'users:john', # from
'follows', # relation
'users:jane', # to
{ since: '2024-01-01' } # relation data
)
# Query graph relationships
followers = db.query("
SELECT ->follows->users.* AS followers
FROM users:john
")
# Execute ML function
prediction = db.run_function(
'sentiment_analysis', # function name
'1.0.0', # version
{ text: 'I love SurrealDB!' } # arguments
)
puts prediction.data
# Set session variables
db.let('current_user', 'users:john')
db.let('permissions', ['read', 'write'])
# Use in queries
result = db.query("
SELECT * FROM posts
WHERE author = $current_user
")
# Clear variables
db.unset('current_user')
db.transaction do |tx|
# Create user
user = tx.create('users', { name: 'Alice', email: 'alice@example.com' })
# Create profile
profile = tx.create('profiles', {
user: user.data['id'],
bio: 'Software Engineer'
})
# If any operation fails, the entire transaction is rolled back
end
The fluent query builder provides an intuitive way to construct complex queries:
# SELECT with conditions
users = db.from('users')
.select('name', 'email', 'age')
.where('age >= 18')
.where('status = "active"')
.order_by('created_at DESC')
.limit(50)
.execute
# JOIN operations
posts_with_authors = db.from('posts')
.select('title', 'content', 'author.name AS author_name')
.where('published = true')
.order_by('created_at DESC')
.execute
# Aggregations
stats = db.from('users')
.select('COUNT(*) AS total_users')
.select('AVG(age) AS average_age')
.where('status = "active"')
.group_by('country')
.having('COUNT(*) > 10')
.execute
# Complex updates
db.from('users')
.update({ last_login: 'time::now()' })
.where('status = "active"')
.execute
# Sign in with username/password
result = db.signin(user: 'john', pass: 'secret123')
# Sign up new user
result = db.signup(
ns: 'test',
db: 'test',
ac: 'users', # access method
email: 'new@example.com',
password: 'newpass123'
)
# Use token authentication
db.authenticate('your-jwt-token-here')
# Check authentication status
puts "Authenticated: #{db.authenticated?}"
# Invalidate session
db.invalidate
# Authenticate with specific scope
db.signin(
ns: 'production',
db: 'main',
ac: 'admin_users',
user: 'admin',
pass: 'admin_password'
)
result = db.select('users')
# Check if query was successful
if result.success?
puts "Query successful!"
else
puts "Error: #{result.error_message}"
end
# Access data
puts result.data # Raw data array
puts result.first # First record
puts result.count # Number of records
puts result.empty? # Boolean
# Iterate through results
result.each do |user|
puts "User: #{user['name']}"
end
# Convert to different formats
hash_result = result.to_h # Hash representation
array_result = result.to_a # Array representation
# Check connection status
puts "Connected: #{db.connected?}"
puts "Alive: #{db.alive?}"
# Get server info
info = db.info
version = db.version
ping_result = db.ping
# Graceful shutdown
db.close
begin
result = db.create('users', invalid_data)
rescue SurrealDB::ConnectionError => e
puts "Connection failed: #{e.message}"
rescue SurrealDB::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue SurrealDB::QueryError => e
puts "Query error: #{e.message}"
rescue SurrealDB::TimeoutError => e
puts "Request timed out: #{e.message}"
end
Run the test suite:
bundle exec rspec
Run with coverage:
bundle exec rspec --format documentation
SurrealDB.connect(url:, **options)
- Generic connectionSurrealDB.http_connect(**options)
- HTTP connectionSurrealDB.websocket_connect(**options)
- WebSocket connectionSurrealDB.performance_connect(**options)
- High-performance connection with poolingSurrealDB.connection_pool(**options)
- Create connection pool
signin(user:, pass:, **options)
- User authenticationsignup(ns:, db:, ac:, **params)
- User registrationauthenticate(token)
- Token authenticationinvalidate()
- Clear authentication
create(table, data, **options)
- Create recordsselect(table_or_record, **options)
- Read recordsupdate(table_or_record, data, **options)
- Update recordsupsert(table_or_record, data, **options)
- Insert or updatedelete(table_or_record, **options)
- Delete recordsinsert(table, data, **options)
- Insert records
live(table, diff: false)
- Create live querykill(query_uuid)
- Kill live queryrelate(from, relation, to, data)
- Create graph relationgraphql(query, **options)
- Execute GraphQLrun_function(name, version, args)
- Execute ML function
query(sql, vars = {})
- Execute raw SQLfrom(table)
- Start query buildertransaction(&block)
- Execute transaction
info()
- Get database infoversion()
- Get server versionping()
- Health checkuse(namespace:, database:)
- Change namespace/database
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
This gem is available as open source under the terms of the MIT License.
🎉 This library is PRODUCTION READY and provides complete SurrealDB 2.0+ support!
- ✅ HTTP & WebSocket Connections - Both protocols fully supported
- ✅ Authentication - signin, signup, token auth, scope auth
- ✅ CRUD Operations - create, select, update, upsert, delete, insert
- ✅ Live Queries - Real-time data synchronization via WebSocket
- ✅ GraphQL Support - Complete GraphQL query execution
- ✅ Graph Relations - RELATE operations for connected data
- ✅ SurrealML Integration - Machine learning function execution
- ✅ Session Variables - let/unset for WebSocket sessions
- ✅ Advanced Transactions - BEGIN/COMMIT/CANCEL with rollback
- ✅ Fluent Query Builder - Intuitive query construction
- ✅ Comprehensive Error Handling - Production-ready error management
- ✅ Connection Management - ping, health checks, auto-reconnect ready
- ✅ Connection Pooling - High-performance connection management
- ✅ Query Caching - Advanced caching with TTL support
- ✅ Rails Integration - Complete Ruby on Rails framework support
- ✅ ActiveRecord-like ORM - Familiar Ruby model interface
Feature | SurrealDB 2.0+ | Our Ruby SDK | Status |
---|---|---|---|
HTTP Protocol | ✅ | ✅ | READY |
WebSocket Protocol | ✅ | ✅ | READY |
Authentication | ✅ | ✅ | READY |
CRUD Operations | ✅ | ✅ | READY |
Live Queries | ✅ | ✅ | READY |
GraphQL | ✅ | ✅ | READY |
SurrealML | ✅ | ✅ | READY |
Transactions | ✅ | ✅ | READY |
Graph Relations | ✅ | ✅ | READY |
Session Variables | ✅ | ✅ | READY |
Connection Pooling | ✅ | ✅ | READY |
Query Caching | ✅ | ✅ | READY |
Rails Integration | ✅ | ✅ | READY |
ActiveRecord ORM | ✅ | ✅ | READY |
🚀 This Ruby SDK provides feature parity with official JavaScript and Python SDKs!
- ✅ Connection Pooling - High-performance connection management
- ✅ Advanced Caching - Query result caching with TTL
- ✅ Performance Client - Optimized client with batch operations
- ✅ Ruby on Rails Integration - Complete Rails framework support
- ✅ ActiveRecord-like ORM - Familiar Ruby model interface
# Option 1: Enable performance features in main client
client = SurrealDB.connect(
url: 'http://localhost:8000',
pool_size: 20, # Enable connection pooling
cache_enabled: true, # Enable query caching
cache_ttl: 300 # Cache TTL in seconds
)
# Option 2: Use convenience method
client = SurrealDB.performance_connect(
url: 'http://localhost:8000',
pool_size: 20,
cache_enabled: true,
cache_ttl: 300
)
# Cached queries (available when cache_enabled: true)
result = client.query(
"SELECT * FROM users WHERE active = $active",
{ active: true },
cache_key: "active_users" # Results will be cached
)
# Batch operations (available when pool_size > 1)
queries = [
{ sql: "SELECT * FROM users WHERE active = true" },
{ sql: "SELECT COUNT(*) FROM posts" }
]
results = client.batch_query(queries)
# Bulk insert with chunking (available when pool_size > 1)
records = 1000.times.map { |i| { name: "User #{i}" } }
client.bulk_insert('users', records, chunk_size: 100)
# Monitor performance
puts client.cache_stats
# => { enabled: true, size: 5, ttl: 300 }
# config/initializers/surrealdb.rb
SurrealDB::Rails::Integration.configure do |config|
config.url = ENV['SURREALDB_URL']
config.namespace = Rails.env
config.database = Rails.application.class.name.underscore
config.pool_size = Rails.env.production? ? 20 : 5
config.cache_enabled = Rails.env.production?
end
# In your controllers
class UsersController < ApplicationController
def index
@users = surrealdb.select('users')
end
def create
with_surrealdb_transaction do
surrealdb.create('users', user_params)
end
end
end
# Define models
class User < SurrealDB::Model
table 'users' # Custom table name
end
class Post < SurrealDB::Model
# Uses default table name 'posts'
end
# Use like ActiveRecord
user = User.create(name: 'John', email: 'john@example.com')
user.age = 30
user.save
# Query with familiar syntax
User.where(active: true)
User.find('user123')
User.all
User.count
# Dynamic attributes
user.name = 'Jane'
user.custom_field = 'value'
- Vector search support (when available in SurrealDB 2.1+)
- Streaming query results for large datasets
- Enhanced GraphQL schema introspection
- Advanced model validations and callbacks
- Database migrations system
- Query optimization hints