WOWSQL.SDK 1.0.0

dotnet add package WOWSQL.SDK --version 1.0.0
                    
NuGet\Install-Package WOWSQL.SDK -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WOWSQL.SDK" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WOWSQL.SDK" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="WOWSQL.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WOWSQL.SDK --version 1.0.0
                    
#r "nuget: WOWSQL.SDK, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WOWSQL.SDK@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WOWSQL.SDK&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=WOWSQL.SDK&version=1.0.0
                    
Install as a Cake Tool

🚀 WOWSQL .NET SDK

Official .NET client for WOWSQL - MySQL Backend-as-a-Service with S3 Storage.

Installation

NuGet Package Manager

Install-Package WOWSQL.SDK

.NET CLI

dotnet add package WOWSQL.SDK

PackageReference

<PackageReference Include="WOWSQL.SDK" Version="1.0.0" />

Quick Start

Database Operations

using WOWSQL;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;

// Initialize client
var client = new WOWSQLClient(
    "https://your-project.wowsql.com",
    "your-api-key"  // Get from dashboard
);

// Select data
var response = await client.Table("users")
    .Select("id", "name", "email")
    .Limit(10)
    .GetAsync();

foreach (var user in response.Data)
{
    Console.WriteLine($"{user["name"]} ({user["email"]})");
}

// Insert data
var newUser = new Dictionary<string, object>
{
    { "name", "Jane Doe" },
    { "email", "jane@example.com" },
    { "age", 25 }
};

await client.Table("users").CreateAsync(newUser);

// Update data
var updates = new Dictionary<string, object>
{
    { "name", "Jane Smith" }
};

await client.Table("users").UpdateAsync(1, updates);

// Delete data
await client.Table("users").DeleteAsync(1);

// Using statement for automatic disposal
using (var client = new WOWSQLClient("your-project", "your-api-key"))
{
    var users = await client.Table("users").GetAsync();
    // Client is automatically disposed when exiting the using block
}

Storage Operations

using WOWSQL;
using System;
using System.Threading.Tasks;
using System.IO;

// Initialize storage client
var storage = new WOWSQLStorage(
    "your-project-slug",
    "your-api-key"
);

// Upload file
using (var fileStream = File.OpenRead("local-file.pdf"))
{
    await storage.UploadFileAsync(fileStream, "uploads/document.pdf", "documents");
}

// Get file URL (with metadata)
var urlData = await storage.GetFileUrlAsync("uploads/document.pdf", 3600);
Console.WriteLine($"File URL: {urlData["file_url"]}");
Console.WriteLine($"Expires at: {urlData["expires_at"]}");

// Get presigned URL (simple)
var presignedUrl = await storage.GetPresignedUrlAsync(
    "uploads/document.pdf",
    3600,
    "get_object"
);
Console.WriteLine($"Presigned URL: {presignedUrl}");

// List files
var files = await storage.ListFilesAsync("uploads/");
foreach (var file in files)
{
    Console.WriteLine($"{file.Key}: {file.SizeMb:F2} MB");
}

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

// Check storage quota
var quota = await storage.GetQuotaAsync();
Console.WriteLine($"Used: {quota.UsedGb:F2} GB / {quota.QuotaGb:F2} GB");
Console.WriteLine($"Available: {quota.AvailableGb:F2} GB");
Console.WriteLine($"Usage: {quota.UsagePercentage:F1}%");

Project Authentication

✨ UNIFIED AUTHENTICATION: Use the same keys as database operations!

using WOWSQL;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;

// Using Anonymous Key (recommended for client-side auth operations)
var auth = new ProjectAuthClient(
    "https://your-project.wowsql.com",
    apiKey: "wowsql_anon_your-anon-key-here"  // Same key as database operations!
);

// Using Service Role Key (for server-side auth operations)
var auth = new ProjectAuthClient(
    "https://your-project.wowsql.com",
    apiKey: "wowsql_service_your-service-key-here"  // Same key as database operations!
);

// Sign up users
var metadata = new Dictionary<string, object>
{
    { "referrer", "landing" }
};

var signupResult = await auth.SignUpAsync(
    "user@example.com",
    "SuperSecret123",
    "End User",
    metadata
);

Console.WriteLine(signupResult.User.Email);
Console.WriteLine(signupResult.Session.AccessToken);

// Sign in
var signinResult = await auth.SignInAsync(
    "user@example.com",
    "SuperSecret123"
);

auth.SetSession(
    signinResult.Session.AccessToken,
    signinResult.Session.RefreshToken
);

// Get current user
var currentUser = await auth.GetUserAsync();
Console.WriteLine($"{currentUser.Id} - {currentUser.EmailVerified}");

// OAuth Authentication
var oauth = await auth.GetOAuthAuthorizationUrlAsync(
    "github",
    "https://app.example.com/auth/callback"
);
Console.WriteLine($"Redirect user to: {oauth["authorization_url"]}");

// After user authorizes, exchange code for tokens
var oauthResult = await auth.ExchangeOAuthCallbackAsync(
    "github",
    "authorization_code_from_callback",
    "https://app.example.com/auth/callback"
);
Console.WriteLine($"Logged in as: {oauthResult.User.Email}");

// OTP Authentication
await auth.SendOtpAsync("user@example.com", "login");
var otpResult = await auth.VerifyOtpAsync(
    "user@example.com",
    "123456",
    "login"
);
Console.WriteLine($"OTP login successful: {otpResult.User.Id}");

// Magic Link Authentication
await auth.SendMagicLinkAsync("user@example.com", "login");
// User clicks link in email, then verify with token
await auth.VerifyEmailAsync("verification_token_from_email");

// Resend verification email
await auth.ResendVerificationAsync("user@example.com");

Features

Database Features

  • ✅ Full CRUD operations (Create, Read, Update, Delete)
  • ✅ Advanced filtering (eq, neq, gt, gte, lt, lte, like, isNull, isNotNull, in, notIn, between, notBetween, or)
  • ✅ GROUP BY with aggregate functions (COUNT, SUM, AVG, etc.)
  • ✅ HAVING clause for filtering aggregated results
  • ✅ Multiple ORDER BY columns
  • ✅ Pagination (limit, offset)
  • ✅ Sorting (orderBy, orderByMultiple)
  • ✅ Get by ID and First record methods
  • ✅ Table schema introspection
  • ✅ Built-in error handling
  • ✅ Async/await support

Storage Features

  • ✅ S3-compatible storage client
  • ✅ File upload with automatic quota validation
  • ✅ File download (presigned URLs)
  • ✅ File listing with metadata
  • ✅ File deletion
  • ✅ Storage quota management
  • ✅ Multi-region support

Authentication Features

  • ✅ User sign up and sign in
  • ✅ OAuth authentication (GitHub, Google, etc.)
  • ✅ Password reset
  • ✅ OTP (One-Time Password) authentication
  • ✅ Magic link authentication
  • ✅ Email verification
  • ✅ Session management
  • ✅ User metadata support

Usage Examples

Select Queries

// Select all columns
var users = await client.Table("users").Select("*").GetAsync();

// Select specific columns
var users = await client.Table("users")
    .Select("id", "name", "email")
    .GetAsync();

// With filters
var activeUsers = await client.Table("users")
    .Select("id", "name", "email")
    .Eq("status", "active")
    .Gt("age", 18)
    .GetAsync();

// With ordering
var recentUsers = await client.Table("users")
    .Select("*")
    .OrderBy("created_at", desc: true)
    .Limit(10)
    .GetAsync();

// With pagination
var page1 = await client.Table("users")
    .Select("*")
    .Limit(20)
    .Offset(0)
    .GetAsync();

var page2 = await client.Table("users")
    .Select("*")
    .Limit(20)
    .Offset(20)
    .GetAsync();

// Pattern matching
var gmailUsers = await client.Table("users")
    .Select("*")
    .Like("email", "%@gmail.com")
    .GetAsync();

// Get first matching record
var firstUser = await client.Table("users")
    .Eq("status", "active")
    .FirstAsync();

// Get record by ID
var user = await client.Table("users").GetByIdAsync(123);

Advanced Queries

// GROUP BY with aggregates
var result = await client.Table("products")
    .Select("category", "COUNT(*) as count", "AVG(price) as avg_price")
    .GroupBy("category")
    .GetAsync();

// GROUP BY with HAVING
var result = await client.Table("products")
    .Select("category", "COUNT(*) as count")
    .GroupBy("category")
    .Having("COUNT(*)", "gt", 10)
    .GetAsync();

// Multiple ORDER BY columns
var result = await client.Table("products")
    .Select("*")
    .OrderByMultiple(
        new OrderByItem { Column = "category", Direction = "asc" },
        new OrderByItem { Column = "price", Direction = "desc" }
    )
    .GetAsync();

// IN operator
var users = await client.Table("users")
    .In("role", new List<object> { "admin", "moderator" })
    .GetAsync();

// BETWEEN operator
var products = await client.Table("products")
    .Between("price", 10, 100)
    .GetAsync();

// OR conditions
var users = await client.Table("users")
    .Eq("status", "active")
    .Or("role", "eq", "admin")
    .GetAsync();

Filter Operators

// Equal
.Eq("status", "active")

// Not equal
.Neq("status", "deleted")

// Greater than
.Gt("age", 18)

// Greater than or equal
.Gte("age", 18)

// Less than
.Lt("age", 65)

// Less than or equal
.Lte("age", 65)

// Pattern matching (SQL LIKE)
.Like("email", "%@gmail.com")

// Is null
.IsNull("deleted_at")

// Is not null
.IsNotNull("email_verified_at")

// IN operator
.In("category", new List<object> { "electronics", "books" })

// NOT IN operator
.NotIn("status", new List<object> { "deleted", "archived" })

// BETWEEN operator
.Between("price", 10, 100)

// NOT BETWEEN operator
.NotBetween("age", 18, 65)

// OR condition
.Or("role", "eq", "admin")

Error Handling

try
{
    var users = await client.Table("users").Select("*").GetAsync();
}
catch (WOWSQLException ex)
{
    Console.WriteLine($"Database error: {ex.Message}");
    Console.WriteLine($"Status code: {ex.StatusCode}");
}

try
{
    await storage.UploadFileAsync(fileStream, "uploads/file.pdf", null);
}
catch (StorageLimitExceededException ex)
{
    Console.WriteLine($"Storage full: {ex.Message}");
    Console.WriteLine("Please upgrade your plan or delete old files");
}
catch (StorageException ex)
{
    Console.WriteLine($"Storage error: {ex.Message}");
}

🔑 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.

Operation Type Recommended Key Alternative Key Used By
Database Operations (CRUD) Service Role Key (wowsql_service_...) Anonymous Key (wowsql_anon_...) WOWSQLClient
Authentication Operations (OAuth, sign-in) Anonymous Key (wowsql_anon_...) Service Role Key (wowsql_service_...) ProjectAuthClient

Where to Find Your Keys

All keys are found in: WOWSQL Dashboard → Settings → API Keys or Authentication → PROJECT KEYS

  1. Anonymous Key (wowsql_anon_...) ✨ Unified Key

    • Location: "Anonymous Key (Public)"
    • 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

    • Location: "Service Role Key (keep secret)"
    • 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!

Database Operations

Use Service Role Key or Anonymous Key for database operations:

// Using Service Role Key (recommended for server-side, full access)
var client = new WOWSQLClient(
    "https://your-project.wowsql.com",
    "wowsql_service_your-service-key-here"  // Service Role Key
);

// Using Anonymous Key (for public/client-side access with limited permissions)
var client = new WOWSQLClient(
    "https://your-project.wowsql.com",
    "wowsql_anon_your-anon-key-here"  // Anonymous Key
);

Authentication Operations

✨ UNIFIED AUTHENTICATION: Use the same keys as database operations!

// Using Anonymous Key (recommended for client-side auth operations)
var auth = new ProjectAuthClient(
    "https://your-project.wowsql.com",
    apiKey: "wowsql_anon_your-anon-key-here"  // Same key as database operations!
);

// Using Service Role Key (for server-side auth operations)
var auth = new ProjectAuthClient(
    "https://your-project.wowsql.com",
    apiKey: "wowsql_service_your-service-key-here"  // Same key as database operations!
);

Note: The publicApiKey parameter is deprecated but still works for backward compatibility. Use apiKey instead.

Key Usage Summary

✨ UNIFIED AUTHENTICATION:

  • WOWSQLClient → Uses Service Role Key or Anonymous Key for database operations
  • ProjectAuthClient → Uses Anonymous Key (client-side) or Service Role Key (server-side) for authentication operations
  • Same keys work for both database AND authentication operations! 🎉
  • Anonymous Key (wowsql_anon_...) → Client-side operations (auth + database)
  • Service Role Key (wowsql_service_...) → Server-side operations (auth + database)

Security Best Practices

  1. Never expose Service Role Key in client-side code or public repositories
  2. Use Anonymous Key for client-side authentication flows (same key as database operations)
  3. Use Anonymous Key for public database access with limited permissions
  4. Store keys in environment variables, never hardcode them
  5. Rotate keys regularly if compromised

Requirements

  • .NET Standard 2.0 or higher
  • .NET Framework 4.6.1 or higher
  • .NET Core 2.0 or higher
  • .NET 5.0 or higher

Dependencies

  • Newtonsoft.Json (13.0.3+)
  • System.Net.Http (4.3.4+)

Development

# Clone repository
git clone https://github.com/wowsql/wowsql-sdk-dotnet.git
cd WOWSQL-sdk-dotnet

# Restore packages
dotnet restore

# Build
dotnet build

# Run tests
dotnet test

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

MIT License - see LICENSE file for details.


Made with ❤️ by the WOWSQL Team

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 181 12/25/2025