Skip to content
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

Introduce BackendCompatible class #701

Merged

Conversation

parsonsmatt
Copy link
Collaborator

This PR introduces some machinery for generalizing the SQL backend requirement, and uses that to generalize the insertOnDuplicateKeyUpdate functions.

This PR enables support for the persistent-typed-db library which wraps the SqlBackend with a phantom type to indicate which database models are associated with. This turns mixing up your connection and models in a multi-db environment into a compile time error.

This PR is based on work done in a PR to esqueleto. I was able to get esqueleto queries working by incorporating the BackendCompatible class to Esqueleto and instantiating it appropriately in the application.

The BackendCompatible class and the HasPersistBackend / IsPersistBackend classes are very similar, and it's likely that the functionality can be merged in some way.

@parsonsmatt parsonsmatt changed the title Generalize insertOnDuplicateKeyUpdate functions to any compatible SQL backend. Introduce BackendCompatible class Sep 21, 2017
@parsonsmatt
Copy link
Collaborator Author

After the merge of #702, this PR is mostly just incorporating the BackendCompatible class into persistent. I've generalized the two MySQL-specific functions to show how this can be done to allow alternate backends.

Generally speaking, where you might have:

foo :: 
  ( PersistEntity record
  , PeristEntityBackend record ~ BaseBackend backend
  , IsSqlBackend backend
  )

this can be replaced with:

foo ::
  ( PersistEntity record,
  , PersistEntityBackend record ~ backend
  , BackendCompatible SqlBackend backend
  )

This works for SqlReadBackend because of the instance BackendCompatible SqlBackend SqlReadBackend, without needing to go through the BaseBackend type family.

Likewise, functions that are currently hardcoded to use SqlBackend can be generalized:

-- before:
asdf :: ReaderT SqlBackend m ()
asdf = pure ()

-- after:
asdf' :: BackendCompatible SqlBackend backend => ReaderT backend m ()
asdf' = withReaderT projectBackend asdf

This is, as far as I can tell, the least invasive way to add this compatibility. I can extend this PR to also generalize the other functions that hardcode SqlBackend if that's desired, or we can keep the changes smaller.

@paul-rouse
Copy link
Contributor

I don't know the persistent code well enough to be able to comment on the principles here; would someone else be able to look at it, please - perhaps @gregwebs or @MaxGabriel ? Obviously there are routine matters still to sort out, such as fixing the tests, perhaps adding some of the explanation from the comments above to the haddock documentation, updating the changelog, and bumping the version.

@MaxGabriel
Copy link
Member

Me either @paul-rouse

@paul-rouse
Copy link
Contributor

@snoyberg would you mind casting an eye over this one, please? It looks OK to me in principle, but is there anything I am missing, and what about the idea of generalising to other functions? If we are proceeding with it, I will happily review the routine things with @parsonsmatt

Copy link
Member

@snoyberg snoyberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked this over, and it looks fine to me. Thanks for the ping @paul-rouse

@paul-rouse
Copy link
Contributor

Thanks @snoyberg !

@parsonsmatt - would you be able to sort out the warning which is getting in the way of the travis tests? Also, I thought your explanation in the comment above was very clear, and it would be really good to copy most of it into the haddock. Then let's go for it!

@paul-rouse
Copy link
Contributor

@parsonsmatt - do you want to pursue this?

@parsonsmatt
Copy link
Collaborator Author

Yes, sorry, I've had a crazy past few weeks :) I'll try to get it done before the weekend's over.

@paul-rouse
Copy link
Contributor

@parsonsmatt No hurry - I just wanted to check it is still open!

@paul-rouse paul-rouse merged commit 5ad1465 into yesodweb:master Oct 22, 2017
@paul-rouse
Copy link
Contributor

Thanks!

@psibi We have several persistent packages queued up for release, and I don't have access on hackage. Would you be able to upload them, please? Unless someone wants to give me access, that is:-) (I am "paulrouse" on hackage.) I believe the ones currently waiting are:

  • persistent-2.7.1
  • persistent-mysql-2.6.2
  • persistent-sqlite-2.6.3

@psibi
Copy link
Member

psibi commented Oct 23, 2017

@paul-rouse I have released the three packages to Hackage.

CC: @snoyberg It would be nice if Paul also has access to Hackage for persistent related packages.

@parsonsmatt
Copy link
Collaborator Author

Thanks so much! 😄

@snoyberg
Copy link
Member

snoyberg commented Oct 23, 2017 via email

@psibi
Copy link
Member

psibi commented Oct 23, 2017

@snoyberg Thanks!

@paul-rouse You should have Hackage access to all of the persistent related repos. Let me know if I missed something.

@paul-rouse
Copy link
Contributor

@psibi Thank you for sorting out the access! I don't even know the status of persistent-redis and persistent-zookeeper, except that they are in the Github repo - but those are the only two I can't access on hackage, and they are probably unimportant.

@psibi
Copy link
Member

psibi commented Oct 23, 2017

@paul-rouse That's because I don't have the Hackage access to those two packages and I haven't required them so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants