wowsql 3.0.0

Official Rust SDK for WOWSQL - MySQL Backend-as-a-Service with S3 Storage
Documentation
# WowSQL Rust SDK


Official Rust client for [WowSQL](https://wowsql.com) — PostgreSQL backend-as-a-service with project auth, object storage, and schema management.

**Crate:** `wowsql` · **Edition:** 2021 · **Rust:** 1.70+ recommended

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

---

## Table of contents


1. [Installation]#installation
2. [Quick start]#quick-start
3. [Concepts & API keys]#concepts--api-keys
4. [Database: `WOWSQLClient`]#database-wowsqlclient
5. [Table & `QueryBuilder`]#table--querybuilder
6. [Authentication: `AuthClient`]#authentication-authclient
7. [Storage: `StorageClient`]#storage-storageclient
8. [Schema: `SchemaClient`]#schema-schemaclient
9. [Models & enums]#models--enums
10. [Errors]#errors
11. [Features]#features-cargo
12. [Examples]#examples
13. [Links]#links

---

## Installation


`Cargo.toml`:

```toml
[dependencies]
wowsql = "1.3"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
serde_json = "1"
```

Async methods are `async` and return `Result<_, wowsql::WOWSQLError>` (or specialized storage/schema errors where noted).

---

## Quick start


```rust
use serde_json::{json, Value};
use wowsql::WOWSQLClient;

#[tokio::main]

async fn main() -> Result<(), wowsql::WOWSQLError> {
    let client = WOWSQLClient::new(
        "https://your-project.wowsql.com",
        std::env::var("WOWSQL_SERVICE_KEY").unwrap().as_str(),
    )?;

    let res = client
        .table("posts")
        .select(&["id", "title"])
        .eq("published", json!(true))
        .limit(10)
        .execute::<Value>()
        .await?;

    println!("rows: {}", res.count);
    Ok(())
}
```

---

## Concepts & API keys


| Key | Prefix | Use |
|-----|--------|-----|
| Anonymous | `wowsql_anon_…` | Client-side auth; limited DB access |
| Service role | `wowsql_service_…` | **Server only** — full DB, storage, **schema DDL** |

- `SchemaClient` **must** use a **service role** key.
- End-user JWTs from `AuthClient` are for your app session — use **API keys** for `WOWSQLClient` / `StorageClient` from backends (same model as other official SDKs).

---

## Database: `WOWSQLClient`


### Construction


```rust
use wowsql::WOWSQLClient;

// Simple
let client = WOWSQLClient::new(project_url, api_key)?;

// Builder
let client = WOWSQLClient::builder(project_url, api_key)
    .base_domain("wowsql.com")
    .secure(true)
    .timeout(30)
    .verify_ssl(true)
    .build()?;
```

### Methods


| Method | Returns | Description |
|--------|---------|-------------|
| `table(&self, name: &str) -> Table` | `Table` | Query/CRUD for one table. |
| `list_tables(&self).await` | `Vec<String>` | |
| `get_table_schema(&self, name).await` | `TableSchema` | |
| `query<T: DeserializeOwned>(&self, sql).await` | `Vec<T>` | Raw SQL helper when enabled. |
| `health(&self).await` | `serde_json::Value` | |
| `close(self)` || |

---

## Table & `QueryBuilder`


### `Table`


| Method | Returns |
|--------|---------|
| `select(&[&str]) -> QueryBuilder` | Starts builder. |
| `filter(column, FilterOperator, value, logical_op?)` | |
| `get() -> QueryBuilder` | Empty select pipeline. |
| `get_by_id(id).await` | `serde_json::Value` |
| `create` / `insert` | `CreateResponse` |
| `bulk_insert(records).await` | `serde_json::Value` |
| `upsert(data, on_conflict).await` | `serde_json::Value` |
| `update(id, data).await` | `UpdateResponse` |
| `delete(id).await` | `DeleteResponse` |
| `eq`, `neq`, `gt`, `gte`, `lt`, `lte` | `QueryBuilder` |
| `order_by(column, SortDirection)` | `QueryBuilder` |
| `count().await` | `usize` |
| `paginate(page, per_page).await` | `PaginatedResponse<T>` |
| `where()` | `QueryBuilder` (named `r#where` in Rust) |

### `QueryBuilder` (owned / consuming)


Chain: `select`, `filter`, `eq`, …, `group_by`, `having`, `order_by` / `order`, `order_by_multiple`, `limit`, `offset`.

**Terminal (consume `self`):**

- `execute::<T>()`, `get::<T>()`
- `first::<T>()`, `single::<T>()`
- `count()`
- `paginate::<T>(page, per_page)`

**Mutations on builder:** `create`, `insert`, `update`, `delete` (when supported by implementation).

### `FilterOperator` & `SortDirection`


`FilterOperator`: `Eq`, `Neq`, `Gt`, `Gte`, `Lt`, `Lte`, `Like`, `IsNull`, `In`, `NotIn`, `Between`, `NotBetween`, `IsNot`.

`SortDirection`: `Asc`, `Desc`.

---

## Authentication: `AuthClient`


```rust
use wowsql::{AuthClient, AuthClientBuilder, MemoryTokenStorage, TokenStorage};
use std::sync::Arc;

let auth = AuthClient::builder(project_url, anon_key)
    .base_domain("wowsql.com")
    .timeout(30)
    .token_storage(Arc::new(MemoryTokenStorage::new()))
    .build()?;
```

### `TokenStorage` trait


`Send + Sync`: `get_access_token`, `get_refresh_token`, `set_tokens`, `clear`.

### Methods (async unless noted)


| Method | Returns |
|--------|---------|
| `sign_up(email, password, full_name, user_metadata).await` | `AuthResponse` |
| `sign_in(email, password).await` | `AuthResponse` |
| `get_user(access_token?).await` | `AuthUser` |
| `get_oauth_authorization_url(provider, redirect_uri?).await` | `HashMap<String, Value>` |
| `exchange_oauth_callback(provider, code, redirect_uri?).await` | `AuthResponse` |
| `forgot_password`, `reset_password` | `HashMap<String, Value>` |
| `send_otp`, `verify_otp`, `send_magic_link`, `verify_email`, `resend_verification` | mixed |
| `logout`, `refresh_token`, `change_password` | mixed |
| `update_user(options: Value).await` | `AuthUser` |
| `get_session()` | `Option<AuthSession>` |
| `set_session`, `clear_session` | |

---

## Storage: `StorageClient`


```rust
use wowsql::StorageClient;

let storage = StorageClient::builder(project_url, api_key)
    .base_domain("wowsql.com")
    .timeout(60)
    .build()?;
```

| Method | Returns |
|--------|---------|
| `create_bucket(name, options?).await` | `StorageBucket` |
| `list_buckets().await` | `Vec<StorageBucket>` |
| `get_bucket(name).await` | `StorageBucket` |
| `update_bucket(name, options).await` | `StorageBucket` |
| `delete_bucket(name).await` | `serde_json::Value` |
| `upload(bucket, data: &[u8], path?, file_name?).await` | `FileUploadResult` |
| `upload_from_path(path, bucket, remote_path?).await` | `FileUploadResult` |
| `list_files(bucket, options?).await` | `Vec<StorageFile>` |
| `download(bucket, path).await` | `Vec<u8>` |
| `download_to_file(bucket, path, local_path).await` | `()` |
| `delete_file(bucket, path).await` | `serde_json::Value` |
| `get_public_url(bucket, path)` | `String` |
| `get_stats().await` | `StorageStats` |
| `get_quota().await` | `StorageQuota` |

---

## Schema: `SchemaClient`


**Requires service role key.**

```rust
use wowsql::{SchemaClient, ColumnDefinition};

let schema = SchemaClient::builder(project_url, service_key)
    .base_domain("wowsql.com")
    .build()?;

schema
    .create_table(
        "items",
        vec![
            ColumnDefinition::new("id", "SERIAL").auto_increment(true),
            ColumnDefinition::new("name", "TEXT").not_null(true),
        ],
        Some("id"),
        None,
    )
    .await?;
```

| Method | Returns |
|--------|---------|
| `create_table` | `SchemaResponse` |
| `alter_table` | `SchemaResponse` |
| `drop_table` | `SchemaResponse` |
| `execute_sql` | `SchemaResponse` |
| `add_column`, `drop_column`, `rename_column`, `modify_column` | `SchemaResponse` |
| `create_index` | `SchemaResponse` |
| `list_tables().await` | `Vec<String>` |
| `get_table_schema(name).await` | `TableSchema` |

Helpers: `ColumnDefinition`, `CreateTableRequest`, `AlterTableRequest`, `IndexDefinition`, `RenameColumn`, `SchemaResponse`.

---

## Models & enums


Exported from `wowsql::models`: `QueryResponse`, `CreateResponse`, `UpdateResponse`, `DeleteResponse`, `PaginatedResponse`, `TableSchema`, `ColumnInfo`, `FilterExpression`, `HavingFilter`, `OrderByItem`, `AuthUser`, `AuthSession`, `AuthResponse`, `OAuthAuthorizationResponse`, `StorageBucket`, `StorageFile`, `StorageQuota`, `StorageStats`, `FileUploadResult`, etc.

---

## Errors


- `WOWSQLError` — main error type; `new`, `from_response`, `is_authentication`, `is_not_found`, `is_rate_limit`.
- `StorageError`, `StorageLimitExceededError`
- `SchemaPermissionError`

`From` conversions exist for `reqwest::Error` and storage/schema errors where implemented.

Use `?` in async functions or match on `e` for status / body.

---

## Features (Cargo)


Default features match `Cargo.toml`. Add `serde` types in your app for typed rows; SDK uses `serde_json::Value` in many places.

---

## Examples


### Paginated list


```rust
let page = client
    .table("orders")
    .select(&["id", "total"])
    .gte("total", json!(10))
    .order_by("id", wowsql::SortDirection::Desc)
    .paginate::<Value>(1, 20)
    .await?;
```

### Auth sign-in


```rust
let session = auth.sign_in("a@b.com", "secret").await?.session.unwrap();
auth.set_session(&session.access_token, &session.refresh_token);
```

---

## Links


- [Documentation]https://wowsql.com/docs
- [Website]https://wowsql.com

**License:** MIT