# 🚀 WOWSQL Rust SDK
Official Rust SDK for [WOWSQL](https://wowsql.com) - MySQL Backend-as-a-Service with S3 Storage.
[](https://crates.io/crates/WOWSQL)
[](https://opensource.org/licenses/MIT)
[](https://www.rust-lang.org/)
## ✨ Features
### Database Features
- 🗄️ Full CRUD operations (Create, Read, Update, Delete)
- 🔍 Advanced filtering (eq, neq, gt, gte, lt, lte, like, isNull)
- 📄 Pagination (limit, offset)
- 📊 Sorting (orderBy)
- 🎯 Fluent query builder API
- 🔒 Type-safe queries with Serde
- ⚡ async/await support
- 📝 Raw SQL queries
- 📋 Table schema introspection
### Storage Features
- 📦 S3-compatible storage for file management
- ⬆️ File upload with automatic quota validation
- ⬇️ File download (presigned URLs)
- 📂 File listing with metadata
- 🗑️ File deletion (single and batch)
- 📊 Storage quota management
## 📦 Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
WOWSQL = "1.0"
tokio = { version = "1.0", features = ["full"] }
```
## 🚀 Quick Start
### Database Operations
```rust
use WOWSQL::WOWSQLClient;
use serde_json::Value;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = WOWSQLClient::new(
"https://your-project.wowsql.com",
"your-api-key"
)?;
// Query data
let response = client.table("users")
.select(&["id", "name", "email"])
.eq("status", "active")
.limit(10)
.execute::<Value>()
.await?;
println!("Found {} users", response.count);
for user in response.data {
println!("{:?}", user);
}
Ok(())
}
```
### Storage Operations
```rust
use WOWSQL::WOWSQLStorage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let storage = WOWSQLStorage::new(
"https://your-project.wowsql.com",
"your-api-key"
)?;
// Upload file
let file_data = std::fs::read("document.pdf")?;
let result = storage.upload_bytes(
&file_data,
"uploads/document.pdf",
Some("application/pdf")
).await?;
println!("Uploaded: {}", result.url);
// Check quota
let quota = storage.get_quota().await?;
println!("Storage used: {}GB / {}GB",
quota.storage_used_gb, quota.storage_quota_gb);
Ok(())
}
```
## 🔧 Schema Management
Programmatically manage your database schema with the `WOWSQLSchema` client.
> **⚠️ IMPORTANT**: Schema operations require a **Service Role Key** (`service_*`). Anonymous keys will return a 403 Forbidden error.
### Quick Start
```rust
use WOWSQL::WOWSQLSchema;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize schema client with SERVICE ROLE KEY
let schema = WOWSQLSchema::new(
"https://your-project.wowsql.com",
"service_xyz789..." // ⚠️ Backend only! Never expose!
)?;
Ok(())
}
```
### Create Table
```rust
use WOWSQL::{WOWSQLSchema, CreateTableRequest, ColumnDefinition, IndexDefinition};
// Create a new table
schema.create_table(CreateTableRequest {
table_name: "products".to_string(),
columns: vec![
ColumnDefinition {
name: "id".to_string(),
column_type: "INT".to_string(),
auto_increment: Some(true),
..Default::default()
},
ColumnDefinition {
name: "name".to_string(),
column_type: "VARCHAR(255)".to_string(),
not_null: Some(true),
..Default::default()
},
ColumnDefinition {
name: "price".to_string(),
column_type: "DECIMAL(10,2)".to_string(),
not_null: Some(true),
..Default::default()
},
ColumnDefinition {
name: "created_at".to_string(),
column_type: "TIMESTAMP".to_string(),
default: Some("CURRENT_TIMESTAMP".to_string()),
..Default::default()
},
],
primary_key: Some("id".to_string()),
indexes: Some(vec![
IndexDefinition {
name: "idx_price".to_string(),
columns: vec!["price".to_string()],
},
]),
}).await?;
println!("Table created successfully!");
```
### Alter Table
```rust
use WOWSQL::AlterTableRequest;
// Add a new column
schema.alter_table(AlterTableRequest {
table_name: "products".to_string(),
add_columns: Some(vec![
ColumnDefinition {
name: "stock_quantity".to_string(),
column_type: "INT".to_string(),
default: Some("0".to_string()),
..Default::default()
},
]),
..Default::default()
}).await?;
// Drop a column
schema.alter_table(AlterTableRequest {
table_name: "products".to_string(),
drop_columns: Some(vec!["category".to_string()]),
..Default::default()
}).await?;
```
### Drop Table
```rust
// Drop a table
schema.drop_table("old_table", false).await?;
// Drop with CASCADE
schema.drop_table("products", true).await?;
```
### Execute Raw SQL
```rust
// Execute custom schema SQL
schema.execute_sql(r#"
CREATE INDEX idx_product_name
ON products(product_name);
"#).await?;
```
### Security & Best Practices
#### ✅ DO:
- Use service role keys **only in backend/server code**
- Store service keys in environment variables
- Test schema changes in development first
#### ❌ DON'T:
- Never expose service role keys in client code
- Never commit service keys to version control
- Don't use anonymous keys for schema operations (will fail)
### Example: Backend Migration Script
```rust
use WOWSQL::{WOWSQLSchema, CreateTableRequest, ColumnDefinition, IndexDefinition};
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let schema = WOWSQLSchema::new(
&env::var("WOWSQL_PROJECT_URL")?,
&env::var("WOWSQL_SERVICE_KEY")? // From env var
)?;
// Create users table
schema.create_table(CreateTableRequest {
table_name: "users".to_string(),
columns: vec![
ColumnDefinition {
name: "id".to_string(),
column_type: "INT".to_string(),
auto_increment: Some(true),
..Default::default()
},
ColumnDefinition {
name: "email".to_string(),
column_type: "VARCHAR(255)".to_string(),
unique: Some(true),
not_null: Some(true),
..Default::default()
},
],
primary_key: Some("id".to_string()),
indexes: Some(vec![
IndexDefinition {
name: "idx_email".to_string(),
columns: vec!["email".to_string()],
},
]),
}).await?;
println!("Migration completed!");
Ok(())
}
```
---
## 📚 Documentation
## 🔑 Unified Authentication
**✨ One Project = One Set of Keys for ALL Operations**
WOWSQL uses **unified authentication** - the same API keys work for both database operations AND authentication operations.
### Key Types
1. **Anonymous Key** (`wowsql_anon_...`) ✨ **Unified Key**
- Used for:
- ✅ Client-side auth operations (signup, login, OAuth)
- ✅ Public/client-side database operations with limited permissions
- **Safe to expose** in frontend code (browser, mobile apps)
2. **Service Role Key** (`wowsql_service_...`) ✨ **Unified Key**
- Used for:
- ✅ Server-side auth operations (admin, full access)
- ✅ Server-side database operations (full access, bypass RLS)
- **NEVER expose** in frontend code - server-side only!
### Usage Example
```rust
use WOWSQL::{WOWSQLClient, ProjectAuthClient, ProjectAuthConfig};
// Database operations
let db_client = WOWSQLClient::new(
"https://your-project.wowsql.com",
"wowsql_anon_..." // Anonymous Key
)?;
// Authentication operations - SAME KEY!
let auth_config = ProjectAuthConfig {
project_url: "your-project".to_string(),
api_key: Some("wowsql_anon_...".to_string()), // Same Anonymous Key
..Default::default()
};
let auth_client = ProjectAuthClient::new(auth_config)?;
```
**Note:** The `public_api_key` parameter is deprecated but still works for backward compatibility. Use `api_key` instead.
Full documentation available at: https://wowsql.com/docs/rust
## 📄 License
MIT License - see [LICENSE](LICENSE) file for details.
---
Made with ❤️ by the WOWSQL Team