Author SHA1 Message Date
paul aa1bb459be Set system to aarch64-darwin 2025-07-15 16:44:15 +02:00
paul d6703f9646 Add tuple decoding into multiple records 2024-07-03 17:00:58 +02:00
paul 6d3b1e660a Slightly change readme example code 2024-07-03 11:22:18 +02:00
4 changed files with 32 additions and 3 deletions
+2 -2
View File
@@ -34,7 +34,7 @@ data User = User
instance Opium.FromRow User where instance Opium.FromRow User where
getUsers :: Connection -> IO (Either Opium.Error [User]) getUsers :: Connection -> IO (Either Opium.Error [User])
getUsers conn = Opium.fetch_ "SELECT * FROM user" conn getUsers = Opium.fetch_ "SELECT * FROM user"
``` ```
The `Opium.FromRow` instance is implemented generically for all product types ("records"). It looks up the field name in the query result and decodes the column value using `Opium.FromField`. The `Opium.FromRow` instance is implemented generically for all product types ("records"). It looks up the field name in the query result and decodes the column value using `Opium.FromField`.
@@ -51,7 +51,7 @@ instance Opium.FromRow ScoreByAge where
getScoreByAge :: Connection -> IO ScoreByAge getScoreByAge :: Connection -> IO ScoreByAge
getScoreByAge conn = do getScoreByAge conn = do
let query = "SELECT regr_intercept(score, age) AS t, regr_slope(score, age) AS m FROM user" let query = "SELECT regr_intercept(score, age) AS t, regr_slope(score, age) AS m FROM user"
Right [x] <- Opium.fetch_ query conn Right (Identity x) <- Opium.fetch_ query conn
pure x pure x
``` ```
+1 -1
View File
@@ -3,7 +3,7 @@
outputs = { self, nixpkgs }: outputs = { self, nixpkgs }:
let let
system = "x86_64-linux"; system = "aarch64-darwin";
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
opium = pkgs.haskellPackages.developPackage { opium = pkgs.haskellPackages.developPackage {
root = ./.; root = ./.;
+22
View File
@@ -53,12 +53,34 @@ class FromRow a where
fromRow result columnTable row = fromRow result columnTable row =
runExceptT $ to <$> fromRow' @0 FRProxy (FromRowCtx result columnTable) row runExceptT $ to <$> fromRow' @0 FRProxy (FromRowCtx result columnTable) row
instance
( Generic a
, GetColumnTable' (Rep a)
, FromRow' 0 (Rep a)
, Generic b
, GetColumnTable' (Rep b)
, FromRow' (NumberOfMembers (Rep a)) (Rep b)
) => FromRow (a, b) where
getColumnTable Proxy result = runExceptT $ do
ctA <- newColumnTable <$> getColumnTable' @(Rep a) Proxy result
ctB <- newColumnTable <$> getColumnTable' @(Rep b) Proxy result
pure $ ctA `concatColumnTables` ctB
fromRow result ct row = runExceptT $ do
x <- to <$> fromRow' @0 FRProxy (FromRowCtx result ct) row
y <- to <$> fromRow' @(NumberOfMembers (Rep a)) FRProxy (FromRowCtx result ct) row
pure (x, y)
newtype ColumnTable = ColumnTable (Vector (Column, Oid)) newtype ColumnTable = ColumnTable (Vector (Column, Oid))
deriving (Eq, Show) deriving (Eq, Show)
newColumnTable :: [(Column, Oid)] -> ColumnTable newColumnTable :: [(Column, Oid)] -> ColumnTable
newColumnTable = ColumnTable . Vector.fromList newColumnTable = ColumnTable . Vector.fromList
concatColumnTables :: ColumnTable -> ColumnTable -> ColumnTable
concatColumnTables (ColumnTable a) (ColumnTable b) =
ColumnTable $ a <> b
indexColumnTable :: ColumnTable -> Int -> (Column, Oid) indexColumnTable :: ColumnTable -> Int -> (Column, Oid)
indexColumnTable (ColumnTable v) i = v `Vector.unsafeIndex` i indexColumnTable (ColumnTable v) i = v `Vector.unsafeIndex` i
+7
View File
@@ -122,6 +122,13 @@ spec = do
row <- Opium.fromRow result columnTable 0 row <- Opium.fromRow result columnTable 0
row `shouldBe` Right (ManyFields "abc" 42 1.0 "test" True) row `shouldBe` Right (ManyFields "abc" 42 1.0 "test" True)
it "Decodes multiple records into a tuple" $ \conn -> do
Just result <- LibPQ.execParams conn "SELECT 'albus' AS name, 123 AS age, 42 AS only" [] LibPQ.Binary
Right columnTable <- Opium.getColumnTable @(Person, Only Int) Proxy result
row <- Opium.fromRow @(Person, Only Int) result columnTable 0
row `shouldBe` Right (Person "albus" 123, Only 42)
describe "fetch" $ do describe "fetch" $ do
it "Passes numbered parameters and retrieves a list of rows" $ \conn -> do it "Passes numbered parameters and retrieves a list of rows" $ \conn -> do
rows <- Opium.fetch "SELECT ($1 + $2) AS only" (17 :: Int, 25 :: Int) conn rows <- Opium.fetch "SELECT ($1 + $2) AS only" (17 :: Int, 25 :: Int) conn