Skip to content

Instantly share code, notes, and snippets.

@icholy
Last active August 29, 2015 14:08
Show Gist options
  • Select an option

  • Save icholy/d56873d4733e5b8dec2a to your computer and use it in GitHub Desktop.

Select an option

Save icholy/d56873d4733e5b8dec2a to your computer and use it in GitHub Desktop.

Revisions

  1. icholy revised this gist Oct 27, 2014. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -52,7 +52,6 @@ func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {
    }

    // release is called by the DB's Close() method
    // don't call this method yourself
    func (f *Factory) release(key string) {
    f.Lock()
    defer f.Unlock()
  2. icholy revised this gist Oct 27, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -75,6 +75,6 @@ type DB struct {
    }

    func (db *DB) Close() {
    go db.factory.release(db.key)
    db.factory.release(db.key)
    }

  3. icholy revised this gist Oct 27, 2014. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,8 @@
    // Use Case:
    //
    // Say you have a bunch of decoupled components which access the same set of databases.
    // Since database/sql does connection pooling it makes sense for the components to share instances of *sql.DB
    // This package lets you do that with minimal code changes.
    package dbmanager

    import (
    @@ -35,7 +40,6 @@ func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {
    defer f.Unlock()
    db, ok := f.connections[dataSourceName]
    if !ok {

    var err error
    db, err = f.open(driverName, dataSourceName)
    if err != nil {
  4. icholy revised this gist Oct 27, 2014. 1 changed file with 4 additions and 9 deletions.
    13 changes: 4 additions & 9 deletions dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -31,10 +31,8 @@ func (f *Factory) open(driverName, dataSourceName string) (*DB, error) {

    // Open returns a DB connection.
    func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {

    f.Lock()
    defer f.Unlock()

    db, ok := f.connections[dataSourceName]
    if !ok {

    @@ -45,7 +43,6 @@ func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {
    }
    f.connections[dataSourceName] = db
    }

    db.leases++
    return db, nil
    }
    @@ -55,16 +52,14 @@ func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {
    func (f *Factory) release(key string) {
    f.Lock()
    defer f.Unlock()

    conn, ok := f.connections[key]
    db, ok := f.connections[key]
    if !ok {
    return
    }

    conn.leases--
    if conn.leases == 0 {
    db.leases--
    if db.leases == 0 {
    delete(f.connections, key)
    conn.DB.Close()
    db.DB.Close()
    }
    }

  5. icholy revised this gist Oct 27, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -58,7 +58,7 @@ func (f *Factory) release(key string) {

    conn, ok := f.connections[key]
    if !ok {
    panic("returning expired connection.")
    return
    }

    conn.leases--
  6. icholy revised this gist Oct 27, 2014. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -64,7 +64,7 @@ func (f *Factory) release(key string) {
    conn.leases--
    if conn.leases == 0 {
    delete(f.connections, key)
    conn.DB.Close()
    conn.DB.Close()
    }
    }

    @@ -78,3 +78,4 @@ type DB struct {
    func (db *DB) Close() {
    go db.factory.release(db.key)
    }

  7. icholy created this gist Oct 27, 2014.
    80 changes: 80 additions & 0 deletions dbmanager.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    package dbmanager

    import (
    "database/sql"
    "time"
    "sync"
    )

    type Factory struct {
    connections map[string]*DB
    sync.Mutex
    }

    func NewFactory() *Factory {
    return &Factory{
    connections: make(map[string]*DB),
    }
    }

    func (f *Factory) open(driverName, dataSourceName string) (*DB, error) {
    db, err := sql.Open(driverName, dataSourceName)
    if err != nil {
    return nil, err
    }
    return &DB{
    key: dataSourceName,
    factory: f,
    DB: db,
    }, nil
    }

    // Open returns a DB connection.
    func (f *Factory) Open(driverName, dataSourceName string) (*DB, error) {

    f.Lock()
    defer f.Unlock()

    db, ok := f.connections[dataSourceName]
    if !ok {

    var err error
    db, err = f.open(driverName, dataSourceName)
    if err != nil {
    return nil, err
    }
    f.connections[dataSourceName] = db
    }

    db.leases++
    return db, nil
    }

    // release is called by the DB's Close() method
    // don't call this method yourself
    func (f *Factory) release(key string) {
    f.Lock()
    defer f.Unlock()

    conn, ok := f.connections[key]
    if !ok {
    panic("returning expired connection.")
    }

    conn.leases--
    if conn.leases == 0 {
    delete(f.connections, key)
    conn.DB.Close()
    }
    }

    type DB struct {
    leases int
    key string
    factory *Factory
    *sql.DB
    }

    func (db *DB) Close() {
    go db.factory.release(db.key)
    }