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) }