Git Product home page Git Product logo

groundhog's People

Contributors

andrewthad avatar begriffs avatar bergmark avatar dougburke avatar dsvensson avatar fendor avatar gregwebs avatar hvr avatar imalsogreg avatar jkachmar avatar korayal avatar lykahb avatar maksar avatar markwright avatar mightybyte avatar natdash avatar wraithm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

groundhog's Issues

Empty Arrays raise an error with Postgres

I'm getting the following error when trying to insert an empty error:

user error (Postgresql.withStmt': bad result status FatalError ("PGRES_FATAL_ERROR"). Error message: ERROR:  cannot determine type of empty array

LINE 1: ...,1,1,1,900,1440,0,0,24,24,true,true,420,true,true,ARRAY[],3,...
                                                             ^
HINT:  Explicitly cast to the desired type, for example ARRAY[]::integer[].

insertByAll race condition?

I implemented some Haskell logic based on the docs of insertByAll saying if there was a constraint violation that it would return Left and then an arbitrary id matching the constraint. I assumed it was rescuing the db-specific error code for a constraint violation. Instead it looks like its selecting ids that match the constraint (no doubt necessary because the db vendor's error message won't have this info). I think the problem here is there is a race condition between the check and the insert:

  1. Thread 1 selects ids matching constraints, it gets none.
  2. Thread 2 selects ids matching constraints, it gets none.
  3. Thread 2 inserts and commits the transaction.
  4. Thread 1 tries to insert, but gets a unique constraint violation. The transaction rolls back and rather than returning a conflicting ID it throws a postgres (in my case) exception.

I'm not certain what the correct solution is here but this feels like it violates the spirit of the documentation. I'd expect not to ever receive a constraint exception fron this function.

In one option you could just insert blindly, rescue a uniqueness error (which means you can't fully get away with one RDBMS-agnostic insertByAll) and then issue your conflicting id query. Problem here is will abort the larger transaction and I'm not familiar enough with transaction semantics in groundhog to know if this is okay.

In another option, you create a subtransaction for the insert. You could still check, as the postgres IRC channel seems to believe the subtransaction is expensive enough that you'd want to optimally avoid it with the pre-insert check. You'd still have to catch the constraint violation.

There may be other solutions, such as this crazy upsert in postgresql.

Migrations happen in the wrong order when run in batches (Postgresql)

Consider this migration where "Category" holds a reference to "Source":

migrateDB :: (MonadIO m, PersistBackend m) => m ()
migrateDB =
    runMigrationUnsafe defaultMigrationLogger $ do
      migrate (undefined :: Source)
      migrate (undefined :: Brand)
      migrate (undefined :: Category)
      migrate (undefined :: Product)

During execution, the migration for 'Source' does not occur before the migration for 'Category', raising a postgresql error complaining about lack of a "source" relation. Based on one observation in this case, the migration orders seems to be alphabetical in this case.

The workaround for now is to run independent migrations, but it may be nice to have support for running them in the right order.

Unique check during insertByAll confuses ordering of constraint fields

Here is the situation. I have a datatype specified as:

data Category = Category {
      catName   :: Text
    , catParent :: Maybe (DefaultKey Category)
    , catSource :: DefaultKey Source
    }

with:

- entity: Category
  keys:
    - name: CatUniq
  constructors:
    - name: Category
      uniques:
        - name: CatUniq
          fields: [catSource, catParent, catName]
          type: constraint

Notice how the ordering of constraint fields are different from the record definition.

Over migrations, the database order is in: name, parent, source, which mirros the original record definition.

Now, when I run an insertByAll command, I see the following in SQL logs:

SELECT "id" FROM "category" WHERE "cat_source"='Category' AND "cat_parent"=null AND "cat_name"=0

which of course is an error. Over at Haskell runtime, I get:

*** Exception: user error (Postgresql.withStmt': bad result status FatalError ("PGRES_FATAL_ERROR"). Error message: ERROR:  invalid input syntax for integer: "Category"
LINE 1: SELECT "id" FROM "category" WHERE "cat_source"='Category' AN...

Reverting definition to:

          fields: [catName, catParent, catSource]

solves the issue.

Groundhog Query

I'm getting the following query error in a query generated by groundhog.

A web handler threw an exception. Details:
user error (Postgresql.withStmt': bad result status FatalError ("PGRES_FATAL_ERROR"). Error message: ERROR:  syntax error at or near "DESC"
LINE 1: ...FROM 1200 ORDER BY "ci_rev_number" DESC,"id" DESC DESC LIMIT...
                                                             ^
)

Here's the query.

project AutoKeyField $
                    (CiFooIdField ==. aid &&.
                     CiWidthField ==. w &&.
                     CiHeightField ==. h)
                    `orderBy` [Desc CiRevNumberField, Desc AutoKeyField] `limitTo` 1

If I remove the second sort item, then the query works.

Question about clustered primary keys

Suppose I have three tables A, B and C, and the clustered primary key for C includes a DefaultKey for B, and similarly the clustered primary key for B includes a DefaultKey for A. I know that joins are not possible in general, but I would like to find all Cs which correspond to a particular DefaultKey for A.

This is simple for two tables using select, but I can't find a way to do what I'd like with three tables.

Note that the DefaultKey for C contains all the fields for a DefaultKey for A, so this should be a simple SELECT ... WHERE involving only columns from C, but I don't know how to write the correct selector. I want something like:

select $ C_B ~> B_A ==. a_key

I get an error like

Couldn't match type
    Selector (Key B (Unique BIdentifier) _)
with type
    Field BConstructor (Key A (Unique AIdentifier))

Maybe I could do this using a raw query or expression, if this is not directly possible?

Examples for getting on primary key?

All the examples show inserting new values and then using that return value (which is a Key) to "get" the record back, but none of them explain how to construct, say a CustomerKey (from your examples) from scratch using an Integer value. Would you be able to amend them for that, because I'd like to be able to do that, and I'm pretty lost on the types around Key.

Embedded sum types

Implementing embedded sum types will allow more flexible mapping between types and DB. Field types like (Either Int String) or (Maybe MyEmbedded) where Maybe is treated as another embedded sum type will become possible.

We have to specify precise behavior for the following operations before starting implementation. The main obstacle for the feature is semantics of accessing subfields that have a sum type in their chain. Such subfields can appear in projections, conditions, updates, etc.

Mapping embedded sum datatype to columns:

The discriminator column and nullable columns for the fields from all constructors.

Conversion to PersistValues:

toPersistValues returns: discriminator value, NULLs for the columns in the other constructors. Note that since we cannot call toPersistValues for values in the other constructors, we must know the number of columns to pad values with nulls. To get this number we can either analyze dbType (slow) or create a new PersistField function numberOfColumns.

Creating data values:

fromPersistValues chooses constructor basing on the discriminator value, skips the NULLs for the other constructors using number of columns for their field types.

Example:

data Sum = One Int | Two String | Three (Int, String)
columns: sumDiscr INTEGER NOT NULL, one INTEGER, two VARCHAR, three#val0 INTEGER, three#val1 VARCHAR
toPersistValues (Two "abc") -> [PersistInt64 1, PersistNull, PersistString "abc", PersistNull, PersistNull]

Subfields:

Consider
data MyEntity = MyEntity {myEither :: Either Int Sum}
project (MyEither ~> LeftSelector)
project (MyEither ~> RightSelector). In this case all values of Sum including its discriminator may be NULLs.

Since any column of a embedded sum type can be NULL, the final type of selector chains must have Maybe (or another optional type), eg, SubField v c (Maybe a). Example:
MyEither ~> LeftSelector :: SubField MyEntity MyEntityConstructor (Maybe Int)
MyEither ~> RightSelector :: SubField MyEntity MyEntityConstructor (Maybe Sum)
MyEither ~> RightSelector ~> TwoSelector :: SubField MyEntity MyEntityConstructor (Maybe String)

instance Embedded (Either a b) where
data Selector (Either a b) c where
LeftSelector :: Selector v c (Maybe a)
RightSelector :: Selector v c (Maybe b)
selectorNum LeftSelector = 0
selectorNum RightSelector = 1

But in this case to access nested sum types, operator ~> should be applicable both to (emb :: f db r a) and (emb :: f db r (Maybe a)) which requires some class hackery. Also we will have nested Maybes and it is not clear how a single PersistField (Maybe a) instance can handle them.

If the fields we select are nullable themselves, we should distinguish between nulls in case when our type has different constructor and when constructor matches, but field is null. Either Int (Maybe Int). To do this we may select the discriminator column for the innermost embedded type. But in this case the number of columns in comparison expressions will not match.

Another approach for projection is to use another subfield type for a chain that contains a sum type. A separate Projection instance will add Maybe. Something like (Projection (SumTypeSubField a) db r (Maybe a)).

select statement returning AutoKey

How do I create a select statement that returns the entity key like selectAll does?

selectAll conses an int46 onto the types:
let types = DbInt64:getConstructorTypes constr

I was trying to answer the question for myself but I didn't know where to look next.

select :: forall m db r v c opts . (db ~ PhantomDb m, r ~ RestrictionHolder v c, PersistBackend m, PersistEntity v, Constructor c, HasSelectOptions opts db r)
       => (Utf8 -> Utf8) -> (forall a . Utf8 -> [DbType] -> [PersistValue] -> (RowPopper m -> m a) -> m a) -> Utf8 -> (Cond db r -> Maybe (RenderS db r)) -> opts -> m [v]
select escape queryFunc noLimit renderCond' options = doSelectQuery where
  SelectOptions cond limit offset ords = getSelectOptions options

  e = entityDef (undefined :: v)
  proxy = undefined :: Proxy (PhantomDb m)
  orders = renderOrders escape ords
  (lim, limps) = case (limit, offset) of
        (Nothing, Nothing) -> ("", [])
        (Nothing, o) -> (" " <> noLimit <> " OFFSET ?", [toPrimitivePersistValue proxy o])
        (l, Nothing) -> (" LIMIT ?", [toPrimitivePersistValue proxy l])
        (l, o) -> (" LIMIT ? OFFSET ?", [toPrimitivePersistValue proxy l, toPrimitivePersistValue proxy o])
  cond' = renderCond' cond
  fields = renderFields escape (constrParams constr)
  query = "SELECT " <> fields <> " FROM " <> tableName escape e constr <> whereClause <> orders <> lim
  whereClause = maybe "" (\c -> " WHERE " <> getQuery c) cond'
  doSelectQuery = queryFunc query types binds $ mapAllRows $ liftM fst . fromEntityPersistValues . (toPrimitivePersistValue proxy cNum:)
  binds = maybe id getValues cond' $ limps
  cNum = phantomConstrNum (undefined :: c a)
  constr = constructors e !! cNum
  types = getConstructorTypes constr

selectAll :: forall m v . (PersistBackend m, PersistEntity v)
          => (Utf8 -> Utf8) -> (forall a . Utf8 -> [DbType] -> [PersistValue] -> (RowPopper m -> m a) -> m a) -> m [(AutoKey v, v)]
selectAll escape queryFunc = start where
  start = if isSimple (constructors e)
    then let
      constr = head $ constructors e
      fields = maybe id (\key cont -> key <> fromChar ',' <> cont) (constrId escape constr) $ renderFields escape (constrParams constr)
      query = "SELECT " <> fields <> " FROM " <> tableName escape e constr
      types = maybe id (const $ (DbInt64:)) (constrId escape constr) $ getConstructorTypes constr
      in queryFunc query types [] $ mapAllRows $ mkEntity proxy 0
    else liftM concat $ forM (zip [0..] (constructors e)) $ \(cNum, constr) -> do
        let fields = fromJust (constrId escape constr) <> fromChar ',' <> renderFields escape (constrParams constr)
        let query = "SELECT " <> fields <> " FROM " <> tableName escape e constr
        let types = DbInt64:getConstructorTypes constr
        queryFunc query types [] $ mapAllRows $ mkEntity proxy cNum
  e = entityDef (undefined :: v)
  proxy = undefined :: Proxy (PhantomDb m)

Sharing types between frontend (ghcjs) and backend (ghc)

Groundhog's encoding of foreign keys makes relationships between tables typesafe; the price to pay is yaml parsing (which depends on a c library), code generation with template haskell, and injecting groundhog-specific type constructors (i.e. DefaultKey) into the user's types.

This makes it hard to a library of application types with few dependencies - something we like to do if we want to share types between backend server compiled by ghc and frontend application compiled by ghcjs.

@mightybyte and I have been comparing solutions to this problem - I wonder if you have your own ideas of how to fix this?

CPP + custom type family in ghcjs case

In user code, chop out mkPersist ghCodegen [groundhog| ... |] from the code with CPP when the compiler is GHCJS, and instead include type instance DefaultKey MyType = Int64. Somewhere at the top-level define type family DefaultKey a :: * This works well, but is a bit of a burden on user's code.

Parse YAML description in ghcjs

By using a different yaml parser when the compiler is ghcjs, the yaml can be parsed and template haskell can then happily make the associated types. groundhog and groundhog-th can themselves be compiled with ghcjs, as can the user's code with the quasiquotes in it. I tried this in a patch to groundhog (master...imalsogreg:ghcjs) that relies on a small, not-yet-on-hackage ghcjs yaml parser binding (https://github.com/imalsogreg/yaml-ghcjs). groundhog-postgres (and probably the other backends) still can't be compiled though - they fail at the linking phase because they depend on a c library. So there is no way to get the captive Postgresql newtype in the client code, which we sometimes need in order to turn Key a BackendSpecific into Int64 and back. My workaround here is to make a NullDatabese empty data type and DbDescriptor instance for it, and use those in the client code to turn Keys into Ints.

Those are a couple of options - if you play with ghcjs, do you have any alternative ideas here, or a preference to go forward? Would you be open to pull requests that introduce CPP into groundhog-th to handle the ghcjs case? Thanks for reading a long message!

Query performance (table indexes are ignored)

Hello,

please take a look at equalsOperator a b for Postgresql:

equalsOperator a b = a <> " IS NOT DISTINCT FROM " <> b

a IS NOT DISTINCT FROM b always ignores indexes, which makes queries on large table quite expensive

testdb=# explain ANALYZE UPDATE "public"."test_table" SET "status"='Something' WHERE "id" IS NOT DISTINCT FROM 468029;                                                                          
                                                     QUERY PLAN                                                     
--------------------------------------------------------------------------------------------------------------------
 Update on test_table  (cost=0.00..59080.88 rows=1 width=87) (actual time=544.271..544.271 rows=0 loops=1)
   ->  Seq Scan on test_table  (cost=0.00..59080.88 rows=1 width=87) (actual time=105.891..543.881 rows=1 loops=1)
         Filter: (NOT (id IS DISTINCT FROM 468029))
         Rows Removed by Filter: 2139457
 Total runtime: 544.308 ms
(5 rows)

Compared to a query using index:

testdb=# explain ANALYZE UPDATE "public"."test_table" SET "status"='Something' WHERE "id"=468029;                                                                                               
                                                             QUERY PLAN                                                              
-------------------------------------------------------------------------------------------------------------------------------------
 Update on test_table  (cost=0.43..8.45 rows=1 width=87) (actual time=0.069..0.069 rows=0 loops=1)
   ->  Index Scan using test_table_pkey on test_table  (cost=0.43..8.45 rows=1 width=87) (actual time=0.034..0.035 rows=1 loops=1)
         Index Cond: (id = 468029)
 Total runtime: 0.116 ms
(4 rows)

I understand that from Haskell perspective Nothing == Nothing, but SQL standard (and postgresql) doesn't consider any two NULL values equal.
cb3adca (from 2011) introduced IS NOT DISTINCT as equals operator. Is there any other reason (except NULL behavior) that requires use IS NOT DISTINCT (or <>, <=> in mysql/sqlite)?

Would you be open to fixing this?
I'm new to the groundhog codebase, so I'm not sure what would be the best way to fix this. Do you have any suggestions?

In any case, thank you for this awesome library - keep up the good work!

Streaming interface for queries?

Currently, I use select as in e.g.

            coms <- runDbConn (select ((ComBoardField ==. BoardIdKey bid) &&.
                                       (ComArtNumField >=. lo') &&.
                                       (ComArtNumField <=. hi'))) cm

to fetch up to about 20000 rows from a table. However, this seems to result in 60MiB of ARR_WORDS being allocated according to Heap profiling, which is far more than the underlying (Sqlite) database contains actual data.

Is there a way to consume result values as soon as they get returned, rather than all at once? Maybe e.g. via a fold-like API?

Examples of CondRaw/expanding raw queries

Hi,

Ive been spinning my wheels for a few hours now trying to figure out how to do raw querying just on the condition of an expression so I can still use typesafe projections, limits, etc. All of the examples in the raw queries example just have an entire raw expression, and do manual projections into a tuple. I just can't figure it out from the haddocks.

I was wondering if you could illuminate (preferably in a way that you or I could put into the raw query example) a way to specify some raw conditions but still have Groundhog handle the projections and turn it into my record type automatically like it does with other queries.

My example that I'm working with has a condition that does a haversine calculation on a coord and tests whether its under some threshold. The condition is like:

( 3959 * acos(cos(radians(?)) * -- latitude
  cos(radians(stores.latitude)) *
  cos(radians(stores.longitude) - radians(?) ) + -- longitude
  sin(radians(?) ) * sin(radians(stores.latitude)))) < ? -- latitude, some constant number of miles like 50

I appreciate any help you are able to provide. I'm fully willing to help you augment the docs if I am able.

Get rid of String for internal representations.

I did a quick first pass here: I made library dependent strings into Text and SQL related strings into Utf8.Text in BSON, Redis and ReQL and the like are closer to Text than to String so it might be nice to have a more direct relationship for the mappings to the backend.

I also got rid of StringLike interface on flattenP since it would've converted into string and back. This also makes it easy to swap out what type Utf8 is, making it easy to try out different string representations.

It still needs some more work. So far I converted groundhog, part of groundhog-th and groundhog-sqlite
https://github.com/lykahb/groundhog/compare/master...hansonkd:string-to-text?expand=1

I thought this would have had more of a speed bump, but it looks like it is about the same as current master so I am probably going to put it on hold. Although it still solves the problem of preventing encoding information from being lost (in an intermediate PersistString).

This also removes read for integer conversion in favor of Text.Reader. A parsing library should be found for datetime conversion.

Edit:
This should only mean backend changes. Users can keep using Strings and have the same performance as before.

By my current benchmarks it increases the speed of Text fields 2x-4x (compared with Text fields in Master), speeds up query render (see critLite.hs) times between 1.5x and 3x, String fields remain about the same performance. Switching from String to Text will be about a 1.5x speedup.

Trying to compile on 7.8.2

Receive this on a fresh cabal install on ghc 7.8.2

Last 10 lines of the build log ( /Users/me/projects/project/.cabal-sandbox/logs/groundhog-0.4.2.2.log ):

Database/Groundhog/Instances.hs:541:10:
    Illegal instance declaration for
      ‘FieldLike (u (UniqueMarker v)) db r k’
      The liberal coverage condition fails in class ‘FieldLike’
        for functional dependency: ‘f -> r a’
      Reason: lhs type ‘u (UniqueMarker v)’
        does not determine rhs types ‘r’, ‘k’
    In the instance declaration for
      ‘FieldLike (u (UniqueMarker v)) db r k’

in_ gives unintuitive behavior for empty list

The definition of the in_ function contains the following:

in_ _ [] = CondEmpty

This results in very unintuitive behavior. I think the natural behavior would be to use a value of false instead of CondEmpty.

IN operator without raw SQL

Forgive me if I've missed it but I cant find anything in the docs that would let you do an IN, i.e. something like select $ [val1, val2]inFieldMyField

This seems like it would be pretty easy to make typesafe, since lists are homogenous. Also, I don't know any way to work around this missing feature for sufficiently large lists without building an enormous OR statement.

One last thought, I could see 2 ways of addressing the issue of empty lists:

  1. Requiring a NonEmpty from semigroups
  2. Have empty list just not produce a condition (return NoCond?)

Would love to hear your thoughts on this.

How do I get the autokey for a record?

I'm trying to create a test example codebase based around the basics example: https://github.com/lykahb/groundhog/blob/master/examples/basic.hs

I've created 10 or so records in the database. I also have some code that grabs them all out... now how do I take one of the Customer records and save it back into the database? How can I get the AutoKey?

I've looked through all the examples and most of the codebase. I can't find out how to do this.

Do I need to change the template haskell for mkPersist?

Please amend the examples so they make this obvious. This is a very common use case, such as creating a web app (which I'm doing), and you have a list of items, and you need to know which are which such that you edit the correct one, so you can save them back.

groundhog-th: yaml dependency

Is it possible to remove the yaml <0.8 constraint?

yaml <0.8 depends on conduit 0.4 and one would like to use the current conduit version, 0.5.

Thank you

Hackage release for transformers-0.5

I can see that the master branch has already bumped the version bounds for transformers. It would be nice to have this change on hackage too.

Nondeterministic groundhog compile errors

I have been getting occasional nondeterministic compile errors with groundhog for quite some time. I haven't said anything before now because I have no idea how to reproduce them or supply a minimal test case demonstrating the problem. I recently upgraded one of my large groundhog projects to GHC 7.8 and now the problem seems to be happening more often. Here's the error I get:

src/Field.hs:140:35:
    Could not deduce (PrimitivePersistField String)
      arising from a use of ‘toPrimitivePersistValue’
    from the context (DbDescriptor db)
      bound by the type signature for
                 toPrimitivePersistValue :: DbDescriptor db =>
                                            proxy db -> Field -> PersistValue
      at src/Field.hs:140:5-27
    In the expression: toPrimitivePersistValue p
    In the expression: toPrimitivePersistValue p $ show x
    In an equation for ‘toPrimitivePersistValue’:
        toPrimitivePersistValue p x = toPrimitivePersistValue p $ show x

src/Field.hs:141:44:
    Could not deduce (PrimitivePersistField String)
      arising from a use of ‘fromPrimitivePersistValue’
    from the context (DbDescriptor db)
      bound by the type signature for
                 fromPrimitivePersistValue :: DbDescriptor db =>
                                              proxy db -> PersistValue -> Field
      at src/Field.hs:141:5-29
    In the second argument of ‘($)’, namely
      ‘fromPrimitivePersistValue p x’
    In the expression: read $ fromPrimitivePersistValue p x
    In an equation for ‘fromPrimitivePersistValue’:
        fromPrimitivePersistValue p x
          = read $ fromPrimitivePersistValue p x

These errors always seem to come in pairs. Here is the code on lines 139-141 of that file.

instance PrimitivePersistField Field where
    toPrimitivePersistValue p x = toPrimitivePersistValue p $ show x
    fromPrimitivePersistValue p x = read $ fromPrimitivePersistValue p x

I've also seen the error in other places where I'm defining a PrimitivePersistField instance. The bizarre thing is that the solution to the problem is simply cabal clean and then build again. This usually makes the problem go away. Since the upgrade from GHC 7.6 to 7.8.4, the problem comes up more often and now sometimes I have to do several cabal cleans before it will compile successfully. Unfortunately I can't show you the code because it's a proprietary project and I haven't ever been able to reproduce the problem anywhere else. I know this doesn't give you much to go on, but I wanted to open this issue to at least make the problem known.

`getBy` and `select` should ideally also return the AutoKey

With getBy defined as below, it is often inconvenient to lookup by a unique key followed by and update or a replace. If getBy also returned the AutoKey for the record in question, that can then easily be used for subsequent operations.

getBy :: (PersistEntity v, IsUniqueKey (Key v (Unique u))) => Key v (Unique u) -> m (Maybe v)

Same applies to select - it is most often better to use the more verbose project to get both the AutoKey and the constructor.

Given AutoKey is very central to groundhog's API (many ops require it), it may be better to return it by default in these kinds of operations.

Conversely, it would be useful to define a new replaceBy function that uses a unique key to perform replacement.

Feature request: deleteAll

We already have selectAll and countAll -- it would be nice to have a deleteAll as well. I've tried to construct it manually but it's awkward to pass a CondEmpty to 'delete' since there's not enough type information. You wind up importing a bunch of internals just to be able to specify the table you want to delete from.

attoparsec not installed error - cabal sandbox

I've tried to install groundhog into my cabal sandbox and got following error - is it a known issue? Does it have any workarounds?

[opensourcegeek@localhost sandbox_sample]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

[opensourcegeek@localhost sandbox_sample]$ cabal --version
cabal-install version 1.16.0.2
using version 1.16.0 of the Cabal library

[opensourcegeek@localhost sandbox_sample]$ cabal install groundhog
Resolving dependencies...
Downloading auto-update-0.1.2.1...
Configuring auto-update-0.1.2.1...
Building auto-update-0.1.2.1...
Preprocessing library auto-update-0.1.2.1...
[1 of 4] Compiling Control.AutoUpdate.Util ( Control/AutoUpdate/Util.hs, dist/build/Control/AutoUpdate/Util.o )
[2 of 4] Compiling Control.Reaper ( Control/Reaper.hs, dist/build/Control/Reaper.o )
[3 of 4] Compiling Control.Debounce ( Control/Debounce.hs, dist/build/Control/Debounce.o )
[4 of 4] Compiling Control.AutoUpdate ( Control/AutoUpdate.hs, dist/build/Control/AutoUpdate.o )
In-place registering auto-update-0.1.2.1...
Installing library in
/home/opensourcegeek/.cabal/lib/auto-update-0.1.2.1/ghc-7.6.3
Registering auto-update-0.1.2.1...
Installed auto-update-0.1.2.1
Downloading base64-bytestring-1.0.0.1...
Configuring base64-bytestring-1.0.0.1...
Building base64-bytestring-1.0.0.1...
Preprocessing library base64-bytestring-1.0.0.1...
[1 of 5] Compiling Data.ByteString.Base64.Internal ( Data/ByteString/Base64/Internal.hs, dist/build/Data/ByteString/Base64/Internal.o )
[2 of 5] Compiling Data.ByteString.Base64.URL ( Data/ByteString/Base64/URL.hs, dist/build/Data/ByteString/Base64/URL.o )
[3 of 5] Compiling Data.ByteString.Base64.URL.Lazy ( Data/ByteString/Base64/URL/Lazy.hs, dist/build/Data/ByteString/Base64/URL/Lazy.o )
[4 of 5] Compiling Data.ByteString.Base64 ( Data/ByteString/Base64.hs, dist/build/Data/ByteString/Base64.o )
[5 of 5] Compiling Data.ByteString.Base64.Lazy ( Data/ByteString/Base64/Lazy.hs, dist/build/Data/ByteString/Base64/Lazy.o )
In-place registering base64-bytestring-1.0.0.1...
Installing library in
/home/opensourcegeek/.cabal/lib/base64-bytestring-1.0.0.1/ghc-7.6.3
Registering base64-bytestring-1.0.0.1...
Installed base64-bytestring-1.0.0.1
Downloading dlist-0.7.1...
Configuring dlist-0.7.1...
Building dlist-0.7.1...
Preprocessing library dlist-0.7.1...
[1 of 1] Compiling Data.DList ( Data/DList.hs, dist/build/Data/DList.o )
In-place registering dlist-0.7.1...
Installing library in /home/opensourcegeek/.cabal/lib/dlist-0.7.1/ghc-7.6.3
Registering dlist-0.7.1...
Installed dlist-0.7.1
Downloading monad-loops-0.4.2.1...
Configuring monad-loops-0.4.2.1...
Building monad-loops-0.4.2.1...
Preprocessing library monad-loops-0.4.2.1...
[1 of 1] Compiling Control.Monad.Loops ( src/Control/Monad/Loops.hs, dist/build/Control/Monad/Loops.o )
In-place registering monad-loops-0.4.2.1...
Installing library in
/home/opensourcegeek/.cabal/lib/monad-loops-0.4.2.1/ghc-7.6.3
Registering monad-loops-0.4.2.1...
Installed monad-loops-0.4.2.1
Downloading nats-1...
Configuring nats-1...
Building nats-1...
Preprocessing library nats-1...
[1 of 1] Compiling Numeric.Natural ( src/Numeric/Natural.hs, dist/build/Numeric/Natural.o )
In-place registering nats-1...
Installing library in /home/opensourcegeek/.cabal/lib/nats-1/ghc-7.6.3
Registering nats-1...
Installed nats-1
Downloading network-2.6.0.2...
Configuring network-2.6.0.2...
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for an ANSI C-conforming const... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking for stdlib.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking winsock2.h usability... no
checking winsock2.h presence... no
checking for winsock2.h... no
checking ws2tcpip.h usability... no
checking ws2tcpip.h presence... no
checking for ws2tcpip.h... no
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking netinet/tcp.h usability... yes
checking netinet/tcp.h presence... yes
checking for netinet/tcp.h... yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking sys/uio.h usability... yes
checking sys/uio.h presence... yes
checking for sys/uio.h... yes
checking sys/un.h usability... yes
checking sys/un.h presence... yes
checking for sys/un.h... yes
checking for readlink... yes
checking for symlink... yes
checking for struct msghdr.msg_control... yes
checking for struct msghdr.msg_accrights... no
checking for struct sockaddr.sa_len... no
checking for in_addr_t in netinet/in.h... yes
checking for SO_PEERCRED and struct ucred in sys/socket.h... yes
checking for getpeereid in unistd.h... checking for getpeereid... no
checking for _head_libws2_32_a in -lws2_32... no
checking for getaddrinfo... yes
checking for gai_strerror... yes
checking whether AI_ADDRCONFIG is declared... yes
checking whether AI_ALL is declared... yes
checking whether AI_NUMERICSERV is declared... yes
checking whether AI_V4MAPPED is declared... yes
checking whether IPV6_V6ONLY is declared... yes
checking whether IPPROTO_IP is declared... yes
checking whether IPPROTO_TCP is declared... yes
checking whether IPPROTO_IPV6 is declared... yes
checking for sendfile in sys/sendfile.h... yes
checking for sendfile in sys/socket.h... no
checking for gethostent... yes
checking for accept4... yes
configure: creating ./config.status
config.status: creating network.buildinfo
config.status: creating include/HsNetworkConfig.h
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
Building network-2.6.0.2...
Preprocessing library network-2.6.0.2...
[ 1 of 11] Compiling Network.Socket.ByteString.IOVec ( dist/build/Network/Socket/ByteString/IOVec.hs, dist/build/Network/Socket/ByteString/IOVec.o )
[ 2 of 11] Compiling Network.Socket.Types ( dist/build/Network/Socket/Types.hs, dist/build/Network/Socket/Types.o )

Network/Socket/Types.hsc:824:1: Warning:
Pattern match(es) are non-exhaustive
In an equation for `sizeOfSockAddrByFamily':
Patterns not matched:
AF_UNSPEC
AF_IMPLINK
AF_PUP
AF_CHAOS
...

Network/Socket/Types.hsc:896:3: Warning:
Pattern match(es) are non-exhaustive
In a case alternative:
Patterns not matched: #x with #x notElem [1#, 2#, 10#]

Network/Socket/Types.hsc:952:10: Warning:
Orphan instance: instance Storable HostAddress6
[ 3 of 11] Compiling Network.Socket.Internal ( dist/build/Network/Socket/Internal.hs, dist/build/Network/Socket/Internal.o )

Network/Socket/Internal.hsc:75:1: Warning:
The import of Foreign.C.String' is redundant except perhaps to import instances fromForeign.C.String'
To import instances alone, use: import Foreign.C.String()

Network/Socket/Internal.hsc:77:1: Warning:
The import of Foreign.Ptr' is redundant except perhaps to import instances fromForeign.Ptr'
To import instances alone, use: import Foreign.Ptr()
[ 4 of 11] Compiling Network.Socket ( dist/build/Network/Socket.hs, dist/build/Network/Socket.o )

Network/Socket.hsc:176:1: Warning:
The import of delete' from moduleData.List' is redundant

Network/Socket.hsc:192:1: Warning:
The qualified import of Control.Exception' is redundant except perhaps to import instances fromControl.Exception'
To import instances alone, use: import Control.Exception()

Network/Socket.hsc:211:1: Warning:
The import of GHC.IO.FD' is redundant except perhaps to import instances fromGHC.IO.FD'
To import instances alone, use: import GHC.IO.FD()

Network/Socket.hsc:949:13: Warning:
Defaulting the following constraint(s) to type Integer' (Integral a0) arising from a use offromIntegral'
at Network/Socket.hsc:949:13-24
(Num a0)
arising from the literal 12' at Network/Socket.hsc:949:27-28 In the expression: (fromIntegral (12)) In an equation forsz': sz = (fromIntegral (12))
In the expression:
do { let fd = fdSocket sock;
let sz = (fromIntegral (12));
with sz $ \ ptr_cr -> alloca $ \ ptr_sz -> ... }

Network/Socket.hsc:953:6: Warning:
A do-notation statement discarded a result of type CInt.
Suppress this warning by saying "_ <- ($)
throwSocketErrorIfMinus1Retry "getPeerCred"
c_getsockopt fd (1) (17) ptr_cr ptr_sz",
or by using the flag -fno-warn-unused-do-bind

Network/Socket.hsc:989:3: Warning:
A do-notation statement discarded a result of type CInt.
Suppress this warning by saying "_ <- ($)
throwSocketErrorWaitWrite sock "sendFd"
c_sendFd (fdSocket sock) outfd",
or by using the flag -fno-warn-unused-do-bind

Network/Socket.hsc:1572:3: Warning:
Defined but not used: `c_accept'
[ 5 of 11] Compiling Network.Socket.ByteString.MsgHdr ( dist/build/Network/Socket/ByteString/MsgHdr.hs, dist/build/Network/Socket/ByteString/MsgHdr.o )
[ 6 of 11] Compiling Network.Socket.ByteString.Internal ( Network/Socket/ByteString/Internal.hs, dist/build/Network/Socket/ByteString/Internal.o )
[ 7 of 11] Compiling Network.Socket.ByteString ( dist/build/Network/Socket/ByteString.hs, dist/build/Network/Socket/ByteString.o )

Network/Socket/ByteString.hsc:54:1: Warning:
The import of SockAddr, Socket' from moduleNetwork.Socket' is redundant
[ 8 of 11] Compiling Network.Socket.ByteString.Lazy ( Network/Socket/ByteString/Lazy.hs, dist/build/Network/Socket/ByteString/Lazy.o )

Network/Socket/ByteString/Lazy.hs:60:1: Warning:
The import of GHC.Conc' is redundant except perhaps to import instances fromGHC.Conc'
To import instances alone, use: import GHC.Conc()
[ 9 of 11] Compiling Network.Socket.ByteString.Lazy.Posix ( Network/Socket/ByteString/Lazy/Posix.hs, dist/build/Network/Socket/ByteString/Lazy/Posix.o )
[10 of 11] Compiling Network.BSD ( dist/build/Network/BSD.hs, dist/build/Network/BSD.o )
[11 of 11] Compiling Network ( Network.hs, dist/build/Network.o )
In-place registering network-2.6.0.2...
Installing library in
/home/opensourcegeek/.cabal/lib/network-2.6.0.2/ghc-7.6.3
Registering network-2.6.0.2...
Installed network-2.6.0.2
Downloading scientific-0.3.3.7...
Configuring scientific-0.3.3.7...
Building scientific-0.3.3.7...
Preprocessing library scientific-0.3.3.7...
[1 of 4] Compiling Math.NumberTheory.Logarithms ( src/Math/NumberTheory/Logarithms.hs, dist/build/Math/NumberTheory/Logarithms.o )
[2 of 4] Compiling Data.Scientific ( src/Data/Scientific.hs, dist/build/Data/Scientific.o )
[3 of 4] Compiling Data.Text.Lazy.Builder.Scientific ( src/Data/Text/Lazy/Builder/Scientific.hs, dist/build/Data/Text/Lazy/Builder/Scientific.o )
[4 of 4] Compiling Data.ByteString.Builder.Scientific ( src/Data/ByteString/Builder/Scientific.hs, dist/build/Data/ByteString/Builder/Scientific.o )
In-place registering scientific-0.3.3.7...
Installing library in
/home/opensourcegeek/.cabal/lib/scientific-0.3.3.7/ghc-7.6.3
Registering scientific-0.3.3.7...
Installed scientific-0.3.3.7
Downloading stm-chans-3.0.0.2...
[1 of 1] Compiling Main ( /tmp/stm-chans-3.0.0.2-10786/stm-chans-3.0.0.2/Setup.hs, /tmp/stm-chans-3.0.0.2-10786/stm-chans-3.0.0.2/dist/setup/Main.o )
Linking /tmp/stm-chans-3.0.0.2-10786/stm-chans-3.0.0.2/dist/setup/setup ...
Configuring stm-chans-3.0.0.2...
Building stm-chans-3.0.0.2...
Preprocessing library stm-chans-3.0.0.2...
[1 of 5] Compiling Control.Concurrent.STM.TMQueue ( src/Control/Concurrent/STM/TMQueue.hs, dist/build/Control/Concurrent/STM/TMQueue.o )
[2 of 5] Compiling Control.Concurrent.STM.TBMQueue ( src/Control/Concurrent/STM/TBMQueue.hs, dist/build/Control/Concurrent/STM/TBMQueue.o )
[3 of 5] Compiling Control.Concurrent.STM.TMChan ( src/Control/Concurrent/STM/TMChan.hs, dist/build/Control/Concurrent/STM/TMChan.o )
[4 of 5] Compiling Control.Concurrent.STM.TBMChan ( src/Control/Concurrent/STM/TBMChan.hs, dist/build/Control/Concurrent/STM/TBMChan.o )
[5 of 5] Compiling Control.Concurrent.STM.TBChan ( src/Control/Concurrent/STM/TBChan.hs, dist/build/Control/Concurrent/STM/TBChan.o )
In-place registering stm-chans-3.0.0.2...
Installing library in
/home/opensourcegeek/.cabal/lib/stm-chans-3.0.0.2/ghc-7.6.3
Registering stm-chans-3.0.0.2...
Installed stm-chans-3.0.0.2
Downloading transformers-0.4.3.0...
Configuring transformers-0.4.3.0...
Building transformers-0.4.3.0...
Preprocessing library transformers-0.4.3.0...
[ 1 of 28] Compiling Control.Monad.Trans.Class ( Control/Monad/Trans/Class.hs, dist/build/Control/Monad/Trans/Class.o )
[ 2 of 28] Compiling Control.Monad.Signatures ( Control/Monad/Signatures.hs, dist/build/Control/Monad/Signatures.o )
[ 3 of 28] Compiling Control.Monad.IO.Class ( Control/Monad/IO/Class.hs, dist/build/Control/Monad/IO/Class.o )
[ 4 of 28] Compiling Data.Functor.Identity ( oldsrc/Data/Functor/Identity.hs, dist/build/Data/Functor/Identity.o )
[ 5 of 28] Compiling Data.Functor.Classes ( Data/Functor/Classes.hs, dist/build/Data/Functor/Classes.o )
[ 6 of 28] Compiling Control.Applicative.Backwards ( Control/Applicative/Backwards.hs, dist/build/Control/Applicative/Backwards.o )
[ 7 of 28] Compiling Data.Functor.Constant ( Data/Functor/Constant.hs, dist/build/Data/Functor/Constant.o )
[ 8 of 28] Compiling Control.Applicative.Lift ( Control/Applicative/Lift.hs, dist/build/Control/Applicative/Lift.o )
[ 9 of 28] Compiling Control.Monad.Trans.Error ( Control/Monad/Trans/Error.hs, dist/build/Control/Monad/Trans/Error.o )
[10 of 28] Compiling Control.Monad.Trans.Identity ( Control/Monad/Trans/Identity.hs, dist/build/Control/Monad/Trans/Identity.o )
[11 of 28] Compiling Control.Monad.Trans.List ( Control/Monad/Trans/List.hs, dist/build/Control/Monad/Trans/List.o )
[12 of 28] Compiling Data.Functor.Compose ( Data/Functor/Compose.hs, dist/build/Data/Functor/Compose.o )
[13 of 28] Compiling Data.Functor.Product ( Data/Functor/Product.hs, dist/build/Data/Functor/Product.o )
[14 of 28] Compiling Data.Functor.Reverse ( Data/Functor/Reverse.hs, dist/build/Data/Functor/Reverse.o )
[15 of 28] Compiling Data.Functor.Sum ( Data/Functor/Sum.hs, dist/build/Data/Functor/Sum.o )
[16 of 28] Compiling Control.Monad.Trans.Cont ( Control/Monad/Trans/Cont.hs, dist/build/Control/Monad/Trans/Cont.o )
[17 of 28] Compiling Control.Monad.Trans.Except ( Control/Monad/Trans/Except.hs, dist/build/Control/Monad/Trans/Except.o )
[18 of 28] Compiling Control.Monad.Trans.Maybe ( Control/Monad/Trans/Maybe.hs, dist/build/Control/Monad/Trans/Maybe.o )
[19 of 28] Compiling Control.Monad.Trans.Reader ( Control/Monad/Trans/Reader.hs, dist/build/Control/Monad/Trans/Reader.o )
[20 of 28] Compiling Control.Monad.Trans.RWS.Lazy ( Control/Monad/Trans/RWS/Lazy.hs, dist/build/Control/Monad/Trans/RWS/Lazy.o )
[21 of 28] Compiling Control.Monad.Trans.RWS ( Control/Monad/Trans/RWS.hs, dist/build/Control/Monad/Trans/RWS.o )
[22 of 28] Compiling Control.Monad.Trans.RWS.Strict ( Control/Monad/Trans/RWS/Strict.hs, dist/build/Control/Monad/Trans/RWS/Strict.o )
[23 of 28] Compiling Control.Monad.Trans.State.Lazy ( Control/Monad/Trans/State/Lazy.hs, dist/build/Control/Monad/Trans/State/Lazy.o )
[24 of 28] Compiling Control.Monad.Trans.State ( Control/Monad/Trans/State.hs, dist/build/Control/Monad/Trans/State.o )
[25 of 28] Compiling Control.Monad.Trans.State.Strict ( Control/Monad/Trans/State/Strict.hs, dist/build/Control/Monad/Trans/State/Strict.o )
[26 of 28] Compiling Control.Monad.Trans.Writer.Lazy ( Control/Monad/Trans/Writer/Lazy.hs, dist/build/Control/Monad/Trans/Writer/Lazy.o )
[27 of 28] Compiling Control.Monad.Trans.Writer ( Control/Monad/Trans/Writer.hs, dist/build/Control/Monad/Trans/Writer.o )
[28 of 28] Compiling Control.Monad.Trans.Writer.Strict ( Control/Monad/Trans/Writer/Strict.hs, dist/build/Control/Monad/Trans/Writer/Strict.o )
In-place registering transformers-0.4.3.0...
Installing library in
/home/opensourcegeek/.cabal/lib/transformers-0.4.3.0/ghc-7.6.3
Registering transformers-0.4.3.0...
Installed transformers-0.4.3.0
Downloading fast-logger-2.3.0...
Configuring fast-logger-2.3.0...
Building fast-logger-2.3.0...
Preprocessing library fast-logger-2.3.0...
[1 of 6] Compiling System.Log.FastLogger.LogStr ( System/Log/FastLogger/LogStr.hs, dist/build/System/Log/FastLogger/LogStr.o )
[2 of 6] Compiling System.Log.FastLogger.IORef ( System/Log/FastLogger/IORef.hs, dist/build/System/Log/FastLogger/IORef.o )
[3 of 6] Compiling System.Log.FastLogger.IO ( System/Log/FastLogger/IO.hs, dist/build/System/Log/FastLogger/IO.o )
[4 of 6] Compiling System.Log.FastLogger.Logger ( System/Log/FastLogger/Logger.hs, dist/build/System/Log/FastLogger/Logger.o )
[5 of 6] Compiling System.Log.FastLogger.File ( System/Log/FastLogger/File.hs, dist/build/System/Log/FastLogger/File.o )
[6 of 6] Compiling System.Log.FastLogger ( System/Log/FastLogger.hs, dist/build/System/Log/FastLogger.o )
In-place registering fast-logger-2.3.0...
Installing library in
/home/opensourcegeek/.cabal/lib/fast-logger-2.3.0/ghc-7.6.3
Registering fast-logger-2.3.0...
Installed fast-logger-2.3.0
Downloading semigroups-0.16.2.2...
Configuring semigroups-0.16.2.2...
Building semigroups-0.16.2.2...
Preprocessing library semigroups-0.16.2.2...
[1 of 3] Compiling Data.List.NonEmpty ( src/Data/List/NonEmpty.hs, dist/build/Data/List/NonEmpty.o )
[2 of 3] Compiling Data.Semigroup ( src/Data/Semigroup.hs, dist/build/Data/Semigroup.o )
[3 of 3] Compiling Data.Semigroup.Generic ( src/Data/Semigroup/Generic.hs, dist/build/Data/Semigroup/Generic.o )
In-place registering semigroups-0.16.2.2...
Installing library in
/home/opensourcegeek/.cabal/lib/semigroups-0.16.2.2/ghc-7.6.3
Registering semigroups-0.16.2.2...
Installed semigroups-0.16.2.2
Downloading mmorph-1.0.4...
Configuring mmorph-1.0.4...
Building mmorph-1.0.4...
Preprocessing library mmorph-1.0.4...
[1 of 2] Compiling Control.Monad.Morph ( src/Control/Monad/Morph.hs, dist/build/Control/Monad/Morph.o )

src/Control/Monad/Morph.hs:76:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

src/Control/Monad/Morph.hs:116:20: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:117:19: Warning:
In the use of data constructor `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:117:34: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:241:11: Warning:
In the use of type constructor or class `E.Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:241:33: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:242:17: Warning:
In the use of data constructor `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:243:14: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

src/Control/Monad/Morph.hs:243:30: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
[2 of 2] Compiling Control.Monad.Trans.Compose ( src/Control/Monad/Trans/Compose.hs, dist/build/Control/Monad/Trans/Compose.o )
In-place registering mmorph-1.0.4...
Installing library in /home/opensourcegeek/.cabal/lib/mmorph-1.0.4/ghc-7.6.3
Registering mmorph-1.0.4...
Installed mmorph-1.0.4
Downloading mtl-2.2.1...
Configuring mtl-2.2.1...
Building mtl-2.2.1...
Preprocessing library mtl-2.2.1...
[ 1 of 22] Compiling Control.Monad.Writer.Class ( Control/Monad/Writer/Class.hs, dist/build/Control/Monad/Writer/Class.o )
[ 2 of 22] Compiling Control.Monad.State.Class ( Control/Monad/State/Class.hs, dist/build/Control/Monad/State/Class.o )
[ 3 of 22] Compiling Control.Monad.Reader.Class ( Control/Monad/Reader/Class.hs, dist/build/Control/Monad/Reader/Class.o )
[ 4 of 22] Compiling Control.Monad.RWS.Class ( Control/Monad/RWS/Class.hs, dist/build/Control/Monad/RWS/Class.o )
[ 5 of 22] Compiling Control.Monad.Identity ( Control/Monad/Identity.hs, dist/build/Control/Monad/Identity.o )
[ 6 of 22] Compiling Control.Monad.Error.Class ( Control/Monad/Error/Class.hs, dist/build/Control/Monad/Error/Class.o )
[ 7 of 22] Compiling Control.Monad.Cont.Class ( Control/Monad/Cont/Class.hs, dist/build/Control/Monad/Cont/Class.o )
[ 8 of 22] Compiling Control.Monad.Trans ( Control/Monad/Trans.hs, dist/build/Control/Monad/Trans.o )
[ 9 of 22] Compiling Control.Monad.Error ( Control/Monad/Error.hs, dist/build/Control/Monad/Error.o )
[10 of 22] Compiling Control.Monad.Except ( Control/Monad/Except.hs, dist/build/Control/Monad/Except.o )
[11 of 22] Compiling Control.Monad.List ( Control/Monad/List.hs, dist/build/Control/Monad/List.o )
[12 of 22] Compiling Control.Monad.RWS.Lazy ( Control/Monad/RWS/Lazy.hs, dist/build/Control/Monad/RWS/Lazy.o )
[13 of 22] Compiling Control.Monad.RWS ( Control/Monad/RWS.hs, dist/build/Control/Monad/RWS.o )
[14 of 22] Compiling Control.Monad.Reader ( Control/Monad/Reader.hs, dist/build/Control/Monad/Reader.o )
[15 of 22] Compiling Control.Monad.RWS.Strict ( Control/Monad/RWS/Strict.hs, dist/build/Control/Monad/RWS/Strict.o )
[16 of 22] Compiling Control.Monad.State.Lazy ( Control/Monad/State/Lazy.hs, dist/build/Control/Monad/State/Lazy.o )
[17 of 22] Compiling Control.Monad.State ( Control/Monad/State.hs, dist/build/Control/Monad/State.o )
[18 of 22] Compiling Control.Monad.State.Strict ( Control/Monad/State/Strict.hs, dist/build/Control/Monad/State/Strict.o )
[19 of 22] Compiling Control.Monad.Writer.Lazy ( Control/Monad/Writer/Lazy.hs, dist/build/Control/Monad/Writer/Lazy.o )
[20 of 22] Compiling Control.Monad.Writer ( Control/Monad/Writer.hs, dist/build/Control/Monad/Writer.o )
[21 of 22] Compiling Control.Monad.Writer.Strict ( Control/Monad/Writer/Strict.hs, dist/build/Control/Monad/Writer/Strict.o )
[22 of 22] Compiling Control.Monad.Cont ( Control/Monad/Cont.hs, dist/build/Control/Monad/Cont.o )
In-place registering mtl-2.2.1...
Installing library in /home/opensourcegeek/.cabal/lib/mtl-2.2.1/ghc-7.6.3
Registering mtl-2.2.1...
Installed mtl-2.2.1
Downloading streaming-commons-0.1.10.0...
Configuring streaming-commons-0.1.10.0...
Building streaming-commons-0.1.10.0...
Preprocessing library streaming-commons-0.1.10.0...
[ 1 of 18] Compiling Data.Streaming.Zlib.Lowlevel ( Data/Streaming/Zlib/Lowlevel.hs, dist/build/Data/Streaming/Zlib/Lowlevel.o )
[ 2 of 18] Compiling Data.Streaming.Zlib ( Data/Streaming/Zlib.hs, dist/build/Data/Streaming/Zlib.o )
[ 3 of 18] Compiling Data.Text.Internal.Unsafe.Shift ( Data/Text/Internal/Unsafe/Shift.hs, dist/build/Data/Text/Internal/Unsafe/Shift.o )
[ 4 of 18] Compiling Data.Text.Internal.Unsafe.Char ( Data/Text/Internal/Unsafe/Char.hs, dist/build/Data/Text/Internal/Unsafe/Char.o )
[ 5 of 18] Compiling Data.Text.Internal.Encoding.Utf8 ( Data/Text/Internal/Encoding/Utf8.hs, dist/build/Data/Text/Internal/Encoding/Utf8.o )
[ 6 of 18] Compiling Data.Text.Internal.Encoding.Utf32 ( Data/Text/Internal/Encoding/Utf32.hs, dist/build/Data/Text/Internal/Encoding/Utf32.o )
[ 7 of 18] Compiling Data.Text.Internal.Encoding.Utf16 ( Data/Text/Internal/Encoding/Utf16.hs, dist/build/Data/Text/Internal/Encoding/Utf16.o )
[ 8 of 18] Compiling Data.Streaming.Text ( Data/Streaming/Text.hs, dist/build/Data/Streaming/Text.o )
[ 9 of 18] Compiling Data.Streaming.Process.Internal ( Data/Streaming/Process/Internal.hs, dist/build/Data/Streaming/Process/Internal.o )
[10 of 18] Compiling Data.Streaming.Process ( Data/Streaming/Process.hs, dist/build/Data/Streaming/Process.o )
[11 of 18] Compiling Data.Streaming.Network.Internal ( Data/Streaming/Network/Internal.hs, dist/build/Data/Streaming/Network/Internal.o )
[12 of 18] Compiling Data.Streaming.Network ( Data/Streaming/Network.hs, dist/build/Data/Streaming/Network.o )
[13 of 18] Compiling Data.Streaming.Filesystem ( Data/Streaming/Filesystem.hs, dist/build/Data/Streaming/Filesystem.o )
[14 of 18] Compiling Data.Streaming.FileRead ( Data/Streaming/FileRead.hs, dist/build/Data/Streaming/FileRead.o )
[15 of 18] Compiling Data.Streaming.ByteString.Builder.Buffer ( Data/Streaming/ByteString/Builder/Buffer.hs, dist/build/Data/Streaming/ByteString/Builder/Buffer.o )
[16 of 18] Compiling Data.Streaming.ByteString.Builder ( Data/Streaming/ByteString/Builder.hs, dist/build/Data/Streaming/ByteString/Builder.o )
[17 of 18] Compiling Data.Streaming.ByteString.Builder.Class ( Data/Streaming/ByteString/Builder/Class.hs, dist/build/Data/Streaming/ByteString/Builder/Class.o )
[18 of 18] Compiling Data.Streaming.Blaze ( Data/Streaming/Blaze.hs, dist/build/Data/Streaming/Blaze.o )
In-place registering streaming-commons-0.1.10.0...
Installing library in
/home/opensourcegeek/.cabal/lib/streaming-commons-0.1.10.0/ghc-7.6.3
Registering streaming-commons-0.1.10.0...
Installed streaming-commons-0.1.10.0
Downloading transformers-compat-0.4.0.4...
Configuring transformers-compat-0.4.0.4...
Building transformers-compat-0.4.0.4...
Preprocessing library transformers-compat-0.4.0.4...
[1 of 1] Compiling Paths_transformers_compat ( dist/build/autogen/Paths_transformers_compat.hs, dist/build/Paths_transformers_compat.o )
In-place registering transformers-compat-0.4.0.4...
Installing library in
/home/opensourcegeek/.cabal/lib/transformers-compat-0.4.0.4/ghc-7.6.3
Registering transformers-compat-0.4.0.4...
Installed transformers-compat-0.4.0.4
Downloading void-0.7...
Configuring void-0.7...
Building void-0.7...
Preprocessing library void-0.7...
[1 of 2] Compiling Data.Void ( src-old/Data/Void.hs, dist/build/Data/Void.o )
[2 of 2] Compiling Data.Void.Unsafe ( src/Data/Void/Unsafe.hs, dist/build/Data/Void/Unsafe.o )
In-place registering void-0.7...
Installing library in /home/opensourcegeek/.cabal/lib/void-0.7/ghc-7.6.3
Registering void-0.7...
Installed void-0.7
Downloading aeson-0.6.2.1...
Configuring aeson-0.6.2.1...
Building aeson-0.6.2.1...
Preprocessing library aeson-0.6.2.1...
[ 1 of 11] Compiling Data.Aeson.Types.Internal ( Data/Aeson/Types/Internal.hs, dist/build/Data/Aeson/Types/Internal.o )
[ 2 of 11] Compiling Data.Aeson.Functions ( Data/Aeson/Functions.hs, dist/build/Data/Aeson/Functions.o )
[ 3 of 11] Compiling Data.Aeson.Types.Class ( Data/Aeson/Types/Class.hs, dist/build/Data/Aeson/Types/Class.o )
[ 4 of 11] Compiling Data.Aeson.Types.Generic ( Data/Aeson/Types/Generic.hs, dist/build/Data/Aeson/Types/Generic.o )
[ 5 of 11] Compiling Data.Aeson.Types ( Data/Aeson/Types.hs, dist/build/Data/Aeson/Types.o )
[ 6 of 11] Compiling Data.Aeson.Parser.Internal ( Data/Aeson/Parser/Internal.hs, dist/build/Data/Aeson/Parser/Internal.o )
[ 7 of 11] Compiling Data.Aeson.Parser ( Data/Aeson/Parser.hs, dist/build/Data/Aeson/Parser.o )
[ 8 of 11] Compiling Data.Aeson.Encode ( Data/Aeson/Encode.hs, dist/build/Data/Aeson/Encode.o )
[ 9 of 11] Compiling Data.Aeson.Generic ( Data/Aeson/Generic.hs, dist/build/Data/Aeson/Generic.o )
[10 of 11] Compiling Data.Aeson ( Data/Aeson.hs, dist/build/Data/Aeson.o )
[11 of 11] Compiling Data.Aeson.TH ( Data/Aeson/TH.hs, dist/build/Data/Aeson/TH.o )
In-place registering aeson-0.6.2.1...
Installing library in /home/opensourcegeek/.cabal/lib/aeson-0.6.2.1/ghc-7.6.3
Registering aeson-0.6.2.1...
Installed aeson-0.6.2.1
Downloading exceptions-0.8.0.2...
Configuring exceptions-0.8.0.2...
Building exceptions-0.8.0.2...
Preprocessing library exceptions-0.8.0.2...
[1 of 2] Compiling Control.Monad.Catch ( src/Control/Monad/Catch.hs, dist/build/Control/Monad/Catch.o )
[2 of 2] Compiling Control.Monad.Catch.Pure ( src/Control/Monad/Catch/Pure.hs, dist/build/Control/Monad/Catch/Pure.o )
In-place registering exceptions-0.8.0.2...
Installing library in
/home/opensourcegeek/.cabal/lib/exceptions-0.8.0.2/ghc-7.6.3
Registering exceptions-0.8.0.2...
Installed exceptions-0.8.0.2
Downloading transformers-base-0.4.4...
Configuring transformers-base-0.4.4...
Building transformers-base-0.4.4...
Preprocessing library transformers-base-0.4.4...
[1 of 1] Compiling Control.Monad.Base ( src/Control/Monad/Base.hs, dist/build/Control/Monad/Base.o )
In-place registering transformers-base-0.4.4...
Installing library in
/home/opensourcegeek/.cabal/lib/transformers-base-0.4.4/ghc-7.6.3
Registering transformers-base-0.4.4...
Installed transformers-base-0.4.4
Downloading monad-control-1.0.0.4...
Configuring monad-control-1.0.0.4...
Building monad-control-1.0.0.4...
Preprocessing library monad-control-1.0.0.4...
[1 of 1] Compiling Control.Monad.Trans.Control ( Control/Monad/Trans/Control.hs, dist/build/Control/Monad/Trans/Control.o )
In-place registering monad-control-1.0.0.4...
Installing library in
/home/opensourcegeek/.cabal/lib/monad-control-1.0.0.4/ghc-7.6.3
Registering monad-control-1.0.0.4...
Installed monad-control-1.0.0.4
Downloading lifted-base-0.2.3.6...
Configuring lifted-base-0.2.3.6...
Building lifted-base-0.2.3.6...
Preprocessing library lifted-base-0.2.3.6...
[ 1 of 10] Compiling System.Timeout.Lifted ( System/Timeout/Lifted.hs, dist/build/System/Timeout/Lifted.o )
[ 2 of 10] Compiling Foreign.Marshal.Utils.Lifted ( Foreign/Marshal/Utils/Lifted.hs, dist/build/Foreign/Marshal/Utils/Lifted.o )
[ 3 of 10] Compiling Data.IORef.Lifted ( Data/IORef/Lifted.hs, dist/build/Data/IORef/Lifted.o )
[ 4 of 10] Compiling Control.Concurrent.QSemN.Lifted ( Control/Concurrent/QSemN/Lifted.hs, dist/build/Control/Concurrent/QSemN/Lifted.o )
[ 5 of 10] Compiling Control.Concurrent.QSem.Lifted ( Control/Concurrent/QSem/Lifted.hs, dist/build/Control/Concurrent/QSem/Lifted.o )
[ 6 of 10] Compiling Control.Concurrent.Chan.Lifted ( Control/Concurrent/Chan/Lifted.hs, dist/build/Control/Concurrent/Chan/Lifted.o )
[ 7 of 10] Compiling Control.Concurrent.MVar.Lifted ( Control/Concurrent/MVar/Lifted.hs, dist/build/Control/Concurrent/MVar/Lifted.o )
[ 8 of 10] Compiling Control.Exception.Lifted ( Control/Exception/Lifted.hs, dist/build/Control/Exception/Lifted.o )
[ 9 of 10] Compiling Control.Concurrent.SampleVar.Lifted ( Control/Concurrent/SampleVar/Lifted.hs, dist/build/Control/Concurrent/SampleVar/Lifted.o )

Control/Concurrent/SampleVar/Lifted.hs:36:1: Warning:
Module `Control.Concurrent.SampleVar' is deprecated:
Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead.

Control/Concurrent/SampleVar/Lifted.hs:37:1: Warning:
Module `Control.Concurrent.SampleVar' is deprecated:
Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead.

Control/Concurrent/SampleVar/Lifted.hs:52:43: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:53:30: Warning:
In the use of `SampleVar.newEmptySampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:57:43: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:58:27: Warning:
In the use of `SampleVar.newSampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:62:37: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:63:29: Warning:
In the use of `SampleVar.emptySampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:67:36: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:68:28: Warning:
In the use of `SampleVar.readSampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:72:37: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:73:32: Warning:
In the use of `SampleVar.writeSampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:77:39: Warning:
In the use of type constructor or class `SampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."

Control/Concurrent/SampleVar/Lifted.hs:78:31: Warning:
In the use of `SampleVar.isEmptySampleVar'
(imported from Control.Concurrent.SampleVar):
Deprecated: "Control.Concurrent.SampleVar will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead."
[10 of 10] Compiling Control.Concurrent.Lifted ( Control/Concurrent/Lifted.hs, dist/build/Control/Concurrent/Lifted.o )
In-place registering lifted-base-0.2.3.6...
Installing library in
/home/opensourcegeek/.cabal/lib/lifted-base-0.2.3.6/ghc-7.6.3
Registering lifted-base-0.2.3.6...
Installed lifted-base-0.2.3.6
Downloading resourcet-1.1.4.1...
Configuring resourcet-1.1.4.1...
Building resourcet-1.1.4.1...
Preprocessing library resourcet-1.1.4.1...
[1 of 4] Compiling Data.Acquire.Internal ( Data/Acquire/Internal.hs, dist/build/Data/Acquire/Internal.o )
[2 of 4] Compiling Control.Monad.Trans.Resource.Internal ( Control/Monad/Trans/Resource/Internal.hs, dist/build/Control/Monad/Trans/Resource/Internal.o )

Control/Monad/Trans/Resource/Internal.hs:41:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

Control/Monad/Trans/Resource/Internal.hs:57:1: Warning:
The import of Control.Monad.ST' is redundant except perhaps to import instances fromControl.Monad.ST'
To import instances alone, use: import Control.Monad.ST()

Control/Monad/Trans/Resource/Internal.hs:69:1: Warning:
Module Prelude' does not exportcatch'

Control/Monad/Trans/Resource/Internal.hs:73:1: Warning:
The import of Control.Monad.ST.Unsafe' is redundant except perhaps to import instances fromControl.Monad.ST.Unsafe'
To import instances alone, use: import Control.Monad.ST.Unsafe()

Control/Monad/Trans/Resource/Internal.hs:79:1: Warning:
The qualified import of Control.Monad.ST.Lazy.Unsafe' is redundant except perhaps to import instances fromControl.Monad.ST.Lazy.Unsafe'
To import instances alone, use: import Control.Monad.ST.Lazy.Unsafe()

Control/Monad/Trans/Resource/Internal.hs:84:1: Warning:
The qualified import of Control.Monad.ST.Lazy' is redundant except perhaps to import instances fromControl.Monad.ST.Lazy'
To import instances alone, use: import Control.Monad.ST.Lazy()

Control/Monad/Trans/Resource/Internal.hs:287:11: Warning:
In the use of type constructor or class `Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Control/Monad/Trans/Resource/Internal.hs:287:56: Warning:
In the use of type constructor or class `ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
[3 of 4] Compiling Control.Monad.Trans.Resource ( Control/Monad/Trans/Resource.hs, dist/build/Control/Monad/Trans/Resource.o )

Control/Monad/Trans/Resource.hs:54:7: Warning:
The export item ExceptionT(..)' suggests that ExceptionT' has (in-scope) constructors or class methods,
but it has none

Control/Monad/Trans/Resource.hs:64:1: Warning:
The import of throw' from moduleControl.Exception' is redundant

Control/Monad/Trans/Resource.hs:73:1: Warning:
The import of Data.Monoid' is redundant except perhaps to import instances fromData.Monoid'
To import instances alone, use: import Data.Monoid()

Control/Monad/Trans/Resource.hs:76:1: Warning:
The import of Control.Monad.Trans.Identity' is redundant except perhaps to import instances fromControl.Monad.Trans.Identity'
To import instances alone, use: import Control.Monad.Trans.Identity()

Control/Monad/Trans/Resource.hs:77:1: Warning:
The import of Control.Monad.Trans.List' is redundant except perhaps to import instances fromControl.Monad.Trans.List'
To import instances alone, use: import Control.Monad.Trans.List()

Control/Monad/Trans/Resource.hs:78:1: Warning:
The import of Control.Monad.Trans.Maybe' is redundant except perhaps to import instances fromControl.Monad.Trans.Maybe'
To import instances alone, use: import Control.Monad.Trans.Maybe()

Control/Monad/Trans/Resource.hs:79:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

Control/Monad/Trans/Resource.hs:79:1: Warning:
The import of Control.Monad.Trans.Error' is redundant except perhaps to import instances fromControl.Monad.Trans.Error'
To import instances alone, use: import Control.Monad.Trans.Error()

Control/Monad/Trans/Resource.hs:80:1: Warning:
The import of Control.Monad.Trans.Reader' is redundant except perhaps to import instances fromControl.Monad.Trans.Reader'
To import instances alone, use: import Control.Monad.Trans.Reader()

Control/Monad/Trans/Resource.hs:81:1: Warning:
The import of Control.Monad.Trans.State' is redundant except perhaps to import instances fromControl.Monad.Trans.State'
To import instances alone, use: import Control.Monad.Trans.State()

Control/Monad/Trans/Resource.hs:82:1: Warning:
The import of Control.Monad.Trans.Writer' is redundant except perhaps to import instances fromControl.Monad.Trans.Writer'
To import instances alone, use: import Control.Monad.Trans.Writer()

Control/Monad/Trans/Resource.hs:84:1: Warning:
The import of Control.Monad.Trans.RWS' is redundant except perhaps to import instances fromControl.Monad.Trans.RWS'
To import instances alone, use: import Control.Monad.Trans.RWS()

Control/Monad/Trans/Resource.hs:86:1: Warning:
The qualified import of Control.Monad.Trans.RWS.Strict' is redundant except perhaps to import instances fromControl.Monad.Trans.RWS.Strict'
To import instances alone, use: import Control.Monad.Trans.RWS.Strict()

Control/Monad/Trans/Resource.hs:87:1: Warning:
The qualified import of Control.Monad.Trans.State.Strict' is redundant except perhaps to import instances fromControl.Monad.Trans.State.Strict'
To import instances alone, use: import Control.Monad.Trans.State.Strict()

Control/Monad/Trans/Resource.hs:88:1: Warning:
The qualified import of Control.Monad.Trans.Writer.Strict' is redundant except perhaps to import instances fromControl.Monad.Trans.Writer.Strict'
To import instances alone, use: import Control.Monad.Trans.Writer.Strict()

Control/Monad/Trans/Resource.hs:91:1: Warning:
The import of Control.Monad.ST' is redundant except perhaps to import instances fromControl.Monad.ST'
To import instances alone, use: import Control.Monad.ST()

Control/Monad/Trans/Resource.hs:93:1: Warning:
The qualified import of Control.Monad.ST.Lazy' is redundant except perhaps to import instances fromControl.Monad.ST.Lazy'
To import instances alone, use: import Control.Monad.ST.Lazy()

Control/Monad/Trans/Resource.hs:96:1: Warning:
The import of Control.Monad.Morph' is redundant except perhaps to import instances fromControl.Monad.Morph'
To import instances alone, use: import Control.Monad.Morph()

Control/Monad/Trans/Resource.hs:222:1: Warning:
Defined but not used: `finally'
[4 of 4] Compiling Data.Acquire ( Data/Acquire.hs, dist/build/Data/Acquire.o )

Data/Acquire.hs:14:1: Warning:
The import of Control.Monad.Trans.Resource' is redundant except perhaps to import instances fromControl.Monad.Trans.Resource'
To import instances alone, use: import Control.Monad.Trans.Resource()

Data/Acquire.hs:16:1: Warning:
The import of Control.Applicative' is redundant except perhaps to import instances fromControl.Applicative'
To import instances alone, use: import Control.Applicative()

Data/Acquire.hs:17:1: Warning:
The import of Control.Monad.Base' is redundant except perhaps to import instances fromControl.Monad.Base'
To import instances alone, use: import Control.Monad.Base()

Data/Acquire.hs:19:1: Warning:
The import of Control.Monad.Trans.Control' is redundant except perhaps to import instances fromControl.Monad.Trans.Control'
To import instances alone, use: import Control.Monad.Trans.Control()

Data/Acquire.hs:21:1: Warning:
The import of Data.Typeable' is redundant except perhaps to import instances fromData.Typeable'
To import instances alone, use: import Data.Typeable()

Data/Acquire.hs:22:1: Warning:
The import of Control.Monad' is redundant except perhaps to import instances fromControl.Monad'
To import instances alone, use: import Control.Monad()
In-place registering resourcet-1.1.4.1...
Installing library in
/home/opensourcegeek/.cabal/lib/resourcet-1.1.4.1/ghc-7.6.3
Registering resourcet-1.1.4.1...
Installed resourcet-1.1.4.1
Downloading conduit-1.2.4...
Configuring conduit-1.2.4...
Building conduit-1.2.4...
Preprocessing library conduit-1.2.4...
[1 of 8] Compiling Data.Conduit.Internal.Pipe ( Data/Conduit/Internal/Pipe.hs, dist/build/Data/Conduit/Internal/Pipe.o )
[2 of 8] Compiling Data.Conduit.Internal.Conduit ( Data/Conduit/Internal/Conduit.hs, dist/build/Data/Conduit/Internal/Conduit.o )

Data/Conduit/Internal/Conduit.hs:86:1: Warning:
Module Prelude' does not exportcatch'
[3 of 8] Compiling Data.Conduit.Internal.Fusion ( Data/Conduit/Internal/Fusion.hs, dist/build/Data/Conduit/Internal/Fusion.o )
[4 of 8] Compiling Data.Conduit.Internal.List.Stream ( Data/Conduit/Internal/List/Stream.hs, dist/build/Data/Conduit/Internal/List/Stream.o )
[5 of 8] Compiling Data.Conduit.Internal ( Data/Conduit/Internal.hs, dist/build/Data/Conduit/Internal.o )
[6 of 8] Compiling Data.Conduit ( Data/Conduit.hs, dist/build/Data/Conduit.o )
[7 of 8] Compiling Data.Conduit.List ( Data/Conduit/List.hs, dist/build/Data/Conduit/List.o )
[8 of 8] Compiling Data.Conduit.Lift ( Data/Conduit/Lift.hs, dist/build/Data/Conduit/Lift.o )

Data/Conduit/Lift.hs:77:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

Data/Conduit/Lift.hs:128:26: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:128:56: Warning:
In the use of type constructor or class `E.Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:130:29: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:133:12: Warning:
In the use of data constructor `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:139:16: Warning:
In the use of type constructor or class `E.Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:140:20: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:145:25: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:150:56: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:159:16: Warning:
In the use of type constructor or class `E.Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:160:20: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:161:29: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:162:23: Warning:
In the use of type constructor or class `E.ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lift.hs:167:32: Warning:
In the use of `E.runErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
In-place registering conduit-1.2.4...
Installing library in /home/opensourcegeek/.cabal/lib/conduit-1.2.4/ghc-7.6.3
Registering conduit-1.2.4...
Installed conduit-1.2.4
Downloading conduit-extra-1.1.7.1...
Configuring conduit-extra-1.1.7.1...
Building conduit-extra-1.1.7.1...
Preprocessing library conduit-extra-1.1.7.1...
[ 1 of 12] Compiling Data.Conduit.Zlib ( Data/Conduit/Zlib.hs, dist/build/Data/Conduit/Zlib.o )
[ 2 of 12] Compiling Data.Conduit.Text ( Data/Conduit/Text.hs, dist/build/Data/Conduit/Text.o )

Data/Conduit/Text.hs:63:7: Warning:
Defined but not used: `codecName'

Data/Conduit/Text.hs:152:21: Warning: Defined but not used: `name'
[ 3 of 12] Compiling Data.Conduit.Network.UDP ( Data/Conduit/Network/UDP.hs, dist/build/Data/Conduit/Network/UDP.o )

Data/Conduit/Network/UDP.hs:16:1: Warning:
The import of SockAddr, AddrInfo' from moduleNetwork.Socket' is redundant

Data/Conduit/Network/UDP.hs:17:1: Warning:
The qualified import of Network.Socket' is redundant except perhaps to import instances fromNetwork.Socket'
To import instances alone, use: import Network.Socket()
[ 4 of 12] Compiling Data.Conduit.Lazy ( Data/Conduit/Lazy.hs, dist/build/Data/Conduit/Lazy.o )

Data/Conduit/Lazy.hs:23:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

Data/Conduit/Lazy.hs:99:11: Warning:
In the use of type constructor or class `Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Data/Conduit/Lazy.hs:99:52: Warning:
In the use of type constructor or class `ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
[ 5 of 12] Compiling Data.Conduit.Filesystem ( Data/Conduit/Filesystem.hs, dist/build/Data/Conduit/Filesystem.o )
[ 6 of 12] Compiling Data.Conduit.ByteString.Builder ( Data/Conduit/ByteString/Builder.hs, dist/build/Data/Conduit/ByteString/Builder.o )
[ 7 of 12] Compiling Data.Conduit.Blaze ( Data/Conduit/Blaze.hs, dist/build/Data/Conduit/Blaze.o )
[ 8 of 12] Compiling Data.Conduit.Binary ( Data/Conduit/Binary.hs, dist/build/Data/Conduit/Binary.o )
[ 9 of 12] Compiling Data.Conduit.Process ( Data/Conduit/Process.hs, dist/build/Data/Conduit/Process.o )
[10 of 12] Compiling Data.Conduit.Attoparsec ( Data/Conduit/Attoparsec.hs, dist/build/Data/Conduit/Attoparsec.o )
[11 of 12] Compiling Data.Conduit.Network ( Data/Conduit/Network.hs, dist/build/Data/Conduit/Network.o )

Data/Conduit/Network.hs:41:1: Warning:
Module Prelude' does not exportcatch'

Data/Conduit/Network.hs:43:1: Warning:
The qualified import of Network.Socket' is redundant except perhaps to import instances fromNetwork.Socket'
To import instances alone, use: import Network.Socket()

Data/Conduit/Network.hs:45:1: Warning:
The import of recv' from moduleNetwork.Socket.ByteString' is redundant

Data/Conduit/Network.hs:49:1: Warning:
The qualified import of Data.ByteString.Char8' is redundant except perhaps to import instances fromData.ByteString.Char8'
To import instances alone, use: import Data.ByteString.Char8()

Data/Conduit/Network.hs:51:1: Warning:
The import of Control.Exception' is redundant except perhaps to import instances fromControl.Exception'
To import instances alone, use: import Control.Exception()

Data/Conduit/Network.hs:84:1: Warning:
Top-level binding with no type signature:
serverSettings :: Int -> SN.HostPreference -> SN.ServerSettings

Data/Conduit/Network.hs:85:1: Warning:
Top-level binding with no type signature:
clientSettings :: Int -> ByteString -> SN.ClientSettings
[12 of 12] Compiling Data.Conduit.Network.Unix ( Data/Conduit/Network/Unix.hs, dist/build/Data/Conduit/Network/Unix.o )

Data/Conduit/Network/Unix.hs:29:1: Warning:
The import of Data.Conduit' is redundant except perhaps to import instances fromData.Conduit'
To import instances alone, use: import Data.Conduit()

Data/Conduit/Network/Unix.hs:30:1: Warning:
The import of Network.Socket' is redundant except perhaps to import instances fromNetwork.Socket'
To import instances alone, use: import Network.Socket()

Data/Conduit/Network/Unix.hs:31:1: Warning:
The qualified import of Network.Socket' is redundant except perhaps to import instances fromNetwork.Socket'
To import instances alone, use: import Network.Socket()

Data/Conduit/Network/Unix.hs:34:1: Warning:
The import of Control.Monad.IO.Class' is redundant except perhaps to import instances fromControl.Monad.IO.Class'
To import instances alone, use: import Control.Monad.IO.Class()

Data/Conduit/Network/Unix.hs:35:1: Warning:
The import of Control.Exception' is redundant except perhaps to import instances fromControl.Exception'
To import instances alone, use: import Control.Exception()

Data/Conduit/Network/Unix.hs:37:1: Warning:
The import of Control.Monad' is redundant except perhaps to import instances fromControl.Monad'
To import instances alone, use: import Control.Monad()

Data/Conduit/Network/Unix.hs:38:1: Warning:
The import of Control.Monad.Trans.Control' is redundant except perhaps to import instances fromControl.Monad.Trans.Control'
To import instances alone, use: import Control.Monad.Trans.Control()

Data/Conduit/Network/Unix.hs:39:1: Warning:
The import of Control.Concurrent' is redundant except perhaps to import instances fromControl.Concurrent'
To import instances alone, use: import Control.Concurrent()

Data/Conduit/Network/Unix.hs:40:1: Warning:
The import of System.Directory' is redundant except perhaps to import instances fromSystem.Directory'
To import instances alone, use: import System.Directory()

Data/Conduit/Network/Unix.hs:41:1: Warning:
The import of System.IO.Error' is redundant except perhaps to import instances fromSystem.IO.Error'
To import instances alone, use: import System.IO.Error()

Data/Conduit/Network/Unix.hs:42:1: Warning:
The import of Control.Monad.Trans.Resource' is redundant except perhaps to import instances fromControl.Monad.Trans.Resource'
To import instances alone, use: import Control.Monad.Trans.Resource()

Data/Conduit/Network/Unix.hs:44:1: Warning:
Top-level binding with no type signature:
clientSettings :: FilePath -> SN.ClientSettingsUnix

Data/Conduit/Network/Unix.hs:45:1: Warning:
Top-level binding with no type signature:
serverSettings :: FilePath -> SN.ServerSettingsUnix
In-place registering conduit-extra-1.1.7.1...
Installing library in
/home/opensourcegeek/.cabal/lib/conduit-extra-1.1.7.1/ghc-7.6.3
Registering conduit-extra-1.1.7.1...
Installed conduit-extra-1.1.7.1
Downloading monad-logger-0.3.13.1...
Configuring monad-logger-0.3.13.1...
Building monad-logger-0.3.13.1...
Preprocessing library monad-logger-0.3.13.1...
[1 of 1] Compiling Control.Monad.Logger ( Control/Monad/Logger.hs, dist/build/Control/Monad/Logger.o )

Control/Monad/Logger.hs:105:1: Warning:
Module `Control.Monad.Trans.Error' is deprecated:
Use Control.Monad.Trans.Except instead

Control/Monad/Logger.hs:205:26: Warning:
In the use of type constructor or class `Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Control/Monad/Logger.hs:205:51: Warning:
In the use of type constructor or class `ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Control/Monad/Logger.hs:223:28: Warning:
In the use of type constructor or class `Error'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"

Control/Monad/Logger.hs:223:55: Warning:
In the use of type constructor or class `ErrorT'
(imported from Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
In-place registering monad-logger-0.3.13.1...
Installing library in
/home/opensourcegeek/.cabal/lib/monad-logger-0.3.13.1/ghc-7.6.3
Registering monad-logger-0.3.13.1...
Installed monad-logger-0.3.13.1
Downloading groundhog-0.7.0.2...
Configuring groundhog-0.7.0.2...
Building groundhog-0.7.0.2...
Preprocessing library groundhog-0.7.0.2...

Database/Groundhog/Instances.hs:27:18:
Could not find module Data.Attoparsec.Number' It is a member of the hidden packageattoparsec-0.10.4.0'.
Perhaps you need to add `attoparsec' to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
Failed to install groundhog-0.7.0.2
cabal: Error: some packages failed to install:
groundhog-0.7.0.2 failed during the building phase. The exception was:
ExitFailure 1

Add enumeration support to `mkPersisit`.

Attempting to compile this with ghc --make causes an error. It would be nice if this worked.

module GroundhogTest where

import qualified Database.Groundhog.TH as TH
import qualified Database.Groundhog.Sqlite as S

data DataEnum = Foo | Bar | Baz
  deriving (Show, Eq)

data ParentType = P Int DataEnum
  deriving (Show, Eq)

TH.mkPersist TH.defaultCodegenConfig [TH.groundhog|
- entity: ParentType
- entity: DataEnum
|]

Specifying primary key

I like groundhog feature to be able to omit automatic primary key.

In addition to that, is it possible (or planned) to specify primary key on arbitrary column?

uuid AutoKey?

I like how TH-derived automatically incremented int keys free me from having to put any kind of primary key directly in my type, since often the key has nothing to do with my business logic, and sometimes I don't know what the key is until the database tells me.

Is it possible to get the same functionality but with V4 UUID's (if I commit myself to Postgres)? Or would I need to have an actual UUID field in my Haskell record if I want a UUID key?

Easy way to impose global db naming convention

In Postgresql, field and table names with upper case letters are a pain to deal with. It would be really nice if there was a way to do a global transformation on db names so that I could have groundhog use names like foo_bar instead of fooBar.

unable to build groundhog-th 0.7.0 with ghc 7.10 RC3 (TH changes)

I get the following error:

Building groundhog-th-0.7.0...
Preprocessing library groundhog-th-0.7.0...
[1 of 3] Compiling Database.Groundhog.TH.Settings ( Database/Groundhog/TH/Settings.hs, dist/dist-sandbox-db28d3ba/build/Database/Groundhog/TH/Settings.o )
[2 of 3] Compiling Database.Groundhog.TH.CodeGen ( Database/Groundhog/TH/CodeGen.hs, dist/dist-sandbox-db28d3ba/build/Database/Groundhog/TH/CodeGen.o )

Database/Groundhog/TH/CodeGen.hs:371:38:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:389:46:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:408:50:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:422:29:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:429:28:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:455:42:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:455:76:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:721:32:
    Not in scope: data constructor ‘ClassP’
    Perhaps you meant one of these:
      ‘ClassD’ (imported from Language.Haskell.TH),
      ‘ClassI’ (imported from Language.Haskell.TH),
      variable ‘classP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:737:40:
    Not in scope: data constructor ‘ClassP’
    Perhaps you meant one of these:
      ‘ClassD’ (imported from Language.Haskell.TH),
      ‘ClassI’ (imported from Language.Haskell.TH),
      variable ‘classP’ (imported from Language.Haskell.TH)

This is with

% ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.0.20150316

Add NeverNull instances for tuples

Today I discovered that there are no NeverNull instances for tuples. It would be nice to have something like this if possible:

instance (NeverNull a, NeverNull b) => NeverNull (a,b)

(Postgres) Unique check during insertByAll doesn't work for Maybe (nullable) fields

To be sure, this is a Postgresql quirk, but I wonder if we could get groundhog to do the intuitive thing. Others have asked about this weird Postgres behavior, for example here:

http://stackoverflow.com/questions/5834471/why-does-postgres-handle-nulls-inconsistently-where-unique-constraints-are-invol

If a type has a Maybe field as part of a unique constraint, groundhog-postgresql uses =null test when the field is a Nothing. This leads to incorrect/misleading results. As an example:

SELECT "id" FROM "category" WHERE "cat_name"='Category' AND "cat_parent"=null AND "cat_source"=0;

which always returns the empty set even if in reality there are records that match in the table. This is due to the =null portion.

If it were, instead:

SELECT "id" FROM "category" WHERE "cat_name"='Category' AND "cat_parent" is null AND "cat_source"=0;

Then we get all the previous entries that match in the database.

The is null appears to be a way to get postgres to actually look at the null field.

This lead to an issue where lots of redundant rows would be inserted during development. It might be nice to solve it so other unsuspecting devs don't fall into the same trap.

Build issues with ghc 8.0.0 RC3

I bumped the groundhog transformers constraint from < 0.5 to < 0.6 in groundhog.cabal (as well as bumping the version to 0.7.0.4) and tried to build 6d2f681 with 8.0.0 RC3 - i.e.

% ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.0.0.20160411

and got the following errors:

% cabal install groundhog
Resolving dependencies...
Notice: installing into a sandbox located at
/home/djburke/chandraobs/groundhog/.cabal-sandbox
Configuring groundhog-0.7.0.4...
Building groundhog-0.7.0.4...
Failed to install groundhog-0.7.0.4
Build log ( /home/djburke/chandraobs/groundhog/.cabal-sandbox/logs/groundhog-0.7.0.4.log ):
cabal: Entering directory '/home/djburke/chandraobs/groundhog/groundhog'
Configuring groundhog-0.7.0.4...
Building groundhog-0.7.0.4...
Preprocessing library groundhog-0.7.0.4...

Database/Groundhog/Expression.hs:1:134: warning:
    -XOverlappingInstances is deprecated: instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS

Database/Groundhog/Instances.hs:1:57: warning:
    -XOverlappingInstances is deprecated: instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS
[1 of 9] Compiling Database.Groundhog.Core ( Database/Groundhog/Core.hs, dist/dist-sandbox-f9efc5f2/build/Database/Groundhog/Core.o )

Database/Groundhog/Core.hs:178:1: error:
    • Potential superclass cycle for ‘Projection'’
        one of whose superclass constraints is headed by a type family:
          ‘ProjectionDb p db’
      Use UndecidableSuperClasses to accept this
    • In the class declaration for ‘Projection'’
cabal: Leaving directory '/home/djburke/chandraobs/groundhog/groundhog'
cabal: Error: some packages failed to install:
groundhog-0.7.0.4 failed during the building phase. The exception was:
ExitFailure 1

Revamp lists implementation

Description

Consider a simple datatype

data Entity {
somevalue :: String,
somelist :: [String]
}

Current schema

Entity references list table. List values table references list table. Triggers remove list row from the list row on entity update/delete.

CREATE TABLE entity (id INTEGER, somevalue VARCHAR, somelist INTEGER);
CREATE TABLE List#String (id INTEGER PRIMARY KEY);
CREATE TABLE List#String#values (id INTEGER REFERENCES List#String(id), ord INTEGER, value VARCHAR);
CREATE TRIGGER ... ON DELETE ...
CREATE TRIGGER ... ON UPDATE ...

Proposed schema

List table is eliminated. Each list has its own table that references entity id or one of its unique keys.

CREATE TABLE entity (id INTEGER, somevalue VARCHAR);
CREATE TABLE entity#somelist (key INTEGER REFERENCES entity (id) ON DELETE CASCADE, ord INTEGER, value VARCHAR);

This opens the way for maps and other complex data structures.

Questions

How can the new schema help solving N+1 query problem?
What is the behavior if the list is inside of an embedded datatype?

Roadmap

The newly added converters may help with this if they do side effects and take entity and its autokey as arguments. A simple way to distinguish between pure and non-pure converter in compile time (TH generation) would be to create two newtypes.

To avoid breaking changes, Groundhog needs to support both schemas for a while. The new schema will be used only if converter is specified. Also, there needs to be a way to do automatic migration from the old schema.

Build failure with GHC 7.10

Unpacking to groundhog-th-0.7.0/
Resolving dependencies...
Configuring groundhog-th-0.7.0...
Building groundhog-th-0.7.0...
Preprocessing library groundhog-th-0.7.0...
[1 of 3] Compiling Database.Groundhog.TH.Settings ( Database/Groundhog/TH/Settings.hs, dist/build/Database/Groundhog/TH/Settings.o )
[2 of 3] Compiling Database.Groundhog.TH.CodeGen ( Database/Groundhog/TH/CodeGen.hs, dist/build/Database/Groundhog/TH/CodeGen.o )

Database/Groundhog/TH/CodeGen.hs:371:38:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:389:46:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:408:50:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:422:29:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:429:28:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:455:42:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:455:76:
    Not in scope: data constructor ‘EqualP’
    Perhaps you meant variable ‘equalP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:721:32:
    Not in scope: data constructor ‘ClassP’
    Perhaps you meant one of these:
      ‘ClassD’ (imported from Language.Haskell.TH),
      ‘ClassI’ (imported from Language.Haskell.TH),
      variable ‘classP’ (imported from Language.Haskell.TH)

Database/Groundhog/TH/CodeGen.hs:737:40:
    Not in scope: data constructor ‘ClassP’
    Perhaps you meant one of these:
      ‘ClassD’ (imported from Language.Haskell.TH),
      ‘ClassI’ (imported from Language.Haskell.TH),
      variable ‘classP’ (imported from Language.Haskell.TH)

Add conversionFunction field to field config

Please add a 'conversionFunction' field which allows the end-developer to specify an isomorphism between the type of the field in the entity and a type which has an existing PersistField instance. This should also work if the type is [A] where A has a PersistField instance.

insertByAll issues a mal-formatted query to PostgreSQL backend while checking for duplicates

Given these unique keys:

        - name: ProdUniqCode
          fields: [prodSource, prodWebCode]
          type: constraint
        - name: ProdIndexImg
          fields: [prodImage]
          type: index

and a computation like:

insertByAll (Product ...[all the fields of the Product type]...)

We are seeing, rather non-deterministically, the frequent:

Exception raised: FormatError {fmtMessage = "3 '?' characters, but 6 parameters", fmtQuery = "SELECT \"id\" FROM \"product\" WHERE \"prod_source\"=? AND \"prod_web_code\"=? OR \"prod_image\"=?", fmtParams = ["5","157560279","null","5","157560279","null"]}. 

It looks like the framework is checking for previous entries based on the keys defined, but somehow messing up the parameter list.

Record fields with underscores give TH machinery trouble

The below yields a large error complaining about:

    Illegal data constructor"
<- " name: `_pgHostField'
    When splicing a TH declaration:
      instance Database.Groundhog.Core.PersistEntity Compute.Backends.PGCommon.PGConfig
    where data Database.Groundhog.Core.Key Compute.Backends.PGCommon.PGConfig

Example code:

data PGConfig = PGConfig
    { _pgHost     :: Text
    , _pgPort     :: Int
    , _pgUser     :: Text
    , _pgPass     :: Text
    , _pgDatabase :: Text
    , _pgSchema   :: Text
    , _pgSSL      :: SSLMode
    } deriving (Eq,Show,Generic)
- entity: PGConfig
  dbName: xxxxx
  constructors:
    - name: PGConfig

Difficulty creating a `ConnectionManager` instance

With new type for withConn :: (conn -> m a) -> conn -> m a, I'm confused about how to write a ConnectionManager instance for snap that defers to the ConnectionManager instance for Pool Postgresql.

What I have so far:

data App = App { _heist :: Snaplet (Heist App), _db :: Pool Postgresql }

instance ConnectionManager App where
  withConn f app@(App _ pg) = do
    pgConn <- extractConnection return pg
    let g = _ f
    withConn g pgConn

It seems I need to somehow create a function g :: Postgresql -> m a out of the function f :: App -> m a if I want to use Postgresql's ConnectionManager instance, but it seems impossible to generate such a function.

Maybe I'm going down the wrong route? The ultimate goal is just to provide a convenience function for running groundhog queries from within my Handler App App monad.

Postgresql AutoKey types: int4 vs. int8

I've noticed that the default 'id' columns in Postgres are assigned int4 as their type while DefaultKey MyType references get an int8. Since these two are really referring to the same field, shouldn't they have the same type?

int8 sounds to me like the write choice in both to support large number of records.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.