On Thu, Jul 30, 2015 at 05:18:00PM +0300, Nikita Karetnikov wrote:
> I have to admit the current mechanism implementation makes me uneasy.
> Everything is mutable and some functions, like underfundedPatrons, do
> too much, making it hard to test and even follow.

Incidentally, where's what I would like underfundedPatrons to "look"
like:

    select * from (
        select pl.user
            , balance - (outlay.tot - (funded_shares * share_value)) as avail
            , pr.id as project
            , pr.share_value
            , pl.funded_shares
            , ac.id account
        from pledge pl
        join "user" u on pl.user = u.id
        join account ac on ac.id = u.account
        join project pr on pl.project = pr.id
        join (
            select u.id as user, sum(funded_shares * share_value) as tot
            from pledge pl
            join project pr on pl.project = pr.id
            join "user" u on pl.user = u.id
            join account ac on u.account = ac.id
            group by u.id
        ) outlay on outlay.user = u.id
    ) as q
    where avail < share_value * funded_shares
    order by q.user

This is a "pure" function of the underlying tables (except perhaps for
the use of share_value, which is strictly speaking non-normalized and
thus spooky). It could be easily tested in isolation. The subquery "q"
could be turned into a database view and thus encapsulated.

The problem is I don't know how to interface this query with the
Haskell code, yet. I would very much like to. Thanks to years of
experience, I can write queries like this in a matter of minutes, but
it still takes me hours to hammer them into the persistent/esqueleto
mold.

I also want compile time guarantees (types). There's a un(i)typed
multiplication in there between funded_shares and share_value that
should be a compile-time error. The sum itself is another potential
type error, since in general it could return null (Nothing) — although
I think it never will in this case. I should also be able to ensure
that every use of this query expects the correct result types.

So... any thoughts? For now I think I'll just crash through some more
persistent and esqueleto to end up with the equivalent data. If anyone
wants to look into this, though, I'm pretty sure you'd get good
support from upstream.

-*-*-*- holy crap -*-*-*-

This is what I want:

https://github.com/tomjaguarpaw/haskell-opaleye

Using Opaleye would probably require some deep restructuring of the
Snowdrift Model code, so I'll hold off for now. I do hope we can move
towards using it, though.

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Dev mailing list
Dev@lists.snowdrift.coop
https://lists.snowdrift.coop/mailman/listinfo/dev

Reply via email to