WOWSQL.SDK
1.0.0
dotnet add package WOWSQL.SDK --version 1.0.0
NuGet\Install-Package WOWSQL.SDK -Version 1.0.0
<PackageReference Include="WOWSQL.SDK" Version="1.0.0" />
<PackageVersion Include="WOWSQL.SDK" Version="1.0.0" />
<PackageReference Include="WOWSQL.SDK" />
paket add WOWSQL.SDK --version 1.0.0
#r "nuget: WOWSQL.SDK, 1.0.0"
#:package WOWSQL.SDK@1.0.0
#addin nuget:?package=WOWSQL.SDK&version=1.0.0
#tool nuget:?package=WOWSQL.SDK&version=1.0.0
🚀 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
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)
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 operationsProjectAuthClient→ 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
- Never expose Service Role Key in client-side code or public repositories
- Use Anonymous Key for client-side authentication flows (same key as database operations)
- Use Anonymous Key for public database access with limited permissions
- Store keys in environment variables, never hardcode them
- 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.
Links
- 📚 Documentation
- 🌐 Website
- 💬 Discord
- 🐛 Issues
Made with ❤️ by the WOWSQL Team
| Product | Versions 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. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.3)
- System.Net.Http (>= 4.3.4)
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 |