diff --git a/dbal/README.md b/dbal/README.md index a67f2bd80..2ac1ad030 100644 --- a/dbal/README.md +++ b/dbal/README.md @@ -166,7 +166,7 @@ permissions: ### HTTP Utilities -For outbound integrations the daemon can use the new requests-inspired helper `runtime::RequestsClient`. It wraps Drogon’s `HttpClient`, exposes `get`/`post` helpers, parses JSON responses, and throws clean timeouts so code paths stay predictable. +For outbound integrations the daemon can use the new requests-inspired helper `runtime::RequestsClient`. It wraps the `cpr` HTTP helpers, exposes `get`/`post` helpers, parses JSON responses, and throws clean timeouts so code paths stay predictable. Native Prisma calls route through `NativePrismaAdapter`, which currently POSTs to the `/api/native-prisma` Next.js API and returns the raw JSON rows or affected count using that helper. When the daemon calls `runQuery`/`runNonQuery`, the response is mapped back into `SqlRow` results so the rest of the stack stays unaware of the HTTP transport. diff --git a/dbal/cpp/src/runtime/requests_client.hpp b/dbal/cpp/src/runtime/requests_client.hpp index c23b8c339..4662cc04c 100644 --- a/dbal/cpp/src/runtime/requests_client.hpp +++ b/dbal/cpp/src/runtime/requests_client.hpp @@ -54,13 +54,7 @@ public: } else if (method == "POST") { response = cpr::Post(url, cprHeaders, cpr::Body(body), timeout); } else { - cpr::Session session; - session.SetUrl(url); - session.SetHeader(cprHeaders); - session.SetTimeout(timeout); - session.SetMethod(method); - session.SetBody(body); - response = session.Send(); + throw std::runtime_error("Unsupported HTTP method: " + method); } if (response.error) { diff --git a/dbal/cpp/tests/unit/client_test.cpp b/dbal/cpp/tests/unit/client_test.cpp index cb6dac433..801abb771 100644 --- a/dbal/cpp/tests/unit/client_test.cpp +++ b/dbal/cpp/tests/unit/client_test.cpp @@ -1205,6 +1205,45 @@ void test_lua_script_validation() { std::cout << " ✓ Allowed globals deduped" << std::endl; } +void test_lua_script_search() { + std::cout << "Testing Lua script search..." << std::endl; + + dbal::ClientConfig config; + config.adapter = "sqlite"; + config.database_url = ":memory:"; + dbal::Client client(config); + + dbal::CreateUserInput userInput; + userInput.username = "lua_search_owner"; + userInput.email = "lua_search_owner@example.com"; + auto userResult = client.createUser(userInput); + assert(userResult.isOk()); + + dbal::CreateLuaScriptInput scriptInput; + scriptInput.name = "search_script"; + scriptInput.code = "return 'search'"; + scriptInput.allowed_globals = {"math"}; + scriptInput.created_by = userResult.value().id; + auto createResult = client.createLuaScript(scriptInput); + assert(createResult.isOk()); + + dbal::CreateLuaScriptInput otherInput = scriptInput; + otherInput.name = "other_script"; + otherInput.code = "return 'other'"; + auto otherResult = client.createLuaScript(otherInput); + assert(otherResult.isOk()); + + auto searchResult = client.searchLuaScripts("search", userResult.value().id, 10); + assert(searchResult.isOk()); + assert(searchResult.value().size() == 1); + std::cout << " ✓ Script name search works" << std::endl; + + auto codeSearch = client.searchLuaScripts("return 'other'", std::nullopt, 10); + assert(codeSearch.isOk()); + assert(codeSearch.value().size() >= 1); + std::cout << " ✓ Script code search works" << std::endl; +} + void test_package_crud() { std::cout << "Testing package CRUD operations..." << std::endl; @@ -1409,6 +1448,7 @@ int main() { test_session_validation(); test_lua_script_crud(); test_lua_script_validation(); + test_lua_script_search(); test_package_crud(); test_package_validation(); test_package_batch_operations(); @@ -1416,7 +1456,7 @@ int main() { std::cout << std::endl; std::cout << "==================================================" << std::endl; - std::cout << "✅ All 31 test suites passed!" << std::endl; + std::cout << "✅ All 32 test suites passed!" << std::endl; std::cout << "==================================================" << std::endl; return 0; } catch (const std::exception& e) { diff --git a/dbal/docs/CAPABILITIES_IMPLEMENTATION.md b/dbal/docs/CAPABILITIES_IMPLEMENTATION.md index 7d26575b5..f145325ff 100644 --- a/dbal/docs/CAPABILITIES_IMPLEMENTATION.md +++ b/dbal/docs/CAPABILITIES_IMPLEMENTATION.md @@ -14,7 +14,7 @@ This document maps the capabilities declared in `api/schema/capabilities.yaml` t | `relations` | Prisma, SQLite | ✅ | Prisma adapter handles relations via `include`, while SQL adapters map foreign keys consistently once SQL statements cover them. | | `migrations` | Prisma (automatic) | ✅ | `prisma migrate` workflows run ahead of TS/C++ builds; refer to `prisma/migrations` and `package.json` scripts. | | `schema_introspection` | Prisma, SQLite | ✅ | Prisma schema is the source of truth, and the C++ daemon reads `api/schema` definitions when generating `SqlRow` conversions. | -| `connection_pooling` | Prisma + Drogon HTTP client | ✅ | Prisma client manages pools for TypeScript; C++ `SqlPool` plus `RequestsClient` ensures safe reuse of HTTP/SQL connections. | +| `connection_pooling` | Prisma + cpr HTTP client | ✅ | Prisma client manages pools for TypeScript; C++ `SqlPool` plus `RequestsClient` ensures safe reuse of HTTP/SQL connections. | | `read_replicas` | Prisma (optional) | ⚠️ | Prisma supports multiple datasources; DBAL proxies to the configured `DATABASE_URL` and allows future replica awareness through `NativePrismaAdapter`. | ## Cross-Cutting Features