packages feed

opaleye 0.6.7002.0 → 0.6.7003.0

raw patch · 9 files changed

+314/−268 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Opaleye.Internal.Table: data Zip a
+ Opaleye: NonNullable :: Nullability
+ Opaleye: Nullable :: Nullability
+ Opaleye: data Cursor haskells
+ Opaleye: data Nullability
+ Opaleye: runSelect :: Default FromFields fields haskells => Connection -> Select fields -> IO [haskells]
+ Opaleye: runSelectExplicit :: FromFields fields haskells -> Connection -> Select fields -> IO [haskells]
+ Opaleye: runSelectFold :: Default FromFields fields haskells => Connection -> Select fields -> b -> (b -> haskells -> IO b) -> IO b
+ Opaleye: runSelectFoldExplicit :: FromFields fields haskells -> Connection -> Select fields -> b -> (b -> haskells -> IO b) -> IO b
+ Opaleye: runSelectTF :: Default FromFields (rec O) (rec H) => Connection -> Select (rec O) -> IO [rec H]
+ Opaleye: type Field a = Field_ 'NonNullable a
+ Opaleye: type FieldNullable a = Field_ 'Nullable a
+ Opaleye: type FromField = QueryRunnerColumn
+ Opaleye: type FromFields = QueryRunner
+ Opaleye.Internal.Table: newtype Zip a
+ Opaleye.Internal.Table: tableField :: TableColumn writeType sqlType => String -> TableFields writeType (Column sqlType)
+ Opaleye.Internal.Table: type TableFields = TableProperties
+ Opaleye.RunSelect: runSelectTF :: Default FromFields (rec O) (rec H) => Connection -> Select (rec O) -> IO [rec H]
+ Opaleye.Table: tableField :: TableColumn writeType sqlType => String -> TableFields writeType (Column sqlType)
+ Opaleye.Table: type TableFields = TableProperties
- Opaleye.Internal.Table: Table :: String -> (TableColumns writerColumns viewColumns) -> Table writerColumns viewColumns
+ Opaleye.Internal.Table: Table :: String -> (TableFields writerColumns viewColumns) -> Table writerColumns viewColumns
- Opaleye.Internal.Table: TableWithSchema :: String -> String -> (TableColumns writerColumns viewColumns) -> Table writerColumns viewColumns
+ Opaleye.Internal.Table: TableWithSchema :: String -> String -> (TableFields writerColumns viewColumns) -> Table writerColumns viewColumns
- Opaleye.Internal.Table: optional :: String -> TableColumns (Maybe (Column a)) (Column a)
+ Opaleye.Internal.Table: optional :: String -> TableFields (Maybe (Column a)) (Column a)
- Opaleye.Internal.Table: required :: String -> TableColumns (Column a) (Column a)
+ Opaleye.Internal.Table: required :: String -> TableFields (Column a) (Column a)
- Opaleye.Internal.Table: tableColumn :: TableColumn writeType sqlType => String -> TableColumns writeType (Column sqlType)
+ Opaleye.Internal.Table: tableColumn :: TableColumn writeType sqlType => String -> TableFields writeType (Column sqlType)
- Opaleye.Internal.Table: tableColumns :: Table writeColumns viewColumns -> TableColumns writeColumns viewColumns
+ Opaleye.Internal.Table: tableColumns :: Table writeColumns viewColumns -> TableFields writeColumns viewColumns
- Opaleye.Internal.Table: tableColumnsView :: TableColumns writeColumns viewColumns -> View viewColumns
+ Opaleye.Internal.Table: tableColumnsView :: TableFields writeColumns viewColumns -> View viewColumns
- Opaleye.Internal.Table: tableColumnsWriter :: TableColumns writeColumns viewColumns -> Writer writeColumns viewColumns
+ Opaleye.Internal.Table: tableColumnsWriter :: TableFields writeColumns viewColumns -> Writer writeColumns viewColumns
- Opaleye.Internal.Table: tableProperties :: Table writeColumns viewColumns -> TableColumns writeColumns viewColumns
+ Opaleye.Internal.Table: tableProperties :: Table writeColumns viewColumns -> TableFields writeColumns viewColumns
- Opaleye.Table: Table :: String -> (TableColumns writerColumns viewColumns) -> Table writerColumns viewColumns
+ Opaleye.Table: Table :: String -> (TableFields writerColumns viewColumns) -> Table writerColumns viewColumns
- Opaleye.Table: TableWithSchema :: String -> String -> (TableColumns writerColumns viewColumns) -> Table writerColumns viewColumns
+ Opaleye.Table: TableWithSchema :: String -> String -> (TableFields writerColumns viewColumns) -> Table writerColumns viewColumns
- Opaleye.Table: optional :: String -> TableColumns (Maybe (Column a)) (Column a)
+ Opaleye.Table: optional :: String -> TableFields (Maybe (Column a)) (Column a)
- Opaleye.Table: required :: String -> TableColumns (Column a) (Column a)
+ Opaleye.Table: required :: String -> TableFields (Column a) (Column a)
- Opaleye.Table: table :: String -> TableColumns writeFields viewFields -> Table writeFields viewFields
+ Opaleye.Table: table :: String -> TableFields writeFields viewFields -> Table writeFields viewFields
- Opaleye.Table: tableColumn :: TableColumn writeType sqlType => String -> TableColumns writeType (Column sqlType)
+ Opaleye.Table: tableColumn :: TableColumn writeType sqlType => String -> TableFields writeType (Column sqlType)
- Opaleye.Table: tableWithSchema :: String -> String -> TableColumns writeFields viewFields -> Table writeFields viewFields
+ Opaleye.Table: tableWithSchema :: String -> String -> TableFields writeFields viewFields -> Table writeFields viewFields

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+## 0.6.7003.0++* Add `tableField` as a future replacement for `tableColumn`++* Export `Opaleye.Field` and `Opaleye.RunSelect` from `Opaleye`++* Use new nomenclature in tutorials+ ## 0.6.7002.0  This is a breaking release that doesn't follow the PVP but because
Doc/Tutorial/TutorialBasic.lhs view
@@ -8,12 +8,12 @@ > > import           Prelude hiding (sum) >-> import           Opaleye (Column, Nullable, matchNullable, isNull,->                          Table, table, tableColumn, queryTable,->                          Query, QueryArr, restrict, (.==), (.<=), (.&&), (.<),+> import           Opaleye (Field, FieldNullable, matchNullable, isNull,+>                          Table, table, tableField, selectTable,+>                          Select, SelectArr, restrict, (.==), (.<=), (.&&), (.<), >                          (.===), >                          (.++), ifThenElse, sqlString, aggregate, groupBy,->                          count, avg, sum, leftJoin, runQuery,+>                          count, avg, sum, leftJoin, runSelect, >                          showSqlForPostgres, Unpackspec, >                          SqlInt4, SqlInt8, SqlText, SqlDate, SqlFloat8, SqlBool) >@@ -59,17 +59,17 @@ `Table` types will have the same type argument repeated twice.  In the manipulation tutorial you can see an example of when they might differ. -> personTable :: Table (Column SqlText, Column SqlInt4, Column SqlText)->                      (Column SqlText, Column SqlInt4, Column SqlText)-> personTable = table "personTable" (p3 ( tableColumn "name"->                                       , tableColumn "age"->                                       , tableColumn "address" ))+> personTable :: Table (Field SqlText, Field SqlInt4, Field SqlText)+>                      (Field SqlText, Field SqlInt4, Field SqlText)+> personTable = table "personTable" (p3 ( tableField "name"+>                                       , tableField "age"+>                                       , tableField "address" ))  By default, the table `"personTable"` is looked up in PostgreSQL's default `"public"` schema. If we wanted to specify a different schema we could have used the `tableWithSchema` function instead of `table`. -To query a table we use `queryTable`.+To query a table we use `selectTable`.  (Here and in a few other places in Opaleye there is some typeclass magic going on behind the scenes to reduce boilerplate.  However, you@@ -79,13 +79,13 @@ because they are simpler to read and the typeclass magic is essentially invisible.) -> personQuery :: Query (Column SqlText, Column SqlInt4, Column SqlText)-> personQuery = queryTable personTable+> personSelect :: Select (Field SqlText, Field SqlInt4, Field SqlText)+> personSelect = selectTable personTable -A `Query` corresponds to an SQL SELECT that we can run.  Here is the-SQL generated for `personQuery`.+A `Select` corresponds to an SQL SELECT that we can run.  Here is the+SQL generated for `personSelect`. -ghci> printSql personQuery+ghci> printSql personSelect SELECT name0_1 as result1,        age1_1 as result2,        address2_1 as result3@@ -126,7 +126,7 @@  > data Birthday' a b = Birthday { bdName :: a, bdDay :: b } > type Birthday = Birthday' String Day-> type BirthdayColumn = Birthday' (Column SqlText) (Column SqlDate)+> type BirthdayField = Birthday' (Field SqlText) (Field SqlDate)  To get user defined types to work with the typeclass magic they must have instances defined for them.  The instances are derivable with@@ -141,15 +141,15 @@ Then we can use 'table' to make a table on our record type in exactly the same way as before. -> birthdayTable :: Table BirthdayColumn BirthdayColumn+> birthdayTable :: Table BirthdayField BirthdayField > birthdayTable = table "birthdayTable"->                        (pBirthday Birthday { bdName = tableColumn "name"->                                            , bdDay  = tableColumn "birthday" })+>                        (pBirthday Birthday { bdName = tableField "name"+>                                            , bdDay  = tableField "birthday" }) >-> birthdayQuery :: Query BirthdayColumn-> birthdayQuery = queryTable birthdayTable+> birthdaySelect :: Select BirthdayField+> birthdaySelect = selectTable birthdayTable -ghci> printSql birthdayQuery+ghci> printSql birthdaySelect SELECT name0_1 as result1,        birthday1_1 as result2 FROM (SELECT *@@ -169,7 +169,7 @@  "Projection" means discarding some of the columns of our query, for example we might want to discard the "address" column of our-`personQuery`.+`personSelect`.  Projection gives us our first example of using "arrow notation" to write Opaleye queries.  Arrow notation is essentially a restricted@@ -177,13 +177,13 @@ computations, and do notation allows you to write monadic computations. -Here we run the `personQuery` passing in () to signify "zero+Here we run the `personSelect` passing in () to signify "zero arguments".  We pattern match on the results and return only the columns we are interested in. -> nameAge :: Query (Column SqlText, Column SqlInt4)+> nameAge :: Select (Field SqlText, Field SqlInt4) > nameAge = proc () -> do->   (name, age, _) <- personQuery -< ()+>   (name, age, _) <- personSelect -< () >   returnA -< (name, age)  ghci> printSql nameAge@@ -205,14 +205,14 @@ =======  "Product" means taking the Cartesian product of two queries.  This is-simple in arrow notation.  Here we take the product of `personQuery`-and `birthdayQuery`.+simple in arrow notation.  Here we take the product of `personSelect`+and `birthdaySelect`.  > personBirthdayProduct ::->   Query ((Column SqlText, Column SqlInt4, Column SqlText), BirthdayColumn)+>   Select ((Field SqlText, Field SqlInt4, Field SqlText), BirthdayField) > personBirthdayProduct = proc () -> do->   personRow   <- personQuery -< ()->   birthdayRow <- birthdayQuery -< ()+>   personRow   <- personSelect -< ()+>   birthdayRow <- birthdaySelect -< () > >   returnA -< (personRow, birthdayRow) @@ -253,12 +253,12 @@ "Restriction" means restricting the rows of the result of a query to only those where some condition holds. -We can restrict `personQuery` to the rows where the person is up to 18+We can restrict `personSelect` to the rows where the person is up to 18 years old. -> youngPeople :: Query (Column SqlText, Column SqlInt4, Column SqlText)+> youngPeople :: Select (Field SqlText, Field SqlInt4, Field SqlText) > youngPeople = proc () -> do->   row@(_, age, _) <- personQuery -< ()+>   row@(_, age, _) <- personSelect -< () >   restrict -< age .<= 18 > >   returnA -< row@@ -286,9 +286,9 @@ We can use a variety of operators to form more complex restriction conditions. -> twentiesAtAddress :: Query (Column SqlText, Column SqlInt4, Column SqlText)+> twentiesAtAddress :: Select (Field SqlText, Field SqlInt4, Field SqlText) > twentiesAtAddress = proc () -> do->   row@(_, age, address) <- personQuery -< ()+>   row@(_, age, address) <- personSelect -< () > >   restrict -< (20 .<= age) .&& (age .< 30) >   restrict -< address .== sqlString "1 My Street, My Town"@@ -327,10 +327,10 @@ such.  > personAndBirthday ::->   Query (Column SqlText, Column SqlInt4, Column SqlText, Column SqlDate)+>   Select (Field SqlText, Field SqlInt4, Field SqlText, Field SqlDate) > personAndBirthday = proc () -> do->   (name, age, address) <- personQuery -< ()->   birthday             <- birthdayQuery -< ()+>   (name, age, address) <- personSelect -< ()+>   birthday             <- birthdaySelect -< () > >   restrict -< name .== bdName birthday >@@ -380,17 +380,17 @@ of each employee and the name of their boss.  If their boss is recorded as NULL then that means they have no boss! -> employeeTable :: Table (Column SqlText, Column (Nullable SqlText))->                        (Column SqlText, Column (Nullable SqlText))-> employeeTable = table "employeeTable" (p2 ( tableColumn "name"->                                           , tableColumn "boss" ))+> employeeTable :: Table (Field SqlText, FieldNullable SqlText)+>                        (Field SqlText, FieldNullable SqlText)+> employeeTable = table "employeeTable" (p2 ( tableField "name"+>                                           , tableField "boss" ))  We can write a query that returns as string indicating for each employee whether they have a boss. -> hasBoss :: Query (Column SqlText)+> hasBoss :: Select (Field SqlText) > hasBoss = proc () -> do->   (name, nullableBoss) <- queryTable employeeTable -< ()+>   (name, nullableBoss) <- selectTable employeeTable -< () > >   let aOrNo = ifThenElse (isNull nullableBoss) (sqlString "no") (sqlString "a") >@@ -419,8 +419,8 @@ returns its first argument.  If not it passes the non-NULL value to the function that is the second argument. -> bossQuery :: QueryArr (Column SqlText, Column (Nullable SqlText)) (Column SqlText)-> bossQuery = proc (name, nullableBoss) -> do+> bossSelect :: SelectArr (Field SqlText, FieldNullable SqlText) (Field SqlText)+> bossSelect = proc (name, nullableBoss) -> do >   returnA -< matchNullable (name .++ sqlString " has no boss") >                            (\boss -> sqlString "The boss of " .++ name >                                      .++ sqlString " is " .++ boss)@@ -440,7 +440,7 @@  Then we get the following SQL. -ghci> printSql (bossQuery <<< queryTable employeeTable)+ghci> printSql (bossSelect <<< selectTable employeeTable)  SELECT CASE WHEN boss1_1 IS NULL THEN (name0_1) || ' has no boss'      ELSE (('The boss of ' || (name0_1)) || ' is ') || (boss1_1) END as result1@@ -469,28 +469,28 @@ twenties" and the restriction to the one's address being "1 My Street, My Town". -The types are of the form `QueryArr a ()`.  This means that they read-columns of type `a` but do not return any columns.  (Note: `Query` is-just a synonym for `QueryArr ()` which means that it is a `QueryArr`+The types are of the form `SelectArr a ()`.  This means that they read+columns of type `a` but do not return any columns.  (Note: `Select` is+just a synonym for `SelectArr ()` which means that it is a `SelectArr` that does not read any columns.) -> restrictIsTwenties :: QueryArr (Column SqlInt4) ()+> restrictIsTwenties :: SelectArr (Field SqlInt4) () > restrictIsTwenties = proc age -> do >   restrict -< (20 .<= age) .&& (age .< 30) >-> restrictAddressIs1MyStreet :: QueryArr (Column SqlText) ()+> restrictAddressIs1MyStreet :: SelectArr (Field SqlText) () > restrictAddressIs1MyStreet = proc address -> do >   restrict -< address .== sqlString "1 My Street, My Town"  We can't generate "the SQL of" these combinators.  They are not-`Query`s so they don't have any SQL!  (This corresponds to the+`Select`s so they don't have any SQL!  (This corresponds to the observation that in Haskell typically values can be "shown", but functions cannot be "shown".) Instead we use them to reimplement `twentiesAtAddress` in a more neatly-factored way. -> twentiesAtAddress' :: Query (Column SqlText, Column SqlInt4, Column SqlText)+> twentiesAtAddress' :: Select (Field SqlText, Field SqlInt4, Field SqlText) > twentiesAtAddress' = proc () -> do->   row@(_, age, address) <- personQuery -< ()+>   row@(_, age, address) <- personSelect -< () > >   restrictIsTwenties -< age >   restrictAddressIs1MyStreet -< address@@ -516,12 +516,12 @@ ----------------------  We can perform a similar transformation for `personAndBirthday` by-pulling out a `QueryArr` which perform the mapping of a person's name-to their date of birth by looking up in `birthdayQuery`.+pulling out a `SelectArr` which perform the mapping of a person's name+to their date of birth by looking up in `birthdaySelect`. -> birthdayOfPerson :: QueryArr (Column SqlText) (Column SqlDate)+> birthdayOfPerson :: SelectArr (Field SqlText) (Field SqlDate) > birthdayOfPerson = proc name -> do->   birthday <- birthdayQuery -< ()+>   birthday <- birthdaySelect -< () > >   restrict -< name .== bdName birthday >@@ -530,9 +530,9 @@ We can then reimplement `personAndBirthday` as follows  > personAndBirthday' ::->   Query (Column SqlText, Column SqlInt4, Column SqlText, Column SqlDate)+>   Select (Field SqlText, Field SqlInt4, Field SqlText, Field SqlDate) > personAndBirthday' = proc () -> do->   (name, age, address) <- personQuery -< ()+>   (name, age, address) <- personSelect -< () >   birthday <- birthdayOfPerson -< name > >   returnA -< (name, age, address, birthday)@@ -580,16 +580,16 @@ For the purposes of this example the style, color and location will be strings, but in practice they might have been a different data type. -> widgetTable :: Table (Widget (Column SqlText) (Column SqlText) (Column SqlText)->                              (Column SqlInt4) (Column SqlFloat8))->                      (Widget (Column SqlText) (Column SqlText) (Column SqlText)->                              (Column SqlInt4) (Column SqlFloat8))+> widgetTable :: Table (Widget (Field SqlText) (Field SqlText) (Field SqlText)+>                              (Field SqlInt4) (Field SqlFloat8))+>                      (Widget (Field SqlText) (Field SqlText) (Field SqlText)+>                              (Field SqlInt4) (Field SqlFloat8)) > widgetTable = table "widgetTable"->                      (pWidget Widget { style    = tableColumn "style"->                                      , color    = tableColumn "color"->                                      , location = tableColumn "location"->                                      , quantity = tableColumn "quantity"->                                      , radius   = tableColumn "radius" })+>                      (pWidget Widget { style    = tableField "style"+>                                      , color    = tableField "color"+>                                      , location = tableField "location"+>                                      , quantity = tableField "quantity"+>                                      , radius   = tableField "radius" })   Say we want to group by the style and color of widgets, calculating@@ -597,14 +597,14 @@ of such widgets and their average radius.  `aggregateWidgets` shows us how to do this. -> aggregateWidgets :: Query (Widget (Column SqlText) (Column SqlText) (Column SqlInt8)->                                   (Column SqlInt4) (Column SqlFloat8))+> aggregateWidgets :: Select (Widget (Field SqlText) (Field SqlText) (Field SqlInt8)+>                                   (Field SqlInt4) (Field SqlFloat8)) > aggregateWidgets = aggregate (pWidget Widget { style    = groupBy >                                              , color    = groupBy >                                              , location = count >                                              , quantity = sum >                                              , radius   = avg })->                              (queryTable widgetTable)+>                              (selectTable widgetTable)  The generated SQL is @@ -644,8 +644,8 @@ uses of our Template Haskell derived code.  We use the 'pWidget' "adaptor" to specify how columns are aggregated.  Note that this is yet another example of avoiding a headache by keeping your datatype-fully polymorphic, because the 'count' aggregator changes a 'Column-String' into a 'Column Int64'.+fully polymorphic, because the 'count' aggregator changes a 'Field+String' into a 'Field Int64'.  Outer join ==========@@ -659,15 +659,15 @@ nullability.  We introduce the following type synonym for this purpose, which is just a notational convenience. -> type ColumnNullableBirthday = Birthday' (Column (Nullable SqlText))->                                         (Column (Nullable SqlDate))+> type FieldNullableBirthday = Birthday' (FieldNullable SqlText)+>                                         (FieldNullable SqlDate)  A left join is expressed by specifying the two tables to join and the join condition. -> personBirthdayLeftJoin :: Query ((Column SqlText, Column SqlInt4, Column SqlText),->                                  ColumnNullableBirthday)-> personBirthdayLeftJoin = leftJoin personQuery birthdayQuery eqName+> personBirthdayLeftJoin :: Select ((Field SqlText, Field SqlInt4, Field SqlText),+>                                  FieldNullableBirthday)+> personBirthdayLeftJoin = leftJoin personSelect birthdaySelect eqName >     where eqName ((name, _, _), birthdayRow) = name .== bdName birthdayRow  The generated SQL is@@ -747,21 +747,21 @@  We could represent the integer ID in Opaleye as a `SqlInt4` -> type BadWarehouseColumn = Warehouse' (Column SqlInt4)->                                      (Column SqlText)->                                      (Column SqlInt4)+> type BadWarehouseField = Warehouse' (Field SqlInt4)+>                                      (Field SqlText)+>                                      (Field SqlInt4) >-> badWarehouseTable :: Table BadWarehouseColumn BadWarehouseColumn+> badWarehouseTable :: Table BadWarehouseField BadWarehouseField > badWarehouseTable = table "warehouse_table"->         (pWarehouse Warehouse { wId       = tableColumn "id"->                               , wLocation = tableColumn "location"->                               , wNumGoods = tableColumn "num_goods" })+>         (pWarehouse Warehouse { wId       = tableField "id"+>                               , wLocation = tableField "location"+>                               , wNumGoods = tableField "num_goods" })  but that would expose us to the following sorts of errors, where we can meaninglessly relate the warehouse ID with the quantity of goods it holds. -> badComparison :: BadWarehouseColumn -> Column SqlBool+> badComparison :: BadWarehouseField -> Field SqlBool > badComparison w = wId w .== wNumGoods w  On the other hand we can make a newtype for the warehouse ID@@ -769,30 +769,30 @@ > newtype WarehouseId' a = WarehouseId a > $(makeAdaptorAndInstance "pWarehouseId" ''WarehouseId') >-> type WarehouseIdColumn = WarehouseId' (Column SqlInt4)+> type WarehouseIdField = WarehouseId' (Field SqlInt4) >-> type GoodWarehouseColumn = Warehouse' WarehouseIdColumn->                                       (Column SqlText)->                                       (Column SqlInt4)+> type GoodWarehouseField = Warehouse' WarehouseIdField+>                                       (Field SqlText)+>                                       (Field SqlInt4) >-> goodWarehouseTable :: Table GoodWarehouseColumn GoodWarehouseColumn+> goodWarehouseTable :: Table GoodWarehouseField GoodWarehouseField > goodWarehouseTable = table "warehouse_table"->         (pWarehouse Warehouse { wId       = pWarehouseId (WarehouseId (tableColumn "id"))->                               , wLocation = tableColumn "location"->                               , wNumGoods = tableColumn "num_goods" })+>         (pWarehouse Warehouse { wId       = pWarehouseId (WarehouseId (tableField "id"))+>                               , wLocation = tableField "location"+>                               , wNumGoods = tableField "num_goods" })  Now the comparison will not pass the type checker -> -- forbiddenComparison :: GoodWarehouseColumn -> Column SqlBool+> -- forbiddenComparison :: GoodWarehouseField -> Field SqlBool > -- forbiddenComparison w = wId w .== wNumGoods w > ---> -- => Couldn't match type `WarehouseId' (Column SqlInt4)' with `Column SqlInt4'+> -- => Couldn't match type `WarehouseId' (Field SqlInt4)' with `Field SqlInt4' -but we can compare two `WarehouseIdColumn`s.+but we can compare two `WarehouseIdField`s. -> permittedComparison :: GoodWarehouseColumn->                     -> GoodWarehouseColumn->                     -> Column SqlBool+> permittedComparison :: GoodWarehouseField+>                     -> GoodWarehouseField+>                     -> Field SqlBool > permittedComparison w1 w2 = wId w1 .=== wId w2  (Currently we use `.===`, a more polymorphic version of `.==`, but@@ -803,47 +803,47 @@   Opaleye provides simple facilities for running queries on Postgres.-`runQuery` is a typeclass polymorphic function that effectively has+`runSelect` is a typeclass polymorphic function that effectively has the following type -> -- runQuery :: Database.PostgreSQL.Simple.Connection-> --          -> Query columns -> IO [haskells]+> -- runSelect :: Database.PostgreSQL.Simple.Connection+> --          -> Select columns -> IO [haskells]  It converts a "record" of Opaleye columns to a list of "records" of Haskell values.  Like `leftJoin` this particular formulation uses typeclasses so please put type signatures on everything in sight to minimize the number of confusing error messages! -For example, for the 'twentiesAtAddress' query `runQuery` would have+For example, for the 'twentiesAtAddress' query `runSelect` would have the following type: -> runTwentiesQuery :: PGS.Connection->                  -> Query (Column SqlText, Column SqlInt4, Column SqlText)+> runTwentiesSelect :: PGS.Connection+>                  -> Select (Field SqlText, Field SqlInt4, Field SqlText) >                  -> IO [(String, Int, String)]-> runTwentiesQuery = runQuery+> runTwentiesSelect = runSelect  Note that nullable columns are indicated with the Nullable type constructor, and these are converted to Maybe when executed.  If we have a table with a nullable column then Nullable columns turn into-Maybes.  We could run the query `queryTable employeeTable` like this.+Maybes.  We could run the query `selectTable employeeTable` like this. -> runEmployeesQuery :: PGS.Connection->                   -> Query (Column SqlText, Column (Nullable SqlText))+> runEmployeesSelect :: PGS.Connection+>                   -> Select (Field SqlText, FieldNullable SqlText) >                   -> IO [(String, Maybe String)]-> runEmployeesQuery = runQuery+> runEmployeesSelect = runSelect  Newtypes are taken care of automatically by the typeclass instance that was generated by `makeAdaptorAndInstance`.  A `WarehouseId'-(Column SqlInt4)` becomes a `WarehouseId' Int` when the query is run.-We could run the query `queryTable goodWarehouseTable` like this.+(Field SqlInt4)` becomes a `WarehouseId' Int` when the query is run.+We could run the query `selectTable goodWarehouseTable` like this.  > type WarehouseId = WarehouseId' Int > type GoodWarehouse = Warehouse' WarehouseId String Int >-> runWarehouseQuery :: PGS.Connection->                   -> Query GoodWarehouseColumn+> runWarehouseSelect :: PGS.Connection+>                   -> Select GoodWarehouseField >                   -> IO [GoodWarehouse]-> runWarehouseQuery = runQuery+> runWarehouseSelect = runSelect   Conclusion@@ -856,5 +856,5 @@  This is a little utility function to help with printing generated SQL. -> printSql :: Default Unpackspec a a => Query a -> IO ()+> printSql :: Default Unpackspec a a => Select a -> IO () > printSql = putStrLn . maybe "Empty query" id . showSqlForPostgres
Doc/Tutorial/TutorialBasicMonomorphic.lhs view
@@ -6,12 +6,12 @@ > > import           Prelude hiding (sum) >-> import           Opaleye (Column, Nullable,->                          Table, table, queryTable,->                          tableColumn,->                          Query, (.==),+> import           Opaleye (Field, FieldNullable,+>                          Table, table, selectTable,+>                          tableField,+>                          Select, (.==), >                          aggregate, groupBy,->                          count, avg, sum, leftJoin, runQuery,+>                          count, avg, sum, leftJoin, runSelect, >                          showSqlForPostgres, Unpackspec, >                          SqlInt4, SqlInt8, SqlText, SqlDate, SqlFloat8) >@@ -61,23 +61,23 @@ `Table` types will have the same type argument repeated twice.  In the manipulation tutorial you can see an example of when they might differ. -> personTable :: Table (Column SqlText, Column SqlInt4, Column SqlText)->                      (Column SqlText, Column SqlInt4, Column SqlText)-> personTable = table "personTable" (p3 ( tableColumn "name"->                                       , tableColumn "age"->                                       , tableColumn "address" ))+> personTable :: Table (Field SqlText, Field SqlInt4, Field SqlText)+>                      (Field SqlText, Field SqlInt4, Field SqlText)+> personTable = table "personTable" (p3 ( tableField "name"+>                                       , tableField "age"+>                                       , tableField "address" )) -> personTable' :: Table (Column SqlText, Column SqlInt4, Column SqlText)->                       (Column SqlText, Column SqlInt4, Column SqlText)-> personTable' = table "personTable" (p3 ( tableColumn "name"->                                        , tableColumn "age"->                                        , tableColumn "address" ))+> personTable' :: Table (Field SqlText, Field SqlInt4, Field SqlText)+>                       (Field SqlText, Field SqlInt4, Field SqlText)+> personTable' = table "personTable" (p3 ( tableField "name"+>                                        , tableField "age"+>                                        , tableField "address" ))  By default, the table `"personTable"` is looked up in PostgreSQL's default `"public"` schema. If we wanted to specify a different schema we could have used the `tableWithSchema` constructor instead of `table`. -To query a table we use `queryTable`.+To query a table we use `selectTable`.  (Here and in a few other places in Opaleye there is some typeclass magic going on behind the scenes to reduce boilerplate.  However, you@@ -87,13 +87,13 @@ because they are simpler to read and the typeclass magic is essentially invisible.) -> personQuery :: Query (Column SqlText, Column SqlInt4, Column SqlText)-> personQuery = queryTable personTable+> personSelect :: Select (Field SqlText, Field SqlInt4, Field SqlText)+> personSelect = selectTable personTable -A `Query` corresponds to an SQL SELECT that we can run.  Here is the-SQL generated for `personQuery`.+A `Select` corresponds to an SQL SELECT that we can run.  Here is the+SQL generated for `personSelect`. -ghci> printSql personQuery+ghci> printSql personSelect SELECT name0_1 as result1,        age1_1 as result2,        address2_1 as result3@@ -132,22 +132,22 @@ mean that you have to define more datatypes and more instances for them. -> data BirthdayColumn = BirthdayColumn { bdNameColumn :: Column SqlText->                                      , bdDayColumn  :: Column SqlDate }+> data BirthdayField = BirthdayField { bdNameField :: Field SqlText+>                                      , bdDayField  :: Field SqlDate } > > data Birthday = Birthday { bdName :: String, bdDay :: Day } >-> birthdayColumnDef ::->   (Applicative (p BirthdayColumn),+> birthdayFieldDef ::+>   (Applicative (p BirthdayField), >    P.Profunctor p,->    Default p (Column SqlText) (Column SqlText),->    Default p (Column SqlDate) (Column SqlDate)) =>->   p BirthdayColumn BirthdayColumn-> birthdayColumnDef = BirthdayColumn <$> P.lmap bdNameColumn D.def->                                    <*> P.lmap bdDayColumn  D.def+>    Default p (Field SqlText) (Field SqlText),+>    Default p (Field SqlDate) (Field SqlDate)) =>+>   p BirthdayField BirthdayField+> birthdayFieldDef = BirthdayField <$> P.lmap bdNameField D.def+>                                    <*> P.lmap bdDayField  D.def >-> instance Default Unpackspec BirthdayColumn BirthdayColumn where->   def = birthdayColumnDef+> instance Default Unpackspec BirthdayField BirthdayField where+>   def = birthdayFieldDef  Naturally this is all derivable using `Generic` or Template Haskell, but no one's bothered to implement that yet.  Would you like to?@@ -155,16 +155,16 @@ Then we can use 'table' to make a table on our record type in exactly the same way as before. -> birthdayTable :: Table BirthdayColumn BirthdayColumn+> birthdayTable :: Table BirthdayField BirthdayField > birthdayTable = >   table "birthdayTable"->   (BirthdayColumn <$> P.lmap bdNameColumn (tableColumn "name")->                   <*> P.lmap bdDayColumn  (tableColumn "birthday"))+>   (BirthdayField <$> P.lmap bdNameField (tableField "name")+>                   <*> P.lmap bdDayField  (tableField "birthday")) >-> birthdayQuery :: Query BirthdayColumn-> birthdayQuery = queryTable birthdayTable+> birthdaySelect :: Select BirthdayField+> birthdaySelect = selectTable birthdayTable -ghci> printSql birthdayQuery+ghci> printSql birthdaySelect SELECT name0_1 as result1,        birthday1_1 as result2 FROM (SELECT *@@ -192,15 +192,15 @@ style, color, location, quantity and radius of widgets.  We can model this information with the following datatype. -> data WidgetColumn = WidgetColumn { style    :: Column SqlText->                                  , color    :: Column SqlText->                                  , location :: Column SqlText->                                  , quantity :: Column SqlInt4->                                  , radius   :: Column SqlFloat8+> data WidgetField = WidgetField { style    :: Field SqlText+>                                  , color    :: Field SqlText+>                                  , location :: Field SqlText+>                                  , quantity :: Field SqlInt4+>                                  , radius   :: Field SqlFloat8 >                                  } >-> instance Default Unpackspec WidgetColumn WidgetColumn where->   def = WidgetColumn <$> P.lmap style    D.def+> instance Default Unpackspec WidgetField WidgetField where+>   def = WidgetField <$> P.lmap style    D.def >                      <*> P.lmap color    D.def >                      <*> P.lmap location D.def >                      <*> P.lmap quantity D.def@@ -209,13 +209,13 @@ For the purposes of this example the style, color and location will be strings, but in practice they might have been a different data type. -> widgetTable :: Table WidgetColumn WidgetColumn+> widgetTable :: Table WidgetField WidgetField > widgetTable = table "widgetTable"->                      (WidgetColumn <$> P.lmap style    (tableColumn "style")->                                    <*> P.lmap color    (tableColumn "color")->                                    <*> P.lmap location (tableColumn "location")->                                    <*> P.lmap quantity (tableColumn "quantity")->                                    <*> P.lmap radius   (tableColumn "radius"))+>                      (WidgetField <$> P.lmap style    (tableField "style")+>                                    <*> P.lmap color    (tableField "color")+>                                    <*> P.lmap location (tableField "location")+>                                    <*> P.lmap quantity (tableField "quantity")+>                                    <*> P.lmap radius   (tableField "radius"))   Say we want to group by the style and color of widgets, calculating@@ -223,14 +223,14 @@ of such widgets and their average radius.  `aggregateWidgets` shows us how to do this. -> aggregateWidgets :: Query (Column SqlText, Column SqlText, Column SqlInt8,->                            Column SqlInt4, Column SqlFloat8)+> aggregateWidgets :: Select (Field SqlText, Field SqlText, Field SqlInt8,+>                            Field SqlInt4, Field SqlFloat8) > aggregateWidgets = aggregate ((,,,,) <$> P.lmap style    groupBy >                                      <*> P.lmap color    groupBy >                                      <*> P.lmap location count >                                      <*> P.lmap quantity sum >                                      <*> P.lmap radius   avg)->                              (queryTable widgetTable)+>                              (selectTable widgetTable)  The generated SQL is @@ -270,8 +270,8 @@ uses of our Template Haskell derived code.  We use the 'pWidget' "adaptor" to specify how columns are aggregated.  Note that this is yet another example of avoiding a headache by keeping your datatype-fully polymorphic, because the 'count' aggregator changes a 'Column-String' into a 'Column Int64'.+fully polymorphic, because the 'count' aggregator changes a 'Field+String' into a 'Field Int64'.  Outer join ==========@@ -285,17 +285,17 @@ nullability.  We introduce the following type synonym for this purpose, which is just a notational convenience. -> data BirthdayColumnNullable =->   BirthdayColumnNullable { bdNameColumnNullable :: Column (Nullable SqlText)->                          , bdDayColumnNullable  :: Column (Nullable SqlDate) }+> data BirthdayFieldNullable =+>   BirthdayFieldNullable { bdNameFieldNullable :: FieldNullable SqlText+>                          , bdDayFieldNullable  :: FieldNullable SqlDate } >-> instance Default O.Unpackspec BirthdayColumnNullable BirthdayColumnNullable where->   def = BirthdayColumnNullable <$> P.lmap bdNameColumnNullable D.def->                                <*> P.lmap bdDayColumnNullable  D.def+> instance Default O.Unpackspec BirthdayFieldNullable BirthdayFieldNullable where+>   def = BirthdayFieldNullable <$> P.lmap bdNameFieldNullable D.def+>                                <*> P.lmap bdDayFieldNullable  D.def >-> instance Default Opaleye.Internal.Join.NullMaker BirthdayColumn BirthdayColumnNullable where->   def = BirthdayColumnNullable <$> P.lmap bdNameColumn D.def->                                <*> P.lmap bdDayColumn  D.def+> instance Default Opaleye.Internal.Join.NullMaker BirthdayField BirthdayFieldNullable where+>   def = BirthdayFieldNullable <$> P.lmap bdNameField D.def+>                                <*> P.lmap bdDayField  D.def  Again, this is all derivable using `Generic` or Template Haskell, if someone would take the time to implement it.@@ -303,11 +303,11 @@ A left join is expressed by specifying the two tables to join and the join condition. -> personBirthdayLeftJoin :: Query ((Column SqlText, Column SqlInt4, Column SqlText),->                                  BirthdayColumnNullable)-> personBirthdayLeftJoin = leftJoin personQuery birthdayQuery eqName+> personBirthdayLeftJoin :: Select ((Field SqlText, Field SqlInt4, Field SqlText),+>                                  BirthdayFieldNullable)+> personBirthdayLeftJoin = leftJoin personSelect birthdaySelect eqName >     where eqName ((name, _, _), birthdayRow) =->             name .== bdNameColumn birthdayRow+>             name .== bdNameField birthdayRow  The generated SQL is @@ -371,25 +371,25 @@   Opaleye provides simple facilities for running queries on Postgres.-`runQuery` is a typeclass polymorphic function that effectively has+`runSelect` is a typeclass polymorphic function that effectively has the following type -> -- runQuery :: Database.PostgreSQL.Simple.Connection-> --          -> Query columns -> IO [haskells]+> -- runSelect :: Database.PostgreSQL.Simple.Connection+> --          -> Select fields -> IO [haskells]  It converts a "record" of Opaleye columns to a list of "records" of Haskell values.  Like `leftJoin` this particular formulation uses typeclasses so please put type signatures on everything in sight to minimize the number of confusing error messages! -> instance Default O.QueryRunner BirthdayColumn Birthday where->   def = Birthday <$> P.lmap bdNameColumn D.def->                  <*> P.lmap bdDayColumn  D.def+> instance Default O.FromFields BirthdayField Birthday where+>   def = Birthday <$> P.lmap bdNameField D.def+>                  <*> P.lmap bdDayField  D.def >-> runBirthdayQuery :: PGS.Connection->                  -> Query BirthdayColumn+> runBirthdaySelect :: PGS.Connection+>                  -> Select BirthdayField >                  -> IO [Birthday]-> runBirthdayQuery = runQuery+> runBirthdaySelect = runSelect  Again, this is derivable using `Generic` or Template Haskell, if someone would take the time to implement it.@@ -404,5 +404,5 @@  This is a little utility function to help with printing generated SQL. -> printSql :: Default Unpackspec a a => Query a -> IO ()+> printSql :: Default Unpackspec a a => Select a -> IO () > printSql = putStrLn . maybe "Empty query" id . showSqlForPostgres
Doc/Tutorial/TutorialBasicTypeFamilies.lhs view
@@ -14,10 +14,10 @@ > > import           Prelude hiding (sum) >-> import           Opaleye (Column,->                          Table, table, tableColumn, queryTable,->                          Query, (.==), aggregate, groupBy,->                          count, avg, sum, leftJoin, runQuery,+> import           Opaleye (Field,+>                          Table, table, tableField, selectTable,+>                          Select, (.==), aggregate, groupBy,+>                          count, avg, sum, leftJoin, runSelect, runSelectTF, >                          showSqlForPostgres, Unpackspec, >                          SqlInt4, SqlInt8, SqlText, SqlDate, SqlFloat8) >@@ -67,17 +67,17 @@ we can read from the table.  In this case all columns are required, so the write and read types will be the same. -> personTable :: Table (Column SqlText, Column SqlInt4, Column SqlText)->                      (Column SqlText, Column SqlInt4, Column SqlText)-> personTable = table "personTable" (p3 ( tableColumn "name"->                                       , tableColumn "age"->                                       , tableColumn "address" ))+> personTable :: Table (Field SqlText, Field SqlInt4, Field SqlText)+>                      (Field SqlText, Field SqlInt4, Field SqlText)+> personTable = table "personTable" (p3 ( tableField "name"+>                                       , tableField "age"+>                                       , tableField "address" ))  By default, the table `"personTable"` is looked up in PostgreSQL's default `"public"` schema. If we wanted to specify a different schema we could have used the `tableWithSchema` function instead of `table`. -To query a table we use `queryTable`.+To query a table we use `selectTable`.  (Here and in a few other places in Opaleye there is some typeclass magic going on behind the scenes to reduce boilerplate.  However, you@@ -87,15 +87,15 @@ because they are simpler to read and the typeclass magic is essentially invisible.) -> personQuery :: Query (Column SqlText, Column SqlInt4, Column SqlText)-> personQuery = queryTable personTable+> personSelect :: Select (Field SqlText, Field SqlInt4, Field SqlText)+> personSelect = selectTable personTable -A `Query` corresponds to an SQL SELECT that we can run.  Here is the-SQL generated for `personQuery`.  (`printSQL` is just a convenient+A `Select` corresponds to an SQL SELECT that we can run.  Here is the+SQL generated for `personSelect`.  (`printSQL` is just a convenient utility function for the purposes of this example file.  See below for its definition.) -    ghci> printSql personQuery+    ghci> printSql personSelect     SELECT name0_1 as result1,            age1_1 as result2,            address2_1 as result3@@ -131,10 +131,6 @@ using type families that reduces boiler plate and has always been compatible with Opaleye! -> -- Cryptic remark: If we were willing to only support 7.8 and up we-> -- could even have a symbol field containing the table name and use-> -- https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-TypeLits.html#v:symbolVal->  > data Birthday f = Birthday { bdName :: TableField f String SqlText NN Req >                            , bdDay  :: TableField f Day    SqlDate NN Req >                            }@@ -164,14 +160,14 @@  > birthdayTable :: Table (Birthday W) (Birthday O) > birthdayTable = table "birthdayTable" $ pBirthday $ Birthday {->     bdName = tableColumn "name"->   , bdDay  = tableColumn "birthday"+>     bdName = tableField "name"+>   , bdDay  = tableField "birthday" > } >-> birthdayQuery :: Query (Birthday O)-> birthdayQuery = queryTable birthdayTable+> birthdaySelect :: Select (Birthday O)+> birthdaySelect = selectTable birthdayTable -    ghci> printSql birthdayQuery+    ghci> printSql birthdaySelect     SELECT name0_1 as result1,            birthday1_1 as result2     FROM (SELECT *@@ -235,11 +231,11 @@  > widgetTable :: Table (Widget W) (Widget O) > widgetTable = table "widgetTable" $ pWidget $ Widget {->     style    = tableColumn "style"->   , color    = tableColumn "color"->   , location = tableColumn "location"->   , quantity = tableColumn "quantity"->   , radius   = tableColumn "radius"+>     style    = tableField "style"+>   , color    = tableField "color"+>   , location = tableField "location"+>   , quantity = tableField "quantity"+>   , radius   = tableField "radius" > }  Say we want to group by the style and color of widgets, calculating@@ -247,14 +243,14 @@ of such widgets and their average radius.  `aggregateWidgets` shows us how to do this. -> aggregateWidgets :: Query (Column SqlText, Column SqlText, Column SqlInt8,->                            Column SqlInt4, Column SqlFloat8)+> aggregateWidgets :: Select (Field SqlText, Field SqlText, Field SqlInt8,+>                            Field SqlInt4, Field SqlFloat8) > aggregateWidgets = aggregate ((,,,,) <$> P.lmap style    groupBy >                                      <*> P.lmap color    groupBy >                                      <*> P.lmap location count >                                      <*> P.lmap quantity sum >                                      <*> P.lmap radius   avg)->                              (queryTable widgetTable)+>                              (selectTable widgetTable)  The generated SQL is @@ -301,9 +297,9 @@ outer joins).  An outer join is expressed by specifying the two tables to join and the join condition. -> personBirthdayLeftJoin :: Query ((Column SqlText, Column SqlInt4, Column SqlText),+> personBirthdayLeftJoin :: Select ((Field SqlText, Field SqlInt4, Field SqlText), >                                  Birthday Nulls)-> personBirthdayLeftJoin = leftJoin personQuery birthdayQuery eqName+> personBirthdayLeftJoin = leftJoin personSelect birthdaySelect eqName >     where eqName ((name, _, _), birthdayRow) = name .== bdName birthdayRow  The generated SQL is@@ -356,10 +352,10 @@  > typeInferred = >     O.fullJoinInferrable (O.fullJoinInferrable->                     birthdayQuery->                     (queryTable widgetTable)+>                     birthdaySelect+>                     (selectTable widgetTable) >                     (const (O.pgBool True)))->                birthdayQuery+>                birthdaySelect >                (const (O.pgBool True))  Running queries on Postgres@@ -367,22 +363,28 @@   Opaleye provides simple facilities for running queries on Postgres.-`runQuery` is a typeclass polymorphic function that effectively has+`runSelect` is a typeclass polymorphic function that effectively has the following type -> -- runQuery :: Database.PostgreSQL.Simple.Connection-> --          -> Query columns -> IO [haskells]+> -- runSelect :: Database.PostgreSQL.Simple.Connection+> --          -> Select columns -> IO [haskells]  It converts a "record" of Opaleye columns to a list of "records" of Haskell values.  Like `leftJoin` this particular formulation uses typeclasses so please put type signatures on everything in sight to minimize the number of confusing error messages! -> runBirthdayQuery :: PGS.Connection->                  -> Query (Birthday O)+> runBirthdaySelect :: PGS.Connection+>                  -> Select (Birthday O) >                  -> IO [Birthday H]-> runBirthdayQuery = runQuery+> runBirthdaySelect = runSelect +The type of selects can be inferred if you use the `runSelectTF`+function.++> -- printNames :: PGS.Connection -> Select (Birthday O) -> IO ()+> printNames conn select = mapM_ (print . bdName) =<< runSelectTF conn select+ Conclusion ========== @@ -393,5 +395,5 @@  This is a little utility function to help with printing generated SQL. -> printSql :: Default Unpackspec a a => Query a -> IO ()+> printSql :: Default Unpackspec a a => Select a -> IO () > printSql = putStrLn . maybe "Empty query" id . showSqlForPostgres
opaleye.cabal view
@@ -1,6 +1,6 @@ name:            opaleye copyright:       Copyright (c) 2014-2018 Purely Agile Limited-version:         0.6.7002.0+version:         0.6.7003.0 synopsis:        An SQL-generating DSL targeting PostgreSQL description:     An SQL-generating DSL targeting PostgreSQL.  Allows                  Postgres queries to be written within Haskell in a@@ -99,7 +99,7 @@                    Opaleye.Internal.HaskellDB.Sql.Default,                    Opaleye.Internal.HaskellDB.Sql.Generate,                    Opaleye.Internal.HaskellDB.Sql.Print-  ghc-options:     -Wall+  ghc-options:     -Wall -Wcompat  test-suite test   default-language: Haskell2010
src/Opaleye.hs view
@@ -18,6 +18,7 @@                , module Opaleye.Column                , module Opaleye.Constant                , module Opaleye.Distinct+               , module Opaleye.Field                , module Opaleye.FunctionalJoin                , module Opaleye.Join                , module Opaleye.Label@@ -27,6 +28,7 @@                , module Opaleye.PGTypes                , module Opaleye.QueryArr                , module Opaleye.RunQuery+               , module Opaleye.RunSelect                , module Opaleye.Sql                , module Opaleye.Select                , module Opaleye.SqlTypes@@ -39,6 +41,13 @@ import Opaleye.Column import Opaleye.Constant import Opaleye.Distinct+import Opaleye.Field+  hiding (null,+          isNull,+          matchNullable,+          fromNullable,+          toNullable,+          maybeToNullable) import Opaleye.FunctionalJoin import Opaleye.Join import Opaleye.Label@@ -48,6 +57,11 @@ import Opaleye.PGTypes import Opaleye.QueryArr import Opaleye.RunQuery+import Opaleye.RunSelect+  hiding (foldForward,+          closeCursor,+          declareCursor,+          declareCursorExplicit) import Opaleye.Select import Opaleye.Sql import Opaleye.SqlTypes
src/Opaleye/Internal/Table.hs view
@@ -52,10 +52,10 @@ -- The constructors of Table are internal only and will be -- deprecated in version 0.7. data Table writerColumns viewColumns-  = Table String (TableColumns writerColumns viewColumns)+  = Table String (TableFields writerColumns viewColumns)     -- ^ For unqualified table names. Do not use the constructor.  It     -- is internal and will be deprecated in version 0.7.-  | TableWithSchema String String (TableColumns writerColumns viewColumns)+  | TableWithSchema String String (TableFields writerColumns viewColumns)     -- ^ Schema name, table name, table properties.  Do not use the     -- constructor.  It is internal and will be deprecated in version 0.7. @@ -63,29 +63,33 @@ tableIdentifier (Table t _) = PQ.TableIdentifier Nothing t tableIdentifier (TableWithSchema s t _) = PQ.TableIdentifier (Just s) t -tableColumns :: Table writeColumns viewColumns -> TableColumns writeColumns viewColumns+tableColumns :: Table writeColumns viewColumns -> TableFields writeColumns viewColumns tableColumns (Table _ p) = p tableColumns (TableWithSchema _ _ p) = p  -- | Use 'tableColumns' instead.  Will be deprecated soon.-tableProperties :: Table writeColumns viewColumns -> TableColumns writeColumns viewColumns+tableProperties :: Table writeColumns viewColumns -> TableFields writeColumns viewColumns tableProperties = tableColumns --- | Use 'TableColumns' instead. 'TableProperties' will be deprecated+-- | Use 'TableFields' instead. 'TableProperties' will be deprecated -- in version 0.7. data TableProperties writeColumns viewColumns = TableProperties    { tablePropertiesWriter :: Writer writeColumns viewColumns    , tablePropertiesView   :: View viewColumns } --- | The new name for 'TableColumns' which will replace--- 'TableColumn' in version 0.7.+-- | Use 'TableFields' instead. 'TableColumns' will be deprecated in+-- version 0.7. type TableColumns = TableProperties -tableColumnsWriter :: TableColumns writeColumns viewColumns+-- | The new name for 'TableColumns' and 'TableProperties' which will+-- replace them in version 0.7.+type TableFields = TableProperties++tableColumnsWriter :: TableFields writeColumns viewColumns                    -> Writer writeColumns viewColumns tableColumnsWriter = tablePropertiesWriter -tableColumnsView :: TableColumns writeColumns viewColumns+tableColumnsView :: TableFields writeColumns viewColumns                  -> View viewColumns tableColumnsView = tablePropertiesView @@ -111,14 +115,14 @@  -- | 'required' is for columns which are not 'optional'.  You must -- provide them on writes.-required :: String -> TableColumns (Column a) (Column a)+required :: String -> TableFields (Column a) (Column a) required columnName = TableProperties   (requiredW columnName)   (View (Column (HPQ.BaseTableAttrExpr columnName)))  -- | 'optional' is for columns that you can omit on writes, such as --  columns which have defaults or which are SERIAL.-optional :: String -> TableColumns (Maybe (Column a)) (Column a)+optional :: String -> TableFields (Maybe (Column a)) (Column a) optional columnName = TableProperties   (optionalW columnName)   (View (Column (HPQ.BaseTableAttrExpr columnName)))@@ -128,7 +132,7 @@     -- the write type.  It's generally more convenient to use this     -- than 'required' or 'optional' but you do have to provide a type     -- signature instead.-    tableColumn :: String -> TableColumns writeType (Column sqlType)+    tableColumn :: String -> TableFields writeType (Column sqlType)  instance TableColumn (Column a) a where     tableColumn = required@@ -136,6 +140,10 @@ instance TableColumn (Maybe (Column a)) a where     tableColumn = optional +tableField :: TableColumn writeType sqlType+           => String -> TableFields writeType (Column sqlType)+tableField = tableColumn+ queryTable :: U.Unpackspec viewColumns columns             -> Table writeColumns viewColumns             -> Tag.Tag@@ -177,15 +185,15 @@   where (outColumns, ()) = f extract columns         extract (pes, s) = ((Zip (fmap return pes), [s]), ()) -data Zip a = Zip { unZip :: NEL.NonEmpty [a] }+newtype Zip a = Zip { unZip :: NEL.NonEmpty [a] }  instance Semigroup (Zip a) where-  (<>) = mappend+  Zip xs <> Zip ys = Zip (NEL.zipWith (++) xs ys)  instance Monoid (Zip a) where   mempty = Zip mempty'     where mempty' = [] `NEL.cons` mempty'-  Zip xs `mappend` Zip ys = Zip (NEL.zipWith (++) xs ys)+  mappend = (<>)  requiredW :: String -> Writer (Column a) (Column a) requiredW columnName =
src/Opaleye/RunSelect.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-}  module Opaleye.RunSelect@@ -18,6 +19,7 @@ import qualified Opaleye.Select as S import qualified Opaleye.RunQuery          as RQ import qualified Opaleye.Sql as S+import qualified Opaleye.TypeFamilies as TF import           Opaleye.Internal.RunQuery (FromFields) import qualified Opaleye.Internal.RunQuery as IRQ import qualified Opaleye.Internal.QueryArr as Q@@ -51,6 +53,16 @@           -- ^           -> IO [haskells] runSelect = RQ.runQuery++-- | 'runSelectTF' has better type inference than 'runSelect' but only+-- works with "higher-kinded data" types.+runSelectTF :: D.Default FromFields (rec TF.O) (rec TF.H)+            => PGS.Connection+            -- ^+            -> S.Select (rec TF.O)+            -- ^+            -> IO [rec TF.H]+runSelectTF = RQ.runQuery  -- | @runSelectFold@ streams the results of a query incrementally and consumes -- the results with a left fold.
src/Opaleye/Table.hs view
@@ -12,7 +12,7 @@  'required' and gives rise to a   @- TableColumns (Column SqlInt4) (Column SqlInt4)+ TableFields (Column SqlInt4) (Column SqlInt4)  @   The leftmost argument is the type of writes. When you insert or@@ -23,7 +23,7 @@  to a   @- TableColumns (Column (Nullable SqlInt4)) (Column (Nullable SqlInt4))+ TableFields (Column (Nullable SqlInt4)) (Column (Nullable SqlInt4))  @   When you insert or update into this column you must give it a @Column@@ -35,7 +35,7 @@  rise to a   @- TableColumns (Maybe (Column SqlInt4)) (Column SqlInt4)+ TableFields (Maybe (Column SqlInt4)) (Column SqlInt4)  @   Optional columns are those that can be omitted on writes, such as@@ -49,7 +49,7 @@  rise to a   @- TableColumns (Maybe (Column (Nullable SqlInt4))) (Column (Nullable SqlInt4))+ TableFields (Maybe (Column (Nullable SqlInt4))) (Column (Nullable SqlInt4))  @   Optional columns are those that can be omitted on writes, such as@@ -66,12 +66,14 @@                       tableWithSchema,                       T.Table,                       T.tableColumn,+                      T.tableField,                       T.optional,                       T.required,                       -- * Querying tables                       selectTable,                       -- * Other-                      TableColumns,+                      T.TableColumns,+                      TableFields,                       -- * Deprecated                       View,                       Writer,@@ -82,7 +84,7 @@ import qualified Opaleye.Internal.QueryArr as Q import qualified Opaleye.Internal.Table as T import           Opaleye.Internal.Table (View, Table, Writer,-                                         TableColumns)+                                         TableFields)  import qualified Opaleye.Internal.Tag as Tag import qualified Opaleye.Internal.Unpackspec as U@@ -114,7 +116,7 @@ -- | Create a table with unqualified names. table :: String       -- ^ Table name-      -> TableColumns writeFields viewFields+      -> TableFields writeFields viewFields       -> Table writeFields viewFields table = T.Table @@ -123,7 +125,7 @@                 -- ^ Schema name                 -> String                 -- ^ Table name-                -> TableColumns writeFields viewFields+                -> TableFields writeFields viewFields                 -> Table writeFields viewFields tableWithSchema = T.TableWithSchema