feat: Add basic key-value store example
- Added a client and server for a simple key-value store. - Improved documentation with client and server usage examples. - Created client and server implementations using the V language.
This commit is contained in:
23
examples/data/ourdb_client.vsh
Executable file
23
examples/data/ourdb_client.vsh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
// Please note that before running this script you need to run the server first
|
||||
// See examples/data/ourdb_server.vsh
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import os
|
||||
|
||||
mut client := ourdb.new_client(
|
||||
port: 3000
|
||||
host: 'localhost'
|
||||
)!
|
||||
|
||||
set := client.set('hello')!
|
||||
get := client.get(set.id)!
|
||||
|
||||
assert set.id == get.id
|
||||
|
||||
println('Set result: ${set}')
|
||||
println('Get result: ${get}')
|
||||
|
||||
// test delete functionality
|
||||
|
||||
client.delete(set.id)!
|
||||
@@ -4,7 +4,7 @@ import freeflowuniverse.herolib.data.ourdb
|
||||
import os
|
||||
|
||||
mut server := ourdb.new_server(
|
||||
port: 9000
|
||||
port: 3000
|
||||
allowed_hosts: ['localhost']
|
||||
allowed_operations: ['set', 'get', 'delete']
|
||||
secret_key: 'secret'
|
||||
|
||||
35
lib/data/ourdb/CLIENT.md
Normal file
35
lib/data/ourdb/CLIENT.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# OurDB Client
|
||||
|
||||
## Overview
|
||||
This client is created to interact with an OurDB server.
|
||||
|
||||
## Prerequisites
|
||||
Before running the client script, ensure that the OurDB server is up and running. You can start the server by following the instructions in the [OurDB Server README](./SERVER.md).
|
||||
|
||||
## Installation
|
||||
|
||||
Ensure you have the V programming language installed. You can download it from [vlang.io](https://vlang.io/).
|
||||
|
||||
## Running the Client
|
||||
|
||||
Once the OurDB server is running, execute the client script:
|
||||
```sh
|
||||
examples/data/ourdb_client.vsh
|
||||
```
|
||||
|
||||
Alternatively, you can run it using V:
|
||||
```sh
|
||||
v -enable-globals run ourdb_client.vsh
|
||||
```
|
||||
|
||||
## How It Works
|
||||
1. Connects to the OurDB server on `localhost:3000`.
|
||||
2. Sets a record with the value `hello`.
|
||||
3. Retrieves the record by ID and verifies the stored value.
|
||||
4. Deletes the record.
|
||||
|
||||
## Example Output
|
||||
```
|
||||
Set result: { id: 1, value: 'hello' }
|
||||
Get result: { id: 1, value: 'hello' }
|
||||
```
|
||||
90
lib/data/ourdb/client.v
Normal file
90
lib/data/ourdb/client.v
Normal file
@@ -0,0 +1,90 @@
|
||||
module ourdb
|
||||
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import json
|
||||
|
||||
pub struct OurDBClient {
|
||||
pub mut:
|
||||
conn httpconnection.HTTPConnection
|
||||
port int // Server port, default is 3000
|
||||
host string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct OurDBClientArgs {
|
||||
pub mut:
|
||||
port int = 3000 // Server port, default is 3000
|
||||
host string = 'localhost' // Server host
|
||||
}
|
||||
|
||||
struct Response[T] {
|
||||
message string // Success message
|
||||
data T // Response data
|
||||
}
|
||||
|
||||
pub fn new_client(args OurDBClientArgs) !OurDBClient {
|
||||
mut client := OurDBClient{
|
||||
port: args.port
|
||||
host: args.host
|
||||
}
|
||||
client.conn = client.connection()!
|
||||
console.print_green('Client started')
|
||||
return client
|
||||
}
|
||||
|
||||
fn (mut client OurDBClient) connection() !&httpconnection.HTTPConnection {
|
||||
mut http := httpconnection.new(
|
||||
name: 'ourdb_client'
|
||||
url: 'http://${client.host}:${client.port}'
|
||||
cache: true
|
||||
retry: 3
|
||||
)!
|
||||
|
||||
client.conn = http
|
||||
return http
|
||||
}
|
||||
|
||||
// Sets a value in the database
|
||||
pub fn (mut client OurDBClient) set(data string) !KeyValueData {
|
||||
mut request_body := json.encode({
|
||||
'value': data
|
||||
})
|
||||
|
||||
req := httpconnection.Request{
|
||||
prefix: 'set'
|
||||
method: .post
|
||||
data: request_body
|
||||
}
|
||||
|
||||
mut http := client.connection()!
|
||||
response := http.post_json_str(req)!
|
||||
|
||||
mut decoded_response := json.decode(Response[KeyValueData], response)!
|
||||
return decoded_response.data
|
||||
}
|
||||
|
||||
// Gets a value in the database based on it's ID
|
||||
pub fn (mut client OurDBClient) get(id u32) !KeyValueData {
|
||||
req := httpconnection.Request{
|
||||
prefix: 'get/${id}'
|
||||
method: .get
|
||||
}
|
||||
|
||||
mut http := client.connection()!
|
||||
response := http.get_json(req)!
|
||||
|
||||
mut decoded_response := json.decode(Response[KeyValueData], response)!
|
||||
return decoded_response.data
|
||||
}
|
||||
|
||||
// Deletes a value in the database based on it's ID
|
||||
pub fn (mut client OurDBClient) delete(id u32) ! {
|
||||
req := httpconnection.Request{
|
||||
prefix: 'delete/${id}'
|
||||
method: .delete
|
||||
}
|
||||
|
||||
mut http := client.connection()!
|
||||
http.delete(req) or { return error('Failed to delete key due to: ${err}') }
|
||||
}
|
||||
@@ -136,8 +136,8 @@ fn (server OurDBServer) success[T](args SuccessResponse[T]) SuccessResponse[T] {
|
||||
}
|
||||
|
||||
// Request body structure for the `/set` endpoint
|
||||
struct SetRequestBody {
|
||||
mut:
|
||||
pub struct KeyValueData {
|
||||
pub mut:
|
||||
id u32 // Record ID
|
||||
value string // Value to store
|
||||
}
|
||||
@@ -146,7 +146,7 @@ mut:
|
||||
@['/set'; post]
|
||||
pub fn (mut server OurDBServer) set(mut ctx ServerContext) veb.Result {
|
||||
request_body := ctx.req.data.str()
|
||||
mut decoded_body := json.decode(SetRequestBody, request_body) or {
|
||||
mut decoded_body := json.decode(KeyValueData, request_body) or {
|
||||
ctx.res.set_status(.bad_request)
|
||||
return ctx.json[ErrorResponse](server.error(
|
||||
error: 'bad_request'
|
||||
@@ -197,7 +197,7 @@ pub fn (mut server OurDBServer) get(mut ctx ServerContext, id string) veb.Result
|
||||
))
|
||||
}
|
||||
|
||||
data := SetRequestBody{
|
||||
data := KeyValueData{
|
||||
id: id_
|
||||
value: record.bytestr()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user