138 lines
4.0 KiB
Odin
138 lines
4.0 KiB
Odin
|
|
package main
|
||
|
|
|
||
|
|
import "core:fmt"
|
||
|
|
import "core:mem"
|
||
|
|
import "core:os"
|
||
|
|
import "core:strconv"
|
||
|
|
//import "core:strings" // I know we'll use in future but because we're not right now, compiler is complaining
|
||
|
|
import "rocksdb"
|
||
|
|
|
||
|
|
Config :: struct {
|
||
|
|
host: string,
|
||
|
|
port: int,
|
||
|
|
data_dir: string,
|
||
|
|
verbose: bool,
|
||
|
|
}
|
||
|
|
|
||
|
|
main :: proc() {
|
||
|
|
// Parse configuration
|
||
|
|
config := parse_config()
|
||
|
|
|
||
|
|
// Print banner
|
||
|
|
print_banner(config)
|
||
|
|
|
||
|
|
// Create data directory
|
||
|
|
os.make_directory(config.data_dir)
|
||
|
|
|
||
|
|
// Initialize storage engine
|
||
|
|
db, err := rocksdb.db_open(config.data_dir, true)
|
||
|
|
if err != .None {
|
||
|
|
fmt.eprintln("Failed to initialize storage:", err)
|
||
|
|
os.exit(1)
|
||
|
|
}
|
||
|
|
defer rocksdb.db_close(&db)
|
||
|
|
|
||
|
|
fmt.printfln("Storage engine initialized at %s", config.data_dir)
|
||
|
|
fmt.printfln("Starting DynamoDB-compatible server on %s:%d", config.host, config.port)
|
||
|
|
|
||
|
|
// Create HTTP server
|
||
|
|
server_config := default_server_config()
|
||
|
|
|
||
|
|
// For now, use a simple echo handler until we implement the full DynamoDB handler
|
||
|
|
server, server_ok := server_init(
|
||
|
|
context.allocator,
|
||
|
|
config.host,
|
||
|
|
config.port,
|
||
|
|
handle_http_request,
|
||
|
|
&db,
|
||
|
|
server_config,
|
||
|
|
)
|
||
|
|
|
||
|
|
if !server_ok {
|
||
|
|
fmt.eprintln("Failed to initialize HTTP server")
|
||
|
|
os.exit(1)
|
||
|
|
}
|
||
|
|
defer server_stop(&server)
|
||
|
|
|
||
|
|
fmt.println("Ready to accept connections!")
|
||
|
|
|
||
|
|
// Start server (blocks)
|
||
|
|
if !server_start(&server) {
|
||
|
|
fmt.eprintln("Server failed to start")
|
||
|
|
os.exit(1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Temporary HTTP request handler
|
||
|
|
// TODO: Replace with full DynamoDB handler once dynamodb/handler.odin is implemented
|
||
|
|
handle_http_request :: proc(ctx: rawptr, request: ^HTTP_Request, request_alloc: mem.Allocator) -> HTTP_Response {
|
||
|
|
//db := cast(^rocksdb.DB)ctx // I know we'll use in future but because we're not right now, compiler is complaining
|
||
|
|
|
||
|
|
response := response_init(request_alloc)
|
||
|
|
response_add_header(&response, "Content-Type", "application/x-amz-json-1.0")
|
||
|
|
response_add_header(&response, "x-amzn-RequestId", "local-request-id")
|
||
|
|
|
||
|
|
// Get X-Amz-Target header
|
||
|
|
target := request_get_header(request, "X-Amz-Target")
|
||
|
|
|
||
|
|
if t, ok := target.?; ok {
|
||
|
|
// Echo back the operation for now
|
||
|
|
body := fmt.aprintf("{{\"operation\":\"%s\",\"status\":\"not_implemented\"}}", t)
|
||
|
|
response_set_body(&response, transmute([]byte)body)
|
||
|
|
} else {
|
||
|
|
response_set_status(&response, .Bad_Request)
|
||
|
|
response_set_body(&response, transmute([]byte)string("{\"error\":\"Missing X-Amz-Target header\"}"))
|
||
|
|
}
|
||
|
|
|
||
|
|
return response
|
||
|
|
}
|
||
|
|
|
||
|
|
parse_config :: proc() -> Config {
|
||
|
|
config := Config{
|
||
|
|
host = "0.0.0.0",
|
||
|
|
port = 8002,
|
||
|
|
data_dir = "./data",
|
||
|
|
verbose = false,
|
||
|
|
}
|
||
|
|
|
||
|
|
// Environment variables
|
||
|
|
if port_str, env_ok := os.lookup_env("JORMUN_PORT"); env_ok {
|
||
|
|
if port, parse_ok := strconv.parse_int(port_str); parse_ok {
|
||
|
|
config.port = port
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if host, ok := os.lookup_env("JORMUN_HOST"); ok {
|
||
|
|
config.host = host
|
||
|
|
}
|
||
|
|
|
||
|
|
if data_dir, ok := os.lookup_env("JORMUN_DATA_DIR"); ok {
|
||
|
|
config.data_dir = data_dir
|
||
|
|
}
|
||
|
|
|
||
|
|
if verbose, ok := os.lookup_env("JORMUN_VERBOSE"); ok {
|
||
|
|
config.verbose = verbose == "1"
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO: Parse command line arguments
|
||
|
|
|
||
|
|
return config
|
||
|
|
}
|
||
|
|
|
||
|
|
print_banner :: proc(config: Config) {
|
||
|
|
banner := `
|
||
|
|
╔═══════════════════════════════════════════════╗
|
||
|
|
║ ║
|
||
|
|
║ ╦╔═╗╦═╗╔╦╗╦ ╦╔╗╔╔╦╗╔╗ ║
|
||
|
|
║ ║║ ║╠╦╝║║║║ ║║║║ ║║╠╩╗ ║
|
||
|
|
║ ╚╝╚═╝╩╚═╩ ╩╚═╝╝╚╝═╩╝╚═╝ ║
|
||
|
|
║ ║
|
||
|
|
║ DynamoDB-Compatible Database ║
|
||
|
|
║ Powered by RocksDB + Odin ║
|
||
|
|
║ ║
|
||
|
|
╚═══════════════════════════════════════════════╝
|
||
|
|
`
|
||
|
|
fmt.println(banner)
|
||
|
|
fmt.printfln(" Port: %d | Data Dir: %s\n", config.port, config.data_dir)
|
||
|
|
}
|