Backend compatible#886
Backend compatible#886parsonsmatt merged 28 commits intoyesodweb:vlix/backend-compatiblefrom Vlix:backend-compatible
Conversation
… and new Filter operators (@>.) and (<@.)
* Upgraded the randomValues function in DataTestTypes.hs to actually have random values everytime * small OCD
…work because of it
|
|
If someone can check with whatever uses it, that'd be great, because I have no idea how they'd be used looking at this library alone. |
|
@akurilin I suggest building this against your org repo. I can't do it for you. I remember y'all using those types too but I have no idea where things are at now. |
|
I'm gonna write some tests for the feature. |
|
Ok, well if the Read/Write types have a function, that still leaves the Seeing as this change does shift almost all functionality to |
|
The I'd love it if the new changes were mostly "drop in." I think changing the functions to return a concrete |
|
I think it may be a good idea to deprecate the |
| runSqlite :: (MonadUnliftIO m) | ||
| => Text -- ^ connection string | ||
| -> ReaderT backend (NoLoggingT (ResourceT m)) a -- ^ database action | ||
| -> ReaderT SqlBackend (NoLoggingT (ResourceT m)) a -- ^ database action |
There was a problem hiding this comment.
This is another thing that should be easy to generalize on our side.
There was a problem hiding this comment.
Well, no, actually 😛
The entire point it that the backend/SqlBackend here, is from the open' function, which creates the SqlBackend in the withSqliteConn. Making a SqlBackend into a BackendCompatible SqlBackend backend => backend would imply creating a backend from a SqlBackend. That being annoying and undesirable was the entire point.
Remember, this is Sqlite specific, so it's gonna have to work with a SqlBackend.
The RawSqlite PR should work now afaict, though. Then the SqlBackend here would turn into a RawSqlite SqlBackend which is what merijn was trying to accomplish, I think.
There was a problem hiding this comment.
That's not quite right - BackendCompatible SqlBackend backend implies that you can create a SqlBackend from a backend. runSqlite would be able to run an action that uses SqlBackend, or SqlReadBackend, or SqlFor SomeDb, or RawSqlite SqlBackend (provided that was given an instance BackendCompatible SqlBackend (RawSqlite SqlBackend)).
The problem with IsSqlBackend is that it requires an isomorphism - that you can go from a SqlBackend to your type. RawSqlite SqlBackend has more than a mere SqlBackend, so there's no SqlBackend -> RawSqlite SqlBackend you can use.
There was a problem hiding this comment.
We can try the polymorphic BackendCompatbile SqlBackend backend => backend stuff and if it presents problems with the raw SQLite stuff then we can revert those functions to concrete types.
It's not a deal breaker either way - requiring ReaderT SqlBackend ... just means that library users call local SqlReadBackend to map the types how they want instead of the library doing it automatically.
There was a problem hiding this comment.
I'll try it one more time, maybe I'm just derping with the type system.
| -- Returns also the identifiers. | ||
| selectSource | ||
| :: (PersistQueryRead (BaseBackend backend), MonadResource m, PersistEntity record, PersistEntityBackend record ~ BaseBackend (BaseBackend backend), MonadReader backend m, HasPersistBackend backend) | ||
| :: (PersistQueryRead backend, MonadResource m, PersistEntity record, PersistRecordBackend record backend, MonadReader backend m) |
There was a problem hiding this comment.
This signature is so much nicer ❤️
|
|
||
| createSqlPool | ||
| :: (MonadLogger m, MonadUnliftIO m, IsSqlBackend backend) | ||
| :: (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) |
There was a problem hiding this comment.
Hm, if these functions can return a BackendCompatible SqlBackend backend => backend then shouldn't the other {with,create}{Postgresql,MySQL,etc}Pool functions also be able to create that?
There was a problem hiding this comment.
Well, no, since those functions are actual implementations, they will create SqlBackends.
The only thing I can think of that wouldn't just imply using IsSqlBackend, would be an extra argument somewhere in which the user of the function can give the following function which will be called before creating the Pool:
BackendCompatible SqlBackend backend => SqlBackend -> backend
Maybe with a MonadIO m so they can use IO to create their own backend.
|
I added some tests in #887 though they're not super complete. |
|
Ok, so here's the dealio: This is the chain: wrapConnectionInfo :: SqliteConnectionInfo -> Sqlite.Connection -> LogFunc -> IO SqlBackend
wrapConnectionInfo = {the entire SqlBackend is constructed here}
open' :: SqliteConnectionInfo -> LogFunc -> IO SqlBackend
open' connInfo logFunc = do
conn <- Sqlite.open $ _sqlConnectionStr connInfo
wrapConnectionInfo connInfo conn logFunc `E.onException` Sqlite.close conn
withSqliteConnInfo :: (MonadUnliftIO m, MonadLogger m)
=> SqliteConnectionInfo -> (SqlBackend -> m a) -> m a
withSqliteConnInfo = withSqlConn . open'
withSqlConn
:: (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend)
=> (LogFunc -> IO backend) -> (backend -> m a) -> m a
withSqlConn open f = do
logFunc <- askLogFunc
withRunInIO $ \run -> bracket
(open logFunc)
close'
(run . f)
runSqlite :: (MonadUnliftIO m)
=> Text -- ^ connection string
-> ReaderT SqlBackend (NoLoggingT (ResourceT m)) a -- ^ database action
-> m a
runSqlite connstr action = runResourceT . runNoLoggingT $
withSqliteConn connstr $ runSqlConn action
|
|
Okay, let's land this PR, then get the SQLite one working, and I'll give these |
|
I tried to test on my work codebase but I need a new version of EDIT: This builds fine on the work codebase, however, we don't use SqlReadT or SqlWriteT anywhere, so not a great point of comparison. I'll try it on esqueleto too, which does use it. Esqueleto works with this PR. |
|
@Vlix There are some merge conflicts from your other PR. Let's get those resolved and merge this in. Freckle and folks can test on |
Agreed and I'm very happy the (more flexible) @Vlix once this PR is merged I'll try and make some time to revisit the SQLite bits you mentioned, since those needed changing in my other PR and since it's grossly out of date by now I need to revisit it anyway. |
|
I'm going to get this PR finished up |
I've factored out what I've found to be redundant constraints in some SQL functions.
Most notably all instances of
IsSqlBackendhave been replaced or removed andBackendCompatible SqlBackendhas been integrated where possible.I've noticed a ton of redundant (at least seemingly) classes/types/etc.
After this refactor at least the following aren't noticeably used anywhere:
If anyone can look this over, to see if I didn't interfere with the API, or some guarantee that's lost by fiddling with constraints, that'd be great.