Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa1bb459be | ||
|
|
d6703f9646 | ||
|
|
6d3b1e660a |
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -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 = ./.;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user