Skip to content

PierreKieffer/distant-sqlite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Distant SQLite - SQLite gRPC Server

A gRPC server that provides remote access to SQLite database (concurrent access using SQLite's WAL mode)

Project Structure

distant-sqlite/ ├── src/ │ ├── main.rs # gRPC server entry point │ ├── client_auth.rs # Example client with authentication │ ├── auth.rs # Authentication module │ └── sqlite_server/ │ ├── mod.rs # Module exports │ └── sqlite_server.rs # Core SQLite service implementation ├── proto/ │ └── sqlite.proto # gRPC service definition ├── Cargo.toml # Dependencies and build configuration ├── build.rs # Protocol buffer compilation └── database.db # SQLite database file (created at runtime) 

Quick Start

Building the Project

# Clone the repository git clone <repository-url> cd distant-sqlite # Build the project cargo build --release # Run the server cargo run --bin server # run client example cargo run --bin client-auth

Client Implementation Examples

Rust Client

use tonic::{Request, metadata::MetadataValue}; use sqlite::sqlite_service_client::SqliteServiceClient; use sqlite::{ReadQueryRequest, WriteQueryRequest}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut client = SqliteServiceClient::connect("http://[::1]:50051").await?; let token = "secret-token-123"; // Authentication token // Create table with authentication let mut create_request = Request::new(WriteQueryRequest { query: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)".to_string(), }); // Add Bearer token to metadata create_request.metadata_mut().insert( "authorization", MetadataValue::from_str(&format!("Bearer {}", token))? ); client.exe_write_query(create_request).await?; // Insert data with authentication let mut insert_request = Request::new(WriteQueryRequest { query: "INSERT INTO users (name, age) VALUES ('Alice', 30)".to_string(), }); insert_request.metadata_mut().insert( "authorization", MetadataValue::from_str(&format!("Bearer {}", token))? ); client.exe_write_query(insert_request).await?; // Query data with authentication let mut read_request = Request::new(ReadQueryRequest { query: "SELECT * FROM users".to_string(), }); read_request.metadata_mut().insert( "authorization", MetadataValue::from_str(&format!("Bearer {}", token))? ); let response = client.exe_read_query(read_request).await?; // Process results... for row in response.into_inner().rows { for (column, value) in row.columns { match &value.value_type { Some(sqlite::value::ValueType::TextValue(s)) => println!("{}: {}", column, s), Some(sqlite::value::ValueType::IntegerValue(n)) => println!("{}: {}", column, n), Some(sqlite::value::ValueType::RealValue(f)) => println!("{}: {}", column, f), Some(sqlite::value::ValueType::NullValue(_)) => println!("{}: NULL", column), Some(sqlite::value::ValueType::BlobValue(b)) => println!("{}: {} bytes", column, b.len()), None => println!("{}: UNKNOWN", column), } } } Ok(()) }

Python Client

import grpc import sqlite_pb2 import sqlite_pb2_grpc async def main(): async with grpc.aio.insecure_channel('[::1]:50051') as channel: stub = sqlite_pb2_grpc.SqliteServiceStub(channel) # Authentication metadata metadata = [('authorization', 'Bearer secret-token-123')] # Create table with authentication request = sqlite_pb2.WriteQueryRequest( query="CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)" ) response = await stub.ExeWriteQuery(request, metadata=metadata) # Insert data with authentication request = sqlite_pb2.WriteQueryRequest( query="INSERT INTO users (name, age) VALUES ('Alice', 30)" ) response = await stub.ExeWriteQuery(request, metadata=metadata) # Query data with authentication request = sqlite_pb2.ReadQueryRequest(query="SELECT * FROM users") response = await stub.ExeReadQuery(request, metadata=metadata) for row in response.rows: for column, value in row.columns.items(): if value.HasField('text_value'): print(f"{column}: {value.text_value}") elif value.HasField('integer_value'): print(f"{column}: {value.integer_value}") elif value.HasField('real_value'): print(f"{column}: {value.real_value}") elif value.HasField('null_value'): print(f"{column}: NULL") elif value.HasField('blob_value'): print(f"{column}: {len(value.blob_value)} bytes")

SQLite Configuration

  • WAL Mode: Enables concurrent readers with writers
  • Synchronous NORMAL: Balances durability with performance
  • Busy Timeout: 30-second timeout for handling locked databases
  • WAL Autocheckpoint: Automatic cleanup every 1000 pages

About

SQLite gRPC Server

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages