# AxarDB Cloud — Full AI & Developer Specification (llms-full.txt) This document is the exhaustive machine-readable specification for interacting with AxarDB Cloud (https://axardb.com). AI agents, autonomous bots, vibe coders, and application developers can use this reference to register, manage, query, and securely integrate AxarDB instances into production systems. --- ## 1. System Architecture & Core Concepts - **Base Domain**: `axardb.com` - **Database Routing**: Each database gets a dedicated HTTPS subdomain: `https://{subdomain}.axardb.com` - **Engine**: Pure in-memory document NoSQL with Jint (server-side JavaScript execution engine). - **Security Tiers**: - **Master / Admin Access**: Requires `Authorization: Bearer axdb_...` or `X-API-Key` header. Has full read/write/delete capabilities on all collections and views via `/query`. - **Public Views Access**: Zero-credential read-only access to pre-defined server-side views via `GET https://{subdomain}.axardb.com/views/{viewName}`. Strictly read-only, safe for public web, mobile, and IoT clients. - **Data Persistence**: Automatic snapshot persistence. Zero DDL required (collections are dynamically created on first insert). --- ## 2. Authentication & Account Management API ### 2.1 Fast Programmatic Registration (`POST /api/auth/register-fast`) Allows an AI agent or script to register with just an email address: ```http POST https://axardb.com/api/auth/register-fast Content-Type: application/json { "email": "agent@gmail.com", "dbName": "production-memory", "subdomain": "agent-prod-db" } ``` **Validation & Policies:** - `email`: Must belong to a reputable email service provider (`gmail.com`, `hotmail.com`, `outlook.com`, `yahoo.com`, `icloud.com`, `proton.me`, `yandex.com`). The local part (before `@`) must NOT contain dots (`.`) or aliases (`+`). Disposable or temporary burner emails are blocked with HTTP 400. - IP rate limit: Maximum 1 registration per IP address per 1 hour window. - `subdomain`: 3-30 characters, alphanumeric and hyphens. Must be globally unique. - Unverified trial: Valid for 1 hour. Unverified accounts cannot create multiple databases or delete their database. **Response (HTTP 201):** ```json { "success": true, "message": "Geçici hesabınız başarıyla oluşturuldu. 1 saat geçerli 1 adet ücretsiz veritabanınız hazırlandı...", "user": { "id": "uuid", "email": "agent@gmail.com", "plan": "free", "emailVerified": false }, "token": "session_token_string", "verificationLink": "https://axardb.com/set-password.html?token=...", "database": { "id": "uuid", "name": "production-memory", "subdomain": "agent-prod-db", "plan": "free", "status": "active" }, "apiKey": "axdb_live_..." } ``` ### 2.2 Account Lifecycle & Database Limits - **Unverified Accounts**: - Maximum **1 free database**. - Account and database expire and are permanently deleted after **24 hours**. - Clicking the email verification link or calling `/api/auth/set-password` validates the account. - **Verified Accounts**: - Maximum **3 concurrent free databases**. - To create a 4th free database, one of the existing 3 databases must be deleted. - Accounts and databases are permanent. --- ## 3. Database Management API All management endpoints require authentication header: `Authorization: Bearer ` or Cookie `ax_session=`. ### 3.1 List User Databases `GET https://axardb.com/api/databases` ### 3.2 Create New Database `POST https://axardb.com/api/databases` ```json { "name": "analytics-db", "subdomain": "my-analytics" } ``` ### 3.3 Delete Database `DELETE https://axardb.com/api/databases/{id}` ### 3.4 Create New API Key `POST https://axardb.com/api/databases/{id}/keys` ```json { "name": "Production Worker Key" } ``` --- ## 4. Query Engine Specification (`/query`) All data manipulation and retrieval is executed via HTTP POST to the database's dedicated subdomain: `POST https://{subdomain}.axardb.com/query` ### Headers: - `Authorization: Bearer axdb_...` - `Content-Type: text/plain; charset=utf-8` ### Query Language Rules: 1. **JavaScript Environment**: Queries are standard ES6+ JavaScript executed natively in the server memory. 2. **Output**: You **MUST** use `return` to output results back to the caller. Any statement without a `return` returns `null`. 3. **Array Results**: Do **NOT** append `.toList()`. In AxarDB `.findall()` directly returns an iterable array. 4. **Auto-Collection**: Calling `db.myCollection.insert(...)` automatically creates `myCollection` if it doesn't already exist. --- ## 5. Supported JavaScript Methods & Operations ### 5.1 Insert Record ```javascript db.users.insert({ name: "Elif Demir", role: "engineer", skills: ["python", "nosql", "ai"], active: true, createdAt: new Date() }); return db.users.find(u => u.name == "Elif Demir"); ``` ### 5.2 Find Single Record ```javascript return db.users.find(u => u.role == "engineer"); ``` ### 5.3 Find All with Filtering & Projection (NO .toList()) ```javascript return db.users.findall(u => u.active == true) .take(10) .select(u => ({ name: u.name, role: u.role })); ``` ### 5.4 Aggregations & Counting ```javascript return { total: db.users.findall().count(), active: db.users.findall(u => u.active == true).count() }; ``` ### 5.5 Update Record ```javascript var user = db.users.find(u => u.name == "Elif Demir"); if (user) { user.role = "lead_engineer"; user.updatedAt = new Date(); } return db.users.find(u => u.name == "Elif Demir"); ``` ### 5.6 Delete Record ```javascript db.users.remove(u => u.active == false); return db.users.findall().count(); ``` --- ## 6. Vibe Coding Privilege: AxarDB Public Views (Zero-Credential Architecture) ### 6.1 The Vibe Coding Problem: Leaked Credentials When building applications rapidly using AI assistants (Cursor, v0, Lovable, Claude, Windsurf), developers often ask the AI to "fetch products from my database" or "save high scores". The AI will intuitively embed the master `axdb_live_...` API key in the client code. - In **mobile apps** (APK, IPA), users decompile binaries and extract master keys. - In **web frontends**, any visitor opens DevTools Network tab and grabs the token. - In **IoT / embedded devices**, firmware dumping exposes the key. With a leaked master key, any malicious user can execute `db.users.remove(...)` or drop entire collections! ### 6.2 The Solution: Public Views (`// @access public`) AxarDB's native Public View system decouples client software from database write credentials: 1. **Developer / AI Backend defines the View once** using the master API key. 2. **The View defines exact business logic**, sanitizes output fields, and binds query parameters (`@paramName`). 3. **Clients make standard HTTP GET requests** with **ZERO** authorization headers: `GET https://{subdomain}.axardb.com/views/{viewName}?param=value` ### 6.3 Defining Public Views on the Server Send an authenticated HTTP POST to `/query`: ```bash curl -X POST "https://my-store.axardb.com/query" \ -H "Authorization: Bearer axdb_live_YOUR_SECRET_KEY" \ -H "Content-Type: text/plain; charset=utf-8" \ -d ' // 1. Ürün listeleme görünümü (Kategori parametreli) db.saveView("getProductsByCategory", ` // @access public var category = @cat; var minRating = @minRating || 0; return db.products .findall(p => p.category == category && p.rating >= minRating && p.isPublic == true) .take(50) .select(p => ({ id: p.id, title: p.title, price: p.price, rating: p.rating, inStock: p.inventory > 0 })); `); // 2. Canlı cihaz telemetrisi / durum panosu görünümü db.saveView("getDeviceConfig", ` // @access public var deviceId = @devId; var config = db.devices.find(d => d.deviceId == deviceId); if (!config) return { status: "not_found" }; return { mode: config.mode, pollIntervalMs: config.pollIntervalMs, targetFirmware: config.latestFirmware, serverTime: new Date() }; `); return "Public views successfully registered!"; ' ``` --- ## 7. Mobile Application Implementations (Zero Credentials) Because Public Views require NO API keys, your mobile apps stay 100% secure. ### 7.1 Flutter (Dart) Add `http` to `pubspec.yaml`: ```dart import 'dart:convert'; import 'package:http/http.dart' as http; class Product { final String id; final String title; final double price; final bool inStock; Product({required this.id, required this.title, required this.price, required this.inStock}); factory Product.fromJson(Map json) { return Product( id: json['id'] ?? '', title: json['title'] ?? '', price: (json['price'] as num?)?.toDouble() ?? 0.0, inStock: json['inStock'] ?? false, ); } } class AxarDbService { static const String baseUrl = 'https://my-store.axardb.com/views'; // Zero-credentials GET request static Future> fetchProducts(String category) async { final url = Uri.parse('$baseUrl/getProductsByCategory?cat=${Uri.encodeComponent(category)}'); final response = await http.get(url); if (response.statusCode == 200) { final List data = json.decode(response.body); return data.map((item) => Product.fromJson(item)).toList(); } else { throw Exception('Failed to load products from AxarDB: ${response.statusCode}'); } } } ``` ### 7.2 React Native / Expo (TypeScript) ```typescript import React, { useEffect, useState } from 'react'; import { View, Text, FlatList, ActivityIndicator } from 'react-native'; interface Product { id: string; title: string; price: number; inStock: boolean; } export const ProductListScreen = ({ category }: { category: string }) => { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { // Zero-credentials fetch from AxarDB Public View fetch(`https://my-store.axardb.com/views/getProductsByCategory?cat=${encodeURIComponent(category)}`) .then((res) => res.json()) .then((data: Product[]) => { setProducts(data); setLoading(false); }) .catch((err) => { console.error('AxarDB fetch error:', err); setLoading(false); }); }, [category]); if (loading) return ; return ( item.id} renderItem={({ item }) => ( {item.title} ${item.price.toFixed(2)} - {item.inStock ? 'In Stock' : 'Out of Stock'} )} /> ); }; ``` ### 7.3 Swift (iOS URLSession & Codable) ```swift import Foundation struct Product: Codable, Identifiable { let id: String let title: String let price: Double let inStock: Bool } class AxarDbClient { static let shared = AxarDbClient() private let endpoint = "https://my-store.axardb.com/views/getProductsByCategory" func fetchProducts(category: String) async throws -> [Product] { guard var components = URLComponents(string: endpoint) else { throw URLError(.badURL) } components.queryItems = [URLQueryItem(name: "cat", value: category)] guard let url = components.url else { throw URLError(.badURL) } // Zero credentials required let (data, response) = try await URLSession.shared.data(from: url) guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { throw URLError(.badServerResponse) } return try JSONDecoder().decode([Product].self, from: data) } } ``` ### 7.4 Kotlin (Android OkHttp & Coroutines) ```kotlin import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request import org.json.JSONArray data class Product(val id: String, val title: String, val price: Double, val inStock: Boolean) class AxarDbRepository { private val client = OkHttpClient() private val baseUrl = "https://my-store.axardb.com/views/getProductsByCategory" suspend fun getProducts(category: String): List = withContext(Dispatchers.IO) { val url = "$baseUrl?cat=$category" val request = Request.Builder().url(url).get().build() client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw Exception("AxarDB error: ${response.code}") val body = response.body?.string() ?: "[]" val jsonArray = JSONArray(body) val list = mutableListOf() for (i in 0 until jsonArray.length()) { val obj = jsonArray.getJSONObject(i) list.add(Product( id = obj.getString("id"), title = obj.getString("title"), price = obj.getDouble("price"), inStock = obj.getBoolean("inStock") )) } list } } } ``` --- ## 8. Frontend Web Implementations (Zero Credentials) ### 8.1 Next.js 14+ (React Server Components / Client Fetch) In Next.js, you can query AxarDB Public Views from both server and client without secret environment variables: ```typescript // app/products/page.tsx (Server Component) import React from 'react'; interface Product { id: string; title: string; price: number; inStock: boolean; } async function getProducts(category: string): Promise { // Ultra-fast in-memory edge query, revalidated every 60 seconds const res = await fetch(`https://my-store.axardb.com/views/getProductsByCategory?cat=${category}`, { next: { revalidate: 60 } }); if (!res.ok) throw new Error('Failed to fetch from AxarDB'); return res.json(); } export default async function ProductsPage() { const products = await getProducts('electronics'); return (
{products.map((p) => (

{p.title}

${p.price}

{p.inStock ? "Stokta Var" : "Tükendi"}
))}
); } ``` ### 8.2 Vue 3 (Composition API) ```html ``` ### 8.3 Vanilla HTML + Modern JavaScript ```html Canlı Ürünler
Yükleniyor...
``` --- ## 9. Embedded & IoT Implementations (ESP32, MicroPython) Microcontrollers and edge gateways often have limited flash and memory, and cannot afford heavy SDKs. Public Views provide a lean, lightweight HTTP GET interface. ### 9.1 ESP32 / Arduino (C++ WiFiClientSecure & HTTPClient) ```cpp #include #include #include const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASS"; // AxarDB Public View endpoint (zero credentials needed) const char* axarDbEndpoint = "https://iot-fleet.axardb.com/views/getDeviceConfig?devId=sensor-node-42"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi Connected!"); fetchRemoteConfig(); } void loop() { // Periyodik kontrol döngüsü delay(60000); fetchRemoteConfig(); } void fetchRemoteConfig() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(axarDbEndpoint); int httpResponseCode = http.GET(); if (httpResponseCode == 200) { String payload = http.getString(); Serial.println("AxarDB Telemetry Config received:"); Serial.println(payload); // JSON Çözümleme StaticJsonDocument<512> doc; deserializeJson(doc, payload); int pollInterval = doc["pollIntervalMs"]; const char* mode = doc["mode"]; Serial.printf("Device Mode: %s, Next Poll: %d ms\n", mode, pollInterval); } else { Serial.printf("AxarDB HTTP Error code: %d\n", httpResponseCode); } http.end(); } } ``` ### 9.2 Raspberry Pi / MicroPython (`urequests`) ```python import urequests import time DEVICE_ID = "pico-edge-01" VIEW_URL = f"https://iot-fleet.axardb.com/views/getDeviceConfig?devId={DEVICE_ID}" def poll_axardb_config(): try: # Zero credentials needed response = urequests.get(VIEW_URL) if response.status_code == 200: config = response.json() print("Received config from AxarDB:", config) return config else: print("AxarDB error:", response.status_code) except Exception as e: print("Network error:", e) finally: response.close() return None while True: cfg = poll_axardb_config() time.sleep(30) ``` --- ## 10. Master Backend SDK Snippets (Authenticated Write Access) When you are on a protected server or backend service with master credentials, use the `/query` endpoint: ### 10.1 Python (Backend) ```python import requests url = "https://agent-prod-db.axardb.com/query" headers = { "Authorization": "Bearer axdb_YOUR_API_KEY", "Content-Type": "text/plain; charset=utf-8" } query = """ db.agent_state.insert({ step: 1, action: "fetch_web_data", status: "completed", timestamp: new Date() }); return db.agent_state.findall(); """ response = requests.post(url, headers=headers, data=query.encode("utf-8")) print(response.json()) ``` ### 10.2 Node.js / TypeScript (Backend) ```typescript const response = await fetch("https://agent-prod-db.axardb.com/query", { method: "POST", headers: { "Authorization": "Bearer axdb_YOUR_API_KEY", "Content-Type": "text/plain; charset=utf-8", }, body: ` db.tasks.insert({ title: "Deploy AI Worker", priority: "high", done: false }); return db.tasks.findall(t => !t.done); `, }); const data = await response.json(); console.log(data); ``` ### 10.3 cURL (CLI Master Query) ```bash curl -X POST "https://agent-prod-db.axardb.com/query" \ -H "Authorization: Bearer axdb_YOUR_API_KEY" \ -H "Content-Type: text/plain; charset=utf-8" \ -d 'return db.tasks.findall();' ``` --- ## 11. Database Migration & In-Memory Acceleration Layer (PostgreSQL, MySQL, MongoDB) AxarDB is designed not only as a standalone database, but as a high-performance **In-Memory Front Layer / Edge Accelerator** for existing relational and document databases (PostgreSQL, MySQL, MongoDB). --- ### 11.1 Architectural Rationale: Why Use AxarDB in Front of SQL/Mongo? Traditional databases (PostgreSQL, MySQL, MongoDB) are built primarily as **Systems of Record (SoR)** prioritizing disk durability, relational integrity, and ACID transactions. Under high concurrency: 1. **Disk I/O Bottlenecks**: High-throughput reads (e.g. thousands of concurrent users browsing an e-commerce catalog) compete for disk IOPS and buffer pool cache. 2. **Locking & Contention**: Table/row locks or MongoDB document locks throttle read performance during write bursts. 3. **Connection Pool Exhaustion**: Serverless functions, mobile apps, and edge workers easily overwhelm the connection pool of a PostgreSQL or MySQL instance. 4. **Credential Exposure Risk**: Connecting client apps directly to MongoDB or PostgreSQL requires exposing database credentials or creating complex microservice middleware. #### The AxarDB Front-Layer Solution: - **100% In-Memory RAM**: Queries execute on in-memory objects in microsecond latency. - **Zero Query Compilation**: Pure JavaScript filtering (`db.users.findall(u => u.active)`) executes directly on objects without SQL AST parsing. - **Edge Offloading**: AxarDB Edge Containers absorb 90%+ of read traffic, protecting primary databases from crashing under traffic spikes. - **Public Views**: Expose read-only cached data directly to mobile apps and browsers with **zero database credentials**. ``` [ Mobile Apps / Web Clients / IoT Devices ] │ ▼ (Sub-millisecond HTTPS GET / Public Views - 0 Credentials) ┌─────────────────────────────────────────────────────────┐ │ AxarDB Cloud In-Memory Acceleration Front-Layer │ │ (100% RAM • Pure JS Engine • Edge Snapshots • Views) │ └──────────────────────────┬──────────────────────────────┘ │ (Async Sync / CDC / Cache-Miss Fallback) ▼ ┌─────────────────────────────────────────────────────────┐ │ Primary System of Record (Heavy Disk / ACID) │ │ PostgreSQL • MySQL • MongoDB │ └─────────────────────────────────────────────────────────┘ ``` --- ### 11.2 PostgreSQL Migration & High-Traffic Catalog Acceleration #### Scenario: E-Commerce Product Catalog An e-commerce platform has 200,000 products in PostgreSQL. Category browsing and search queries cause heavy JOINs between `products`, `categories`, and `prices`. By hydrating AxarDB with denormalized product documents, product catalog reads achieve sub-millisecond edge latency. #### Step 1: Migration / Sync Pipeline (Python ETL) Extracts relational data with JOINs from PostgreSQL and bulk-loads denormalized JSON into AxarDB: ```python import psycopg2 import requests import json PG_CONN = "postgresql://user:password@localhost:5432/store_db" AXARDB_URL = "https://store-catalog.axardb.com/query" AXARDB_KEY = "axdb_live_YOUR_API_KEY" def migrate_postgres_to_axardb(): conn = psycopg2.connect(PG_CONN) cur = conn.cursor() # Denormalize relational data with SQL JOIN query = """ SELECT p.id, p.title, p.sku, p.price, p.stock, c.name as category, COALESCE(json_agg(t.tag_name) FILTER (WHERE t.tag_name IS NOT NULL), '[]') as tags FROM products p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN product_tags t ON p.id = t.product_id WHERE p.is_active = TRUE GROUP BY p.id, c.name; """ cur.execute(query) rows = cur.fetchall() products = [] for r in rows: products.append({ "id": r[0], "title": r[1], "sku": r[2], "price": float(r[3]), "stock": r[4], "category": r[5], "tags": r[6] if isinstance(r[6], list) else json.loads(r[6]) }) print(f"Extracted {len(products)} products from PostgreSQL. Ingesting to AxarDB...") # Batch bulk-insert into AxarDB (batches of 1000) batch_size = 1000 for i in range(0, len(products), batch_size): chunk = products[i:i + batch_size] js_payload = f""" var batch = {json.dumps(chunk)}; batch.forEach(function(item) {{ var existing = db.products.find(p => p.id == item.id); if (existing) {{ Object.assign(existing, item); }} else {{ db.products.insert(item); }} }}); return {{ ingested: batch.length }}; """ resp = requests.post( AXARDB_URL, headers={ "Authorization": f"Bearer {AXARDB_KEY}", "Content-Type": "text/plain; charset=utf-8" }, data=js_payload.encode("utf-8") ) print(f"Batch {i // batch_size + 1} status: {resp.status_code}, result: {resp.text}") cur.close() conn.close() if __name__ == "__main__": migrate_postgres_to_axardb() ``` #### Step 2: Next.js Read-Through Acceleration API ```typescript // app/api/products/route.ts import { NextResponse } from "next/server"; import { Pool } from "pg"; const pgPool = new Pool({ connectionString: process.env.DATABASE_URL }); const AXARDB_SUBDOMAIN = "https://store-catalog.axardb.com"; const AXARDB_KEY = process.env.AXARDB_API_KEY!; export async function GET(request: Request) { const { searchParams } = new URL(request.url); const category = searchParams.get("category") || "electronics"; // 1. Try In-Memory AxarDB first (< 1ms latency) try { const axarRes = await fetch(`${AXARDB_SUBDOMAIN}/query`, { method: "POST", headers: { "Authorization": `Bearer ${AXARDB_KEY}`, "Content-Type": "text/plain; charset=utf-8" }, body: `return db.products.findall(p => p.category == "${category}" && p.stock > 0).take(20);`, cache: "no-store" }); if (axarRes.ok) { const data = await axarRes.json(); if (data.result && data.result.length > 0) { return NextResponse.json({ source: "axardb-memory", products: data.result }); } } } catch (err) { console.warn("AxarDB cache miss/error, falling back to PostgreSQL:", err); } // 2. Cache-Miss Fallback: Query PostgreSQL System of Record const pgResult = await pgPool.query( "SELECT id, title, price, stock, category FROM products WHERE category = $1 AND stock > 0 LIMIT 20", [category] ); // 3. Asynchronously hydrate AxarDB cache for subsequent requests fetch(`${AXARDB_SUBDOMAIN}/query`, { method: "POST", headers: { "Authorization": `Bearer ${AXARDB_KEY}`, "Content-Type": "text/plain; charset=utf-8" }, body: ` var items = ${JSON.stringify(pgResult.rows)}; items.forEach(item => db.products.insert(item)); return true; ` }).catch(() => {}); return NextResponse.json({ source: "postgresql-sor", products: pgResult.rows }); } ``` --- ### 11.3 MySQL Migration & Real-Time Leaderboard / Session Acceleration #### Scenario: High-Frequency Leaderboard & Session Store A gaming platform stores 50,000 players in MySQL. Recalculating the global top 100 leaderboard every second crushes MySQL CPU with `ORDER BY score DESC`. AxarDB maintains the live leaderboard in memory, updating immediately on score changes and serving top lists in microseconds. #### Migration & Real-Time Sync Pipeline (Node.js / TypeScript) ```typescript import mysql from "mysql2/promise"; const AXARDB_URL = "https://gaming-leaderboard.axardb.com/query"; const AXARDB_KEY = "axdb_live_YOUR_KEY"; async function syncMySqlToAxarDb() { const connection = await mysql.createConnection({ host: "localhost", user: "root", password: "password", database: "game_db" }); // Query top players from MySQL const [rows] = await connection.execute( "SELECT id, username, score, level, avatar_url, updated_at FROM players ORDER BY score DESC LIMIT 10000" ); console.log(`Fetched ${(rows as any[]).length} players from MySQL.`); // Ingest into AxarDB in-memory database const res = await fetch(AXARDB_URL, { method: "POST", headers: { "Authorization": `Bearer ${AXARDB_KEY}`, "Content-Type": "text/plain; charset=utf-8" }, body: ` var players = ${JSON.stringify(rows)}; players.forEach(function(p) { var existing = db.leaderboard.find(x => x.id == p.id); if (existing) { existing.score = p.score; existing.level = p.level; existing.updated_at = p.updated_at; } else { db.leaderboard.insert(p); } }); // Register public view for live top 10 ranking db.saveView("getTop100", \` // @access public return db.leaderboard .findall() .sort((a, b) => b.score - a.score) .take(100) .select((p, idx) => ({ rank: idx + 1, username: p.username, score: p.score, level: p.level })); \`); return "MySQL data synchronized and getTop100 Public View registered!"; ` }); const outcome = await res.json(); console.log("AxarDB sync result:", outcome); await connection.end(); } syncMySqlToAxarDb(); ``` #### Fast Client Query (Zero Credentials): Mobile games or web apps query the leaderboard without touching MySQL: ```bash curl "https://gaming-leaderboard.axardb.com/views/getTop100" ``` --- ### 11.4 MongoDB Migration & Edge Public View Offloading #### Scenario: MongoDB Telemetry & Activity Stream A fleet of IoT devices or mobile clients emits telemetry documents into MongoDB Atlas. Querying Atlas directly from mobile devices is insecure (requires connection strings or tokens) and expensive in Atlas compute tiers. By syncing summarized activity into AxarDB, clients query live metrics at the edge with zero credentials. #### Migration & Delta Ingestion Script (Python) ```python import pymongo import requests import json MONGO_URI = "mongodb+srv://app_user:secret@cluster0.mongodb.net/iot_db" AXARDB_URL = "https://iot-edge.axardb.com/query" AXARDB_KEY = "axdb_live_YOUR_KEY" def sync_mongodb_to_axardb(): client = pymongo.MongoClient(MONGO_URI) db = client["iot_db"] devices_col = db["device_telemetry"] # Extract latest telemetry per device from MongoDB pipeline = [ {"$sort": {"timestamp": -1}}, {"$group": { "_id": "$device_id", "battery": {"$first": "$battery"}, "temperature": {"$first": "$temperature"}, "status": {"$first": "$status"}, "last_seen": {"$first": "$timestamp"} }}, {"$limit": 5000} ] results = list(devices_col.aggregate(pipeline)) sanitized = [] for doc in results: sanitized.append({ "deviceId": doc["_id"], "battery": doc.get("battery", 100), "temperature": doc.get("temperature", 25.0), "status": doc.get("status", "online"), "lastSeen": doc.get("last_seen").isoformat() if doc.get("last_seen") else None }) # Bulk hydrate AxarDB in memory query_body = f""" var items = {json.dumps(sanitized)}; items.forEach(function(d) {{ var existing = db.telemetry.find(x => x.deviceId == d.deviceId); if (existing) {{ Object.assign(existing, d); }} else {{ db.telemetry.insert(d); }} }}); // Register Public View for device status check db.saveView("getDeviceLiveStatus", ` // @access public var dev = @id; var record = db.telemetry.find(x => x.deviceId == dev); if (!record) return {{ error: "Device not found" }}; return record; `); return {{ synced: items.length }}; """ res = requests.post( AXARDB_URL, headers={ "Authorization": f"Bearer {AXARDB_KEY}", "Content-Type": "text/plain; charset=utf-8" }, data=query_body.encode("utf-8") ) print("AxarDB response:", res.status_code, res.text) if __name__ == "__main__": sync_mongodb_to_axardb() ``` --- ### 11.5 Write-Through & Cache Invalidation Patterns When using AxarDB as an in-memory front-layer, data modifications in the primary database (PostgreSQL, MySQL, or MongoDB) must be propagated to AxarDB to avoid stale reads. #### Pattern A: Write-Through / Dual-Write Your application writes to the primary database first for ACID durability, then immediately updates the AxarDB in-memory document: ```typescript // Dual-write service function async function updateProductPrice(productId: number, newPrice: number) { // 1. Update primary database (PostgreSQL / MySQL) await pgClient.query("UPDATE products SET price = $1, updated_at = NOW() WHERE id = $2", [newPrice, productId]); // 2. Immediately update AxarDB in-memory cache (< 2ms) await fetch("https://store-catalog.axardb.com/query", { method: "POST", headers: { "Authorization": `Bearer ${process.env.AXARDB_API_KEY}`, "Content-Type": "text/plain; charset=utf-8" }, body: ` var item = db.products.find(p => p.id == ${productId}); if (item) { item.price = ${newPrice}; item.updated_at = new Date(); } return item ? "updated" : "not_found"; ` }); } ``` #### Pattern B: Database Trigger / Change Data Capture (CDC) Webhook You can trigger an HTTP webhook from PostgreSQL (`pg_notify` / pg_net) or MySQL (Debezium / server trigger) or MongoDB Change Streams: ```typescript // MongoDB Change Stream listener updating AxarDB in real time import { MongoClient } from "mongodb"; async function watchMongoStream() { const client = new MongoClient(process.env.MONGO_URI!); const collection = client.db("iot_db").collection("device_telemetry"); const changeStream = collection.watch([{ $match: { operationType: { $in: ["insert", "update", "replace"] } } }]); changeStream.on("change", async (change) => { const doc = change.fullDocument; if (!doc) return; await fetch("https://iot-edge.axardb.com/query", { method: "POST", headers: { "Authorization": `Bearer ${process.env.AXARDB_API_KEY}`, "Content-Type": "text/plain" }, body: ` var incoming = ${JSON.stringify(doc)}; var target = db.telemetry.find(x => x.deviceId == incoming.deviceId); if (target) Object.assign(target, incoming); else db.telemetry.insert(incoming); return true; ` }); }); } ``` --- ### 11.6 Terminal CLI Migration One-Liners For devops engineers and quick script migrations, you can pipe database dump utilities directly into AxarDB via standard UNIX pipes: #### 1. PostgreSQL to AxarDB in One Command: ```bash psql "postgresql://user:pass@localhost:5432/store" -t -A \ -c "SELECT json_agg(t) FROM (SELECT id, title, price, stock, category FROM products WHERE is_active = true) t;" | \ python3 -c ' import sys, json, requests rows = json.load(sys.stdin) js = f"var items = {json.dumps(rows)}; items.forEach(i => db.products.insert(i)); return {{ imported: items.length }};" res = requests.post("https://store-catalog.axardb.com/query", headers={"Authorization": "Bearer axdb_live_YOUR_KEY", "Content-Type": "text/plain; charset=utf-8"}, data=js.encode("utf-8")) print("AxarDB Import Result:", res.json()) ' ``` #### 2. MySQL to AxarDB in One Command: ```bash mysql -u root -p -D game_db --batch --raw -e "SELECT JSON_ARRAYAGG(JSON_OBJECT('id', id, 'username', username, 'score', score)) as data FROM players;" | \ tail -n 1 | \ python3 -c ' import sys, json, requests raw = sys.stdin.read().strip() items = json.loads(raw) js = f"var items = {json.dumps(items)}; items.forEach(i => db.leaderboard.insert(i)); return items.length;" res = requests.post("https://gaming-leaderboard.axardb.com/query", headers={"Authorization": "Bearer axdb_live_YOUR_KEY", "Content-Type": "text/plain"}, data=js.encode("utf-8")) print("Ingested players:", res.json()) ' ``` #### 3. MongoDB to AxarDB in One Command: ```bash mongoexport --uri="mongodb://localhost:27017/iot_db" --collection="device_telemetry" --jsonArray --limit=5000 | \ python3 -c ' import sys, json, requests docs = json.load(sys.stdin) # Clean MongoDB ObjectId $oid types clean_docs = [{k: (v["$oid"] if isinstance(v, dict) and "$oid" in v else v) for k, v in d.items()} for d in docs] js = f"var batch = {json.dumps(clean_docs)}; batch.forEach(d => db.telemetry.insert(d)); return batch.length;" res = requests.post("https://iot-edge.axardb.com/query", headers={"Authorization": "Bearer axdb_live_YOUR_KEY", "Content-Type": "text/plain; charset=utf-8"}, data=js.encode("utf-8")) print("MongoDB to AxarDB sync:", res.json()) ' ``` --- ### 11.7 Performance Benchmark Comparison Real-world benchmark comparing direct queries against traditional databases vs. AxarDB as an in-memory front-layer (10,000 concurrent requests, 50,000 documents): | Benchmark Parameter | Direct PostgreSQL | Direct MySQL | Direct MongoDB Atlas | AxarDB Cloud Front-Layer | |:---|:---|:---|:---|:---| | **Average Read Latency (p50)** | 32 ms | 28 ms | 41 ms | **0.8 ms** (40x faster) | | **P99 Tail Latency** | 185 ms | 160 ms | 240 ms | **3.2 ms** (60x faster) | | **Max Concurrency (RPS)** | ~1,200 req/sec | ~1,500 req/sec | ~950 req/sec | **18,500+ req/sec** | | **Primary DB CPU Usage** | 85% – 100% | 78% – 95% | 80% – 92% | **< 5%** (Idle / Offloaded) | | **Disk Read IOPS** | 2,400 IOPS | 2,100 IOPS | 3,100 IOPS | **0 IOPS** (100% in RAM) | | **Client Auth Model** | Backend proxy / secrets | Backend proxy / secrets | Mongo connection URI | **Zero-Credential Public Views** | --- ### 11.8 Best Practices for Data Migration & Ingestion 1. **Batch Size Tuning**: - Optimal batch size is **500 to 1,500 documents** per `/query` POST request. - For 100,000 records, chunk into 100 requests in parallel (up to 8 concurrent threads). 2. **Atomic Upsert Pattern in Pure JavaScript**: ```javascript var existing = db.myCollection.find(x => x.id == item.id); if (existing) { Object.assign(existing, item); } else { db.myCollection.insert(item); } ``` 3. **Periodic Watermark Sync (Incremental Sync)**: - Keep a `last_synced_at` timestamp. - Query `WHERE updated_at > last_synced_at` in MySQL/PostgreSQL and push only the diff to AxarDB every 30-60 seconds. 4. **Snapshot Persistence & Disaster Recovery**: - AxarDB automatically persists in-memory state snapshots to persistent encrypted cloud storage, ensuring that your accelerated cache survives container restarts without having to reload from the primary database.