Skip to content

Expose underlying database connections to the users #42

@sullivan-

Description

@sullivan-

Let users have a back door to the database to do whatever they need to do. They can always open up another connection themselves; Having two database connections open from the same app to the same database is workable, but less than ideal. (Actually, in SQLite, this probably isn't even workable, as SQLite has single-writer model.)

This is slightly trickier than you might expect, because each back end has their own connection API, and these connection APIs are defined in optional dependencies. So we have to be careful where to expose these methods so that things don't break when the optional dependency is missing. We've handled this kind of thing before. See for example implicit def longevity.persistence.repoToAkkaStreamsRepo.

Probably the best signatures for these methods would be something like:

def mongoClientOpt: Option[com.mongodb.MongoClient]
def mongoDatabaseOpt: Option[com.mongodb.client.MongoDatabase]
def jdbcConnectionOpt: Option[java.sql.Connection]
def cassandraSessionOpt: Option[com.datastax.driver.core.Session]

A couple of notes here:

  • Normally the MongoClient should be sufficient, but in some circumstances, the MongoDatabase instance may be needed. (In case they need to connect to the admin database for some reason.)
  • We could choose to not wrap in Options, and just throw exception if the connection is closed. (See e.g. private lazy val session in MongoRepo.) But it's probably better to wrap in an option than introduce an API method that throws exception. (Note it would be quite inconvenient for, say, Repo.create to return an F[Option[PState[P]]], where the option was None if the connection was closed. So it's less unreasonable for Repo.create to throw a ConnectionClosedException. (This exception is thrown within the effect F, of course.) There are probably some good functional approaches that could avoid exception throwing cleanly here...)
  • It's important that the end user plays nice with the exposed session, i.e., doesn't close it. This would put Repo internal state out of sync. (Again, probably some good functional approaches to get rid of this internal state. But certainly not obvious.) This "plays nice" requirement should be mentioned in the Scaladocs for the method.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions