Java SDK (Coming Soon)

Java Quick Start

WowSQL Java SDK — Get started in minutes

Get your API keys: In your WowSQL project dashboard, go to Settings → API to find your anon key (wowsql_anon_...) and service role key (wowsql_service_...). The anon key is safe for client-side use (respects Row Level Security). The service role key bypasses RLS and should only be used server-side.

Installation

Official package: View on Maven Central →

Maven:

<dependency>
  <groupId>com.WowSQL</groupId>
  <artifactId>WowSQL-sdk</artifactId>
  <version>1.0.0</version>
</dependency>

Gradle:

implementation 'com.WowSQL:WowSQL-sdk:1.0.0'

Initialize Client

The SDK talks to PostgREST at /rest/v1/ under the hood. Your project URL resolves to https://myproject.wowsqlconnect.com.

import com.WowSQL.WowSQLClient;
import com.WowSQL.models.QueryResponse;
import java.util.*;

// Initialize client — URL resolves to https://myproject.wowsqlconnect.com
// SDK communicates with PostgREST at /rest/v1/
WowSQLClient client = new WowSQLClient(
    "https://myproject.wowsqlconnect.com",
    "wowsql_anon_your_key_here"
);

// Always use select() before get()/execute()
QueryResponse<?> users = client.table("users").select("*").limit(10).get();

Query Data

Basic Queries

// Get all records
QueryResponse<?> users = client.table("users").select("*").get();

// With filters
QueryResponse<?> adults = client.table("users")
    .select("*")
    .filter("age", "gte", 18)
    .get();

// Select specific columns
QueryResponse<?> names = client.table("users").select("id", "name").get();

Advanced Queries

// Multiple filters with sorting
QueryResponse<?> activeUsers = client.table("users")
    .select("*")
    .filter("status", "eq", "active")
    .filter("age", "gt", 18)
    .order("created_at", "desc")
    .limit(20)
    .offset(0)
    .get();

System.out.println("Found " + activeUsers.getCount() + " users");
for (Object user : activeUsers.getData()) {
    System.out.println(((Map<String, Object>) user).get("name"));
}

Filter Helper Methods

// Using helper methods: eq, gt, gte, lt, lte, like, in, between
QueryResponse<?> users = client.table("users")
    .eq("status", "active")
    .gt("age", 18)
    .like("email", "%@gmail.com")
    .in("role", Arrays.asList("admin", "moderator"))
    .between("created_at", "2024-01-01", "2024-12-31")
    .get();

GROUP BY and Aggregates

Basic GROUP BY

// Group by category with counts
QueryResponse<?> result = client.table("products")
    .select("category", "COUNT(*) as count", "AVG(price) as avg_price")
    .groupBy("category")
    .get();

// Group by date
QueryResponse<?> result2 = client.table("orders")
    .select("DATE(created_at) as date", "COUNT(*) as orders", "SUM(total) as revenue")
    .groupBy("DATE(created_at)")
    .orderBy("date", "desc")
    .get();

HAVING Clause

QueryResponse<?> result = client.table("products")
    .select("category", "COUNT(*) as count")
    .groupBy("category")
    .having("COUNT(*)", "gt", 10)
    .get();

CRUD Operations

Create Record

Map<String, Object> row = new HashMap<>();
row.put("name", "John Doe");
row.put("email", "john@example.com");
row.put("age", 30);
Map<String, Object> result = client.table("users").create(row);
System.out.println("Created user with ID: " + result.get("id"));

Update Record

client.table("users").update(123, Map.of("email", "newemail@example.com"));
System.out.println("User updated successfully");

Delete Record

client.table("users").delete(123);
System.out.println("User deleted successfully");

Get Single Record by ID

Map<String, Object> user = client.table("users").getById(123);
System.out.println("User: " + user.get("name"));

Get First Record

Map<String, Object> first = client.table("users")
    .filter("status", "eq", "active")
    .first();
if (first != null) {
    System.out.println("First active user: " + first.get("name"));
}

Filter Operators

Available operators for filtering data:

OperatorDescriptionExample (Java)
eqEquals.filter("status", "eq", "active")
neqNot equals.filter("status", "neq", "deleted")
gtGreater than.filter("age", "gt", 18)
gteGreater than or equal.filter("age", "gte", 18)
ltLess than.filter("price", "lt", 100)
lteLess than or equal.filter("price", "lte", 100)
likePattern matching.filter("name", "like", "john")
inIN operator.in("category", Arrays.asList("electronics", "books"))
not_inNOT IN.notIn("status", Arrays.asList("deleted", "archived"))
betweenBETWEEN.between("price", 10, 100)

Error Handling

try {
    QueryResponse<?> users = client.table("users").select("*").get();
    System.out.println("Success: " + users.getData().size() + " users");
} catch (WowSQLException e) {
    if (e.getStatusCode() == 401) System.out.println("Authentication failed — check your API key");
    else if (e.getStatusCode() == 404) System.out.println("Table or resource not found");
    else System.out.println("Error (" + e.getStatusCode() + "): " + e.getMessage());
}

Authentication

Auth endpoints are served at /auth/v1/. Use the anon key for client-side auth operations.

Sign Up & Sign In

import com.WowSQL.ProjectAuthClient;
import com.WowSQL.models.AuthResponse;

ProjectAuthClient auth = new ProjectAuthClient(
    "https://myproject.wowsqlconnect.com",
    "wowsql_anon_your_key_here"
);

// Sign up — POST /auth/v1/signup
AuthResponse result = auth.signUp("user@example.com", "SecurePassword123", "John Doe", null);
System.out.println("Access token: " + result.getSession().getAccessToken());

// Sign in — POST /auth/v1/login
AuthResponse login = auth.signIn("user@example.com", "SecurePassword123");
System.out.println("User ID: " + login.getUser().getId());

Password Reset

auth.forgotPassword("user@example.com");
auth.resetPassword("reset_token_from_email", "NewSecurePassword123");

OAuth Authentication

Setup checklist — do this once per provider, per project:
1. Dashboard → Project → Auth → Providers: enable the provider, paste Client ID and Client Secret (no leading/trailing spaces).
2. Copy the Redirect URI shown: https://<slug>.wowsqlconnect.com/auth/v1/oauth/<provider>/callback and register it in your provider's developer console.
3. The callback URL is handled entirely by WowSQL — your app does not send an API key on it. WowSQL exchanges the code and redirects to your frontend_redirect_uri with ?access_token=&refresh_token=.

// ── Step 1: Server-side — get the authorization URL ─────────────────────────
import com.WowSQL.models.OAuthResponse;

OAuthResponse oauth = auth.getOAuthAuthorizationUrl(
    "google",
    "https://yourapp.com/auth/callback"
);
// Redirect the browser to oauth.getAuthorizationUrl()
// Google calls: https://<slug>.wowsqlconnect.com/auth/v1/oauth/google/callback
// WowSQL exchanges the code and redirects to your frontend_redirect_uri.

// ── Step 2: Frontend — read tokens from the redirect ────────────────────────
// WowSQL redirects to: https://yourapp.com/auth/callback?access_token=...&refresh_token=...

// ── (Advanced) Manual code exchange — only if you handle the callback yourself
AuthResponse result = auth.exchangeOAuthCallback(
    "google",
    "authorization_code_from_callback",
    "https://yourapp.com/auth/callback"  // must match step 1
);
System.out.println("OAuth login successful: " + result.getUser().getId());

Initialize Storage

Storage endpoints are served at /storage/v1/.

WowSQLStorage storage = new WowSQLStorage(
    "https://myproject.wowsqlconnect.com",
    "wowsql_anon_your_key_here"
);

File Operations

// Upload file
storage.uploadFromPath("path/to/document.pdf", "uploads/document.pdf", "documents");

// Get file URL
Map<String, Object> urlData = storage.getFileUrl("uploads/document.pdf", 3600);
System.out.println("Download URL: " + urlData.get("file_url"));

// List files
List<StorageFile> files = storage.listFiles("uploads/");
for (StorageFile file : files) {
    System.out.println(file.getKey() + ": " + file.getSizeMb() + " MB");
}

// Delete file
storage.deleteFile("uploads/document.pdf");

// Check quota
StorageQuota quota = storage.getQuota();
System.out.println("Used: " + quota.getUsedGb() + " GB / " + quota.getQuotaGb() + " GB");

Download or View File

Via REST:

  • Upload: POST /storage/v1/object/{bucket}/{path}
  • Download: GET /storage/v1/object/{bucket}/{path}
  • List: POST /storage/v1/object/list/{bucket}
  • Public URL: GET /storage/v1/object/public/{bucket}/{path}

Schema DDL (WOWSQLSchema)

Requires service role key. createTable requires the primary key column to be type UUID. Use "auto_increment": true on that column for DEFAULT gen_random_uuid(). Raw CREATE TABLE via execute SQL cannot use SERIAL PRIMARY KEY (or similar integer PK). Existing tables are unchanged.

WOWSQLSchema schema = new WOWSQLSchema("myproject", "wowsql_service_your_key_here");
List<Map<String, Object>> columns = new ArrayList<>();
Map<String, Object> idCol = new HashMap<>();
idCol.put("name", "id");
idCol.put("type", "UUID");
idCol.put("auto_increment", true);
columns.add(idCol);
Map<String, Object> titleCol = new HashMap<>();
titleCol.put("name", "title");
titleCol.put("type", "TEXT");
columns.add(titleCol);
schema.createTable("items", columns, "id");