ProtonDB C++ Client
A robust C++ client library for interacting with ProtonDB via TCP, providing a PostgreSQL-like interface for NoSQL operations.
Overview
This is a complete C++ client library for ProtonDB, a lightweight embedded NoSQL database. The library provides a clean, PostgreSQL-inspired interface (psycopg2-style) for managing connections, executing queries, and handling responses over TCP.
Built as a fork contribution to the main ProtonDB project, this client simplifies database operations through high-level abstractions while maintaining full control over socket-level communication and error handling.
Architecture & Core Classes
The library is structured around five main classes that work together to provide a complete database client interface:
Connection
Manages TCP/TLS connections to ProtonDB servers, handles login authentication, automatic reconnection, and timeout management. Supports both IPv4 and IPv6 with configurable retry logic and connection pooling.
Connection conn = Connection::Connect("127.0.0.1", 9090, "admin", "password");
Cursor
Executes queries and manages result sets. Supports both DSL commands and raw JSON protocol messages, with automatic response parsing and validation.
cursor.execute("demo.insert({\"name\": \"Allan\", \"role\": \"admin\"})");
cursor.fetch();
SocketHandle & SocketIO
RAII socket management with reliable send/receive operations. Handles partial sends, retries for transient errors, and cross-platform socket operations (Windows/Unix).
ScriptRunner
Batch processing for .pdb scripts with error handling callbacks. Processes commands line by line with configurable error recovery strategies.
Exception Hierarchy
Structured exception handling with ConnectionError, TimeoutError, ProtocolError, and ScriptParseError. Supports exception chaining with detailed error context.
Key Features
Robust Connection Management
Automatic reconnection with configurable timeouts for connect, send, and receive operations. Handles connection drops gracefully and supports TLS encryption for secure connections.
Query Flexibility
Execute queries in DSL format (collection.insert(...)) or raw JSON protocol messages. Both approaches support the full ProtonDB command set with consistent error handling.
Cross-Platform Socket Layer
Native socket handling for Windows and Unix systems. Includes retry logic for EINTR/EAGAIN errors and proper resource cleanup through RAII patterns.
Script Execution
Process entire .pdb script files with line-by-line error handling. Custom error callbacks allow graceful handling of failed commands without stopping the entire batch.
JSON Response Parsing
Automatic parsing of ProtonDB responses into structured objects. Extract status, result, message fields with built-in validation and error reporting.
Usage Examples
Basic Connection & Queries
// Establish connection
protondb::Connection conn = protondb::Connection::Connect("127.0.0.1", 9090, "admin", "password");
// Create cursor and execute commands
protondb::Cursor cursor(conn);
cursor.execute("db.use(\"mydb\")");
cursor.fetch();
// Insert document
cursor.execute("users.insert({\"name\": \"John\", \"age\": 25})");
cursor.fetch();
std::cout << cursor.status() << ": " << cursor.message() << std::endl;
// Query documents
cursor.execute("users.print(age > 20)");
cursor.fetch();
std::cout << cursor.result() << std::endl;
Script Execution
// Execute .pdb script file
protondb::ScriptRunner runner(conn);
runner.onScriptError([](const std::string& line, const std::exception& err) {
std::cerr << "Error on line: " << line << " - " << err.what() << std::endl;
});
runner.executeScript("setup.pdb");
Raw JSON Commands
// Send raw protocol message
std::string raw = R"({"Command":"QUERY","Data":"collection.create(\"products\")"})";
cursor.executeRaw(raw);
cursor.fetch();
Technical Implementation
Socket Layer
Low-level socket management using platform-specific APIs (select(), WSAGetLastError()) with proper error handling and timeout support. All socket operations are wrapped in RAII classes to prevent resource leaks.
Protocol Implementation
Full implementation of the ProtonDB TCP protocol using UTF-8 JSON lines. Commands follow the format {"Command": "QUERY", "Data": "..."} with structured responses containing status, message, and result fields.
Memory Management
Modern C++ patterns with move semantics, RAII resource management, and exception safety. No manual memory management or raw pointers in the public interface.
Error Handling Strategy
Hierarchical exception system with specific error types for different failure modes. Supports exception chaining to preserve the full error context through the call stack.
Build & Testing
CMake Build System
Standard CMake configuration with support for different build types and optional JSON library integration. Examples and tests are built as separate targets.
cmake -S . -B build
cd build
make
./example_basic
Comprehensive Test Suite
Unit tests for all major components including connection handling, query execution, script processing, and exception scenarios.
cmake -DTEST_NAME="connection" -S . -B build
cd build
make
./test_connection
Examples
Basic usage example demonstrates connection setup, query execution, and response handling. Library management system shows a complete CRUD application using the client.
Project Context
This C++ client was developed as a contribution to the ProtonDB project, filling the need for a robust native client library. While ProtonDB already had Python and C# clients, the C++ community needed a clean, efficient way to interact with the database.
The implementation follows PostgreSQL client patterns (psycopg2-style API) to provide familiarity for developers coming from traditional SQL databases while adapting to ProtonDB's document-oriented approach.
Forked from the main ProtonDB repository, this client extends the ecosystem and demonstrates how to build robust database client libraries in modern C++.
Comments