-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable value-level codecs #61
Conversation
@@ -46,7 +46,7 @@ in upstream | |||
, "validation" | |||
] | |||
, repo = "https://github.com/jordanmartinez/purescript-postgresql-client.git" | |||
, version = "updateTov0.14.1" | |||
, version = "exposeUnsafeQuery" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is using my fork temporarily.
@@ -47,5 +47,5 @@ You can edit this file as you like. | |||
, "variant" | |||
] | |||
, packages = ./packages.dhall | |||
, sources = [ "src/**/*.purs", "test/**/*.purs", "guide/src/**/*.purs" ] | |||
, sources = [ "src/**/*.purs" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be reverted before a final PR is merged.
→ FullQuery B { | i } | ||
→ (Array Foreign -> Either String { | o }) | ||
→ Aff (Either PGError (Array { | o })) | ||
query' conn q decodeRow = runSelda conn $ Selda.PG.query' q decodeRow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eta-reducing these produces compiler errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean? there's $
so the term cannot be eta-reduced
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I was thinking query' conn = runSelda conn <<< Selda.PG.query'
. It's been so long since I worked on this, I'm not sure anymore.
, query1 | ||
, query1' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The appended '
indicates value-level codecs are used. I think a different suffix should be used that's clearer (e.g. V
for value).
import Type.Proxy (Proxy) | ||
|
||
class GenericQuery ∷ ∀ k. k → (Type → Type) → Row Type → Row Type → Constraint | ||
class Monad m <= GenericQuery b m i o | i → o, b → m where | ||
genericQuery | ||
∷ Proxy b | ||
→ FullQuery b { | i } | ||
→ (Array Foreign -> Either String { | o }) | ||
→ m (Array { | o }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the addition of this new argument, I'm not sure what the order of the arguments should be.
genericQuery | ||
∷ Proxy b | ||
→ FullQuery b { | i } | ||
→ (decodeInput -> decodeOutput { | o }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary because different backends have different ways of decoding things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these differences are not that serious - the common input could be just Foreign
which is convertible to Array Foreign
when needed. Similarly the error monad decodeOutput
which could be just m
Ok. Pretty sure this code works, but testing it is going to be it's own major pain. I essentially need to change |
I couldn't figure out how to update the tests, so that a test is defined in only one location and can tested against multiple backends. While I get why you're doing this, I think it's a better tradeoff to define tests separately for each backend. I'd like to proceed in that direction (i.e. duplicating |
I'd really want to keep |
Ok. I've removed the last commit that started to duplicate Common across each backend. |
Nice work @JordanMartinez , I'm not yet ready to push this any further, but I have some insights.
primGenericQuery ∷
∀ s a i.
GetCols i ⇒
String → -- query parameter placeholder, e.g. '$' for pg, and '?' for sqlite
Int → -- first query parameter index, usually `1`
-- both of these parameters determine how we generate query
-- parameter names, e.g. '$1', '$2', ... for pg
(String → Array Foreign → a) →
FullQuery s { | i } →
a
primGenericQuery ph i exec q = do
-- transform Query AST `q` into a query string and query parameters
let { strQuery, params } = showM ph i $ showQuery q
-- execute the query with the parameters
exec strQuery params
pgPrimGenericQuery ∷
∀ s a i m.
GetCols i ⇒ -- needed by query string generation
MonadSeldaPG m ⇒ -- PG specific monad constraints
(Array Foreign → m a) → -- generic decoder, errors are handled by monad `m`
FullQuery s { | i } → -- query AST
m (Array a) -- result rows of output records, record type `{ | o }` is determined by `i` via the type-function
pgPrimGenericQuery decodeRow = primGenericQuery "$" 1 exec
where
exec strQuery params = do
conn ← ask
errOrResult ← liftAff $ PostgreSQL.unsafeQuery conn strQuery params
result ← either throwError pure errOrResult
traverse decodeRow result.rows
pgGenericQuery ∷
∀ s o i m.
GetCols i ⇒
MapR UnCol_ i o ⇒ -- type-level function that maps over `{ | i }`
-- and removes `Col s` from each record member
-- thus `o` is now determined by the input `i`
MonadSeldaPG m ⇒
(Array Foreign → m { | o }) →
FullQuery s { | i } →
m (Array { | o }) -- the additional constraint forces the
-- appropriate result type
pgGenericQuery = pgPrimGenericQuery |
@Kamirus I'm not likely to get to this anytime soon. But, perhaps those changes your mentioning should be done in a separate PR first before this one would be continued? |
Yes, no problem, I just wanted to write these ideas here so we don't lose them. |
I've opened #64 to track that idea. |
I don't foresee getting back to this anytime soon, so I'm going to close this PR. I won't delete my branch though. |
Fixes #60
Currently a WIP. I've opted to make
PostgreSQL
work first before working onSQLite3
.