From ce0ee46571ad27aac3e6889818075a6a040f7642 Mon Sep 17 00:00:00 2001 From: Derek Bourgeois Date: Wed, 25 Mar 2026 12:57:36 -0400 Subject: [PATCH 1/2] feat: add surreal cache store alias --- README.md | 16 +++++++++++++ config/cache.php | 8 +++++++ tests/Feature/DatabaseCacheOnSurrealTest.php | 24 ++++++++++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f0bfed..9e575a7 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,22 @@ Katra now includes a first Laravel-compatible Surreal schema driver for migratio - The current slice is intentionally narrow: table creation, field creation, field removal, and table removal are supported for common Katra field types. - This is still not full SQL-driver parity yet, but it is enough for Katra's current migration set and for Surreal-backed application schema work without relying on SQLite migration bookkeeping. +### Surreal-Backed Cache + +Katra also supports Laravel's cache abstraction against SurrealDB by pointing the database cache store at the `surreal` connection. + +- Set `CACHE_STORE=surreal` when you want the main cache store to live in SurrealDB. +- The dedicated `surreal` cache store alias uses Laravel's built-in `database` cache driver with the `surreal` connection, so application code can keep using normal `Cache` APIs. +- Override the table and connection names with `SURREAL_CACHE_CONNECTION`, `SURREAL_CACHE_TABLE`, `SURREAL_CACHE_LOCK_CONNECTION`, and `SURREAL_CACHE_LOCK_TABLE` if you need something other than the defaults. +- Make sure the cache tables are migrated on the Surreal connection before you rely on the store: + +```bash +php artisan migrate --path=database/migrations/0001_01_01_000001_create_cache_table.php +``` + +- Core cache operations like `get`, `put`, `add`, `many`, `forever`, `forget`, and `flush` are covered in the test suite against a real Surreal runtime. +- SQL-transaction-dependent limiter semantics are still treated as unsupported on Surreal-backed cache storage, so Katra keeps `CACHE_LIMITER=file` by default for Fortify throttling and other limiter middleware. + ## Planning Docs - [Katra v2 Overview](docs/v2-overview.md) diff --git a/config/cache.php b/config/cache.php index b31d488..16741c4 100644 --- a/config/cache.php +++ b/config/cache.php @@ -61,6 +61,14 @@ 'lock_table' => env('DB_CACHE_LOCK_TABLE'), ], + 'surreal' => [ + 'driver' => 'database', + 'connection' => env('SURREAL_CACHE_CONNECTION', 'surreal'), + 'table' => env('SURREAL_CACHE_TABLE', env('DB_CACHE_TABLE', 'cache')), + 'lock_connection' => env('SURREAL_CACHE_LOCK_CONNECTION', env('DB_CACHE_LOCK_CONNECTION', 'surreal')), + 'lock_table' => env('SURREAL_CACHE_LOCK_TABLE', env('DB_CACHE_LOCK_TABLE')), + ], + 'file' => [ 'driver' => 'file', 'path' => storage_path('framework/cache/data'), diff --git a/tests/Feature/DatabaseCacheOnSurrealTest.php b/tests/Feature/DatabaseCacheOnSurrealTest.php index a343849..e04f8bb 100644 --- a/tests/Feature/DatabaseCacheOnSurrealTest.php +++ b/tests/Feature/DatabaseCacheOnSurrealTest.php @@ -24,6 +24,8 @@ $originalCacheStore = config('cache.default'); $originalCacheDatabaseConnection = config('cache.stores.database.connection'); $originalCacheLockConnection = config('cache.stores.database.lock_connection'); + $originalSurrealCacheConnection = config('cache.stores.surreal.connection'); + $originalSurrealCacheLockConnection = config('cache.stores.surreal.lock_connection'); File::deleteDirectory($storagePath); File::ensureDirectoryExists(dirname($storagePath)); @@ -44,14 +46,17 @@ config()->set('surreal.storage_path', $storagePath); config()->set('surreal.runtime', 'local'); config()->set('surreal.autostart', false); - config()->set('cache.default', 'database'); + config()->set('cache.default', 'surreal'); config()->set('cache.stores.database.connection', 'surreal'); config()->set('cache.stores.database.lock_connection', 'surreal'); + config()->set('cache.stores.surreal.connection', 'surreal'); + config()->set('cache.stores.surreal.lock_connection', 'surreal'); app()->forgetInstance(SurrealConnection::class); app()->forgetInstance(SurrealRuntimeManager::class); DB::purge('surreal'); Cache::forgetDriver('database'); + Cache::forgetDriver('surreal'); app()->forgetInstance('cache'); app()->forgetInstance('cache.store'); app()->forgetInstance('migration.repository'); @@ -63,7 +68,7 @@ '--path' => database_path('migrations/0001_01_01_000001_create_cache_table.php'), ]))->toBe(0); - $store = Cache::store('database'); + $store = Cache::store('surreal'); expect($store->add('login:127.0.0.1', 'first-hit', 60))->toBeTrue() ->and($store->add('login:127.0.0.1', 'second-hit', 60))->toBeFalse() @@ -72,6 +77,18 @@ expect($store->put('login:127.0.0.1', 'updated-hit', 60))->toBeTrue() ->and($store->get('login:127.0.0.1'))->toBe('updated-hit'); + expect($store->put('recent-workspace', 'katra-local', 60))->toBeTrue() + ->and($store->many(['login:127.0.0.1', 'recent-workspace']))->toBe([ + 'login:127.0.0.1' => 'updated-hit', + 'recent-workspace' => 'katra-local', + ]); + + expect($store->forever('feature-flag:desktop-ui', true))->toBeTrue() + ->and($store->get('feature-flag:desktop-ui'))->toBeTrue(); + + expect($store->forget('recent-workspace'))->toBeTrue() + ->and($store->get('recent-workspace'))->toBeNull(); + expect($store->flush())->toBeTrue() ->and($store->get('login:127.0.0.1'))->toBeNull(); } finally { @@ -80,11 +97,14 @@ config()->set('cache.default', $originalCacheStore); config()->set('cache.stores.database.connection', $originalCacheDatabaseConnection); config()->set('cache.stores.database.lock_connection', $originalCacheLockConnection); + config()->set('cache.stores.surreal.connection', $originalSurrealCacheConnection); + config()->set('cache.stores.surreal.lock_connection', $originalSurrealCacheLockConnection); app()->forgetInstance(SurrealConnection::class); app()->forgetInstance(SurrealRuntimeManager::class); DB::purge('surreal'); Cache::forgetDriver('database'); + Cache::forgetDriver('surreal'); app()->forgetInstance('cache'); app()->forgetInstance('cache.store'); app()->forgetInstance('migration.repository'); From 7095d97fc62b89e5515298303e31203683f8a23c Mon Sep 17 00:00:00 2001 From: Derek Bourgeois Date: Wed, 25 Mar 2026 13:10:38 -0400 Subject: [PATCH 2/2] fix: tighten surreal cache defaults --- README.md | 2 +- config/cache.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e575a7..19431e8 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Katra also supports Laravel's cache abstraction against SurrealDB by pointing th - Make sure the cache tables are migrated on the Surreal connection before you rely on the store: ```bash -php artisan migrate --path=database/migrations/0001_01_01_000001_create_cache_table.php +php artisan migrate --database=surreal --path=database/migrations/0001_01_01_000001_create_cache_table.php ``` - Core cache operations like `get`, `put`, `add`, `many`, `forever`, `forget`, and `flush` are covered in the test suite against a real Surreal runtime. diff --git a/config/cache.php b/config/cache.php index 16741c4..ac063ae 100644 --- a/config/cache.php +++ b/config/cache.php @@ -65,7 +65,7 @@ 'driver' => 'database', 'connection' => env('SURREAL_CACHE_CONNECTION', 'surreal'), 'table' => env('SURREAL_CACHE_TABLE', env('DB_CACHE_TABLE', 'cache')), - 'lock_connection' => env('SURREAL_CACHE_LOCK_CONNECTION', env('DB_CACHE_LOCK_CONNECTION', 'surreal')), + 'lock_connection' => env('SURREAL_CACHE_LOCK_CONNECTION', env('DB_CACHE_LOCK_CONNECTION')), 'lock_table' => env('SURREAL_CACHE_LOCK_TABLE', env('DB_CACHE_LOCK_TABLE')), ],