hasql-1.10.3.4: src/engine-tests/Hasql/Engine/Structures/StatementCacheSpec.hs
module Hasql.Engine.Structures.StatementCacheSpec (spec) where
import Data.Maybe
import Database.PostgreSQL.LibPQ (Oid (..))
import Hasql.Engine.Structures.StatementCache qualified as StatementCache
import Test.Hspec
spec :: Spec
spec = do
describe "empty" do
it "returns Nothing on lookup" do
StatementCache.lookup "SELECT 1" [] StatementCache.empty
`shouldBe` Nothing
describe "insert and lookup" do
it "can insert and retrieve a statement" do
let (remoteKey, cache) = StatementCache.insert "SELECT 1" [] StatementCache.empty
StatementCache.lookup "SELECT 1" [] cache
`shouldBe` Just remoteKey
it "generates unique remote keys for different SQL" do
let (key1, cache1) = StatementCache.insert "SELECT 1" [] StatementCache.empty
(key2, _cache2) = StatementCache.insert "SELECT 2" [] cache1
key1 `shouldNotBe` key2
it "generates unique remote keys for same SQL with different OIDs" do
let oid23 = Oid 23
oid25 = Oid 25
(key1, cache1) = StatementCache.insert "SELECT $1" [oid23] StatementCache.empty
(key2, _cache2) = StatementCache.insert "SELECT $1" [oid25] cache1
key1 `shouldNotBe` key2
it "distinguishes statements with same SQL but different OIDs" do
let oid23 = Oid 23
oid25 = Oid 25
(_key1, cache1) = StatementCache.insert "SELECT $1" [oid23] StatementCache.empty
(_key2, cache2) = StatementCache.insert "SELECT $1" [oid25] cache1
-- Both should be findable
StatementCache.lookup "SELECT $1" [oid23] cache2
`shouldSatisfy` isJust
StatementCache.lookup "SELECT $1" [oid25] cache2
`shouldSatisfy` isJust
-- And should have different remote keys
let rk1 = StatementCache.lookup "SELECT $1" [oid23] cache2
rk2 = StatementCache.lookup "SELECT $1" [oid25] cache2
rk1 `shouldNotBe` rk2
it "returns Nothing for a non-inserted SQL" do
let (_key, cache) = StatementCache.insert "SELECT 1" [] StatementCache.empty
StatementCache.lookup "SELECT 2" [] cache
`shouldBe` Nothing
it "returns Nothing for matching SQL but different OIDs" do
let oid23 = Oid 23
oid25 = Oid 25
(_key, cache) = StatementCache.insert "SELECT $1" [oid23] StatementCache.empty
StatementCache.lookup "SELECT $1" [oid25] cache
`shouldBe` Nothing
it "handles empty OID list" do
let (key, cache) = StatementCache.insert "SELECT 1" [] StatementCache.empty
StatementCache.lookup "SELECT 1" [] cache
`shouldBe` Just key
it "handles multiple OIDs" do
let oids = [Oid 23, Oid 25, Oid 1043]
(key, cache) = StatementCache.insert "SELECT $1, $2, $3" oids StatementCache.empty
StatementCache.lookup "SELECT $1, $2, $3" oids cache
`shouldBe` Just key
it "distinguishes different OID ordering" do
let oidsA = [Oid 23, Oid 25]
oidsB = [Oid 25, Oid 23]
(_keyA, cache1) = StatementCache.insert "SELECT $1, $2" oidsA StatementCache.empty
(_keyB, cache2) = StatementCache.insert "SELECT $1, $2" oidsB cache1
StatementCache.lookup "SELECT $1, $2" oidsA cache2
`shouldSatisfy` isJust
StatementCache.lookup "SELECT $1, $2" oidsB cache2
`shouldSatisfy` isJust
let rkA = StatementCache.lookup "SELECT $1, $2" oidsA cache2
rkB = StatementCache.lookup "SELECT $1, $2" oidsB cache2
rkA `shouldNotBe` rkB
describe "reset" do
it "clears all cached statements" do
let (_key, cache) = StatementCache.insert "SELECT 1" [] StatementCache.empty
resetCache = StatementCache.reset cache
StatementCache.lookup "SELECT 1" [] resetCache
`shouldBe` Nothing
it "results in a cache equal to empty" do
let (_key, cache) = StatementCache.insert "SELECT 1" [] StatementCache.empty
StatementCache.reset cache
`shouldBe` StatementCache.empty