WowSQL Ruby SDK
Official Ruby client for WowSQL — PostgreSQL backend-as-a-service with project auth and object storage.
Gem: wowsql-sdk · Module: WOWSQL · Ruby: 2.6+
Table of contents
- Installation
- Quick start
- Concepts & API keys
- Database:
WOWSQLClient - Table &
QueryBuilder - Authentication:
ProjectAuthClient - Storage:
WOWSQLStorage - Schema:
WOWSQLSchema - Models & types
- Exceptions
- Configuration
- Rails integration
- Examples
- Troubleshooting
- Links
Installation
Gemfile
gem 'wowsql-sdk', '~> 1.3'
bundle install
Manual
gem install wowsql-sdk
Require
require 'wowsql'
# or
require 'wowmysql' # legacy alias entry (same library)
Quick start
Database (CRUD + query builder)
require 'wowsql'
client = WOWSQL::WOWSQLClient.new(
'https://your-project.wowsql.com',
ENV.fetch('WOWSQL_SERVICE_KEY'),
base_domain: 'wowsql.com',
secure: true,
timeout: 30,
verify_ssl: true
)
rows = client.table('posts')
.select('id', 'title', 'created_at')
.eq('published', true)
.order_by('created_at', 'desc')
.limit(10)
.get
puts rows['data'].inspect
created = client.table('posts').create(
'title' => 'Hello',
'body' => 'World',
'published' => true
)
puts created['id']
client.close
Project authentication
auth = WOWSQL::ProjectAuthClient.new(
ENV.fetch('WOWSQL_PROJECT_URL'),
ENV.fetch('WOWSQL_ANON_KEY'),
base_domain: 'wowsql.com'
)
res = auth.sign_up(
email: '[email protected]',
password: 'SecurePass123!',
full_name: 'Ada Lovelace'
)
auth.set_session(
access_token: res.session.access_token,
refresh_token: res.session.refresh_token
)
user = auth.get_user
puts user.email
auth.close
Storage (buckets & files)
storage = WOWSQL::WOWSQLStorage.new(
ENV.fetch('WOWSQL_PROJECT_URL'),
ENV.fetch('WOWSQL_SERVICE_KEY'),
base_domain: 'wowsql.com',
timeout: 60
)
bucket = storage.create_bucket('avatars', public: true)
storage.upload(bucket.name, File.binread('face.png'), path: 'u/1.png', file_name: '1.png')
puts storage.get_public_url('avatars', 'u/1.png')
storage.close
Schema (service role only)
schema = WOWSQL::WOWSQLSchema.new(
ENV.fetch('WOWSQL_PROJECT_URL'),
ENV.fetch('WOWSQL_SERVICE_KEY')
)
schema.create_table(
'notes',
[
{ 'name' => 'id', 'type' => 'SERIAL', 'auto_increment' => true },
{ 'name' => 'body', 'type' => 'TEXT', 'nullable' => false }
],
primary_key: 'id'
)
schema.close
Concepts & API keys
| Key | Prefix | Typical use |
|---|---|---|
| Anonymous | wowsql_anon_… |
Browser/mobile auth flows, limited DB access |
| Service role | wowsql_service_… |
Server only — full DB, storage, schema DDL |
WOWSQLClient/WOWSQLStorage: use anon or service key depending on RLS and server vs client.WOWSQLSchema: requires service role (403 otherwise).ProjectAuthClient: usually anon on clients; service key only on trusted servers.
Store keys in ENV, never commit them.
Project URL: full https://{slug}.wowsql.com or just the slug; the client normalizes against base_domain and secure.
Database: WOWSQLClient
WOWSQL::WOWSQLClient.new(
project_url,
api_key,
base_domain: 'wowsql.com',
secure: true,
timeout: 30,
verify_ssl: true
)
| Method | Returns | Description |
|---|---|---|
table(table_name) |
Table |
Fluent access to one table (public schema via API). |
list_tables |
Array<String> |
Table names in the project DB. |
get_table_schema(table_name) |
Hash |
Column metadata from the API. |
request(method, path, params, json) |
Hash |
Low-level JSON request (advanced). |
close |
— | Release resources. |
Reader: api_url, api_key, timeout, verify_ssl.
Table & QueryBuilder
Table
Obtained via client.table('name').
| Method | Returns | Notes |
|---|---|---|
select(*columns) |
QueryBuilder |
Column list or '*'-style strings per your API. |
filter(column, operator, value, logical_op: 'AND') |
QueryBuilder |
See operators below. |
get(options = nil) |
Hash |
Executes SELECT pipeline. |
get_by_id(record_id) |
Hash |
Single row by PK. |
create(data) / insert(data) |
Hash |
Insert one row. |
bulk_insert(records) |
Array |
Multiple inserts. |
upsert(data, on_conflict: 'id') |
Hash |
Upsert semantics per backend. |
update(record_id, data) |
Hash |
Update by id. |
delete(record_id) |
Hash |
Delete by id. |
eq / neq / gt / gte / lt / lte |
QueryBuilder |
Shorthand filters. |
order_by(column, direction = 'asc') |
QueryBuilder |
|
count |
Integer |
|
paginate(page: 1, per_page: 20) |
Hash |
Paginated result envelope. |
QueryBuilder
Chainable; ends with get, execute, first, single, count, or paginate.
Filters: eq, neq, gt, gte, lt, lte, like, is_null, is_not_null, in_list, not_in, between, not_between, or_filter.
Grouping / aggregates: group_by(*columns), having(column, operator, value).
Sort / page: order_by, order, limit, offset.
Terminal:
| Method | Behavior |
|---|---|
get / execute |
Full result hash (data, counts, etc.). |
first |
First row or nil. |
single |
Exactly one row; raises WOWSQLError if not one row. |
count |
Integer count. |
paginate(page:, per_page:) |
Paginated structure. |
Filter operators (string)
Use with filter or the shorthand methods:
eq, neq, gt, gte, lt, lte, like, is, in, not_in, between, not_between, is_not — as supported by the WowSQL REST API for your project.
Authentication: ProjectAuthClient
WOWSQL::ProjectAuthClient.new(
project_url,
api_key,
base_domain: 'wowsql.com',
secure: true,
timeout: 30,
verify_ssl: true,
token_storage: nil # optional WOWSQL::MemoryTokenStorage or custom
)
TokenStorage (module)
Implement in your app for Redis/DB/session persistence:
get_access_token/set_access_token(token)get_refresh_token/set_refresh_token(token)
WOWSQL::MemoryTokenStorage is in-memory only.
Methods
| Method | Returns |
|---|---|
sign_up(email:, password:, full_name:, user_metadata:) |
AuthResponse |
sign_in(email:, password:) |
AuthResponse |
get_user(access_token: nil) |
AuthUser |
get_oauth_authorization_url(provider:, redirect_uri:) |
Hash |
exchange_oauth_callback(provider:, code:, redirect_uri:) |
AuthResponse |
forgot_password(email:) |
Hash |
reset_password(token:, new_password:) |
Hash |
send_otp(email:, purpose: 'login') |
Hash |
verify_otp(email:, otp:, purpose: 'login', new_password: nil) |
AuthResponse or Hash |
send_magic_link(email:, purpose: 'login') |
Hash |
verify_email(token:) |
Hash |
resend_verification(email:) |
Hash |
logout(access_token: nil) |
Hash |
refresh_token(refresh_token: nil) |
AuthResponse |
change_password(current_password:, new_password:, access_token: nil) |
Hash |
update_user(full_name:, avatar_url:, username:, user_metadata:, access_token:) |
AuthUser |
get_session |
Hash with token keys |
set_session(access_token:, refresh_token: nil) |
|
clear_session |
|
close |
Structs: AuthUser, AuthSession, AuthResponse (see Models).
Storage: WOWSQLStorage
WOWSQL::WOWSQLStorage.new(
project_url = '',
api_key = '',
project_slug: '',
base_url: '',
base_domain: 'wowsql.com',
secure: true,
timeout: 60,
verify_ssl: true
)
| Method | Returns |
|---|---|
create_bucket(name, public: false, file_size_limit: nil, allowed_mime_types: nil) |
StorageBucket |
list_buckets |
Array<StorageBucket> |
get_bucket(name) |
StorageBucket |
update_bucket(name, **options) |
StorageBucket |
delete_bucket(name) |
Hash |
upload(bucket_name, file_data, path: nil, file_name: nil) |
StorageFile |
upload_from_path(file_path, bucket_name: 'default', path: nil) |
StorageFile |
list_files(bucket_name, prefix: nil, limit: 100, offset: 0) |
Array<StorageFile> |
download(bucket_name, file_path) |
String (binary string) |
download_to_file(bucket_name, file_path, local_path) |
String (path) |
delete_file(bucket_name, file_path) |
Hash |
get_public_url(bucket_name, file_path) |
String |
get_stats |
StorageQuota |
get_quota(force_refresh: false) |
StorageQuota |
close |
Value objects: StorageBucket, StorageFile (size_mb, size_gb), StorageQuota.
Schema: WOWSQLSchema
Requires service role key.
WOWSQL::WOWSQLSchema.new(
project_url,
service_key,
base_domain: 'wowsql.com',
secure: true,
timeout: 30,
verify_ssl: true
)
| Method | Returns |
|---|---|
create_table(table_name, columns, primary_key: nil, indexes: nil) |
Hash |
alter_table(table_name, operation, column_name: nil, column_type: nil, new_column_name: nil, nullable: true, default: nil) |
Hash |
drop_table(table_name, cascade: false) |
Hash |
execute_sql(sql) |
Hash |
add_column(table_name, column_name, column_type, nullable: true, default: nil) |
Hash |
drop_column(table_name, column_name) |
Hash |
rename_column(table_name, old_name, new_name) |
Hash |
modify_column(table_name, column_name, column_type: nil, nullable: nil, default: nil) |
Hash |
create_index(table_name, columns, unique: false, name: nil, using: nil) |
Hash |
list_tables |
Array<String> |
get_table_schema(table_name) |
Hash |
close |
operation examples: add_column, drop_column, modify_column, rename_column (per API).
Models & types
Auth (structs)
AuthUser:id,email,full_name,avatar_url,email_verified,user_metadata,app_metadata,created_atAuthSession:access_token,refresh_token,token_type,expires_inAuthResponse:session,user
Storage
StorageBucket:id,name,public,file_size_limit,allowed_mime_types,created_at,object_count,total_sizeStorageFile:id,bucket_id,name,path,mime_type,size,metadata,created_at,public_url—size_mb,size_gbStorageQuota:total_files,total_size_bytes,total_size_gb,file_types
Exceptions
| Class | Typical HTTP | When |
|---|---|---|
WOWSQLError |
any | Base error; message, status_code, response. |
StorageError |
4xx/5xx | Storage API failures. |
StorageLimitExceededError |
413 | Quota / size limit. |
SchemaPermissionError |
403 | Schema call without service key. |
Aliases: WOWSQLException, StorageException, StorageLimitExceededException, PermissionException → map to the classes above.
begin
client.table('x').get
rescue WOWSQL::WOWSQLError => e
warn "#{e.status_code}: #{e.message}"
end
Configuration
| Option | Default | Notes |
|---|---|---|
base_domain |
wowsql.com |
Custom cloud domain if applicable. |
secure |
true |
Use HTTPS. |
timeout |
30 (DB/auth/schema), 60 (storage) | Seconds. |
verify_ssl |
true |
Set false only for local dev with self-signed certs. |
Rails integration
config/initializers/wowsql.rb
# frozen_string_literal: true
WOWSQL_CLIENT = WOWSQL::WOWSQLClient.new(
ENV.fetch('WOWSQL_PROJECT_URL'),
ENV.fetch('WOWSQL_SERVICE_KEY')
)
WOWSQL_AUTH = WOWSQL::ProjectAuthClient.new(
ENV.fetch('WOWSQL_PROJECT_URL'),
ENV.fetch('WOWSQL_ANON_KEY')
)
Use service key only in server-side code (jobs, controllers that must bypass restrictions). Prefer anon for end-user auth flows.
Examples
Blog: posts and comments
posts = WOWSQL_CLIENT.table('posts')
.select('id', 'title')
.eq('published', true)
.order_by('created_at', 'desc')
.limit(20)
.get
posts['data'].each do |p|
puts p['title']
end
Upload avatar then save URL in public table
storage = WOWSQL::WOWSQLStorage.new(ENV['WOWSQL_PROJECT_URL'], ENV['WOWSQL_SERVICE_KEY'])
path = "avatars/#{user_id}.jpg"
storage.upload('default', File.binread(local_path), path: path, file_name: 'avatar.jpg')
url = storage.get_public_url('default', path)
WOWSQL_CLIENT.table('profiles').update(user_id, 'avatar_url' => url)
storage.close
Troubleshooting
| Issue | Check |
|---|---|
cannot load such file -- faraday/multipart |
Install faraday-multipart (gem install faraday-multipart) or upgrade to wowsql-sdk ≥ 3.0.1, which declares this dependency. Faraday 2 moved multipart into that gem. |
| 401 Invalid API key | Key matches project; no extra spaces; key active in dashboard. |
| 403 Schema | Using service role for WOWSQLSchema. |
| 413 Storage | StorageLimitExceededError — plan / quota / object size. |
| SSL errors | verify_ssl: false temporarily on dev only. |
Links
License: MIT — see included LICENSE.
WowSQL Team