2020-08-06 20:58:47 +03:00
|
|
|
package driver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
2020-12-30 21:57:58 +03:00
|
|
|
"sync"
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
"github.com/neilotoole/lg"
|
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/cleanup"
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/source"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ScratchSrcFunc is a function that returns a scratch source.
|
|
|
|
// The caller is responsible for invoking cleanFn.
|
|
|
|
type ScratchSrcFunc func(log lg.Log, name string) (src *source.Source, cleanFn func() error, err error)
|
|
|
|
|
|
|
|
// scratchDatabase implements driver.Database.
|
2020-08-12 21:24:01 +03:00
|
|
|
// It exists as a separate type mostly to support cleanup of the
|
|
|
|
// created scratch database during Close. Possibly this type can
|
|
|
|
// be ditched entirely.
|
2020-08-06 20:58:47 +03:00
|
|
|
type scratchDatabase struct {
|
|
|
|
log lg.Log
|
|
|
|
impl Database
|
|
|
|
cleanup *cleanup.Cleanup
|
2020-12-30 21:57:58 +03:00
|
|
|
mu sync.Mutex
|
|
|
|
closed bool
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// DB implements driver.Database.
|
|
|
|
func (d *scratchDatabase) DB() *sql.DB {
|
|
|
|
return d.impl.DB()
|
|
|
|
}
|
|
|
|
|
|
|
|
// TableMetadata implements driver.Database.
|
|
|
|
func (d *scratchDatabase) TableMetadata(ctx context.Context, tblName string) (*source.TableMetadata, error) {
|
|
|
|
return d.impl.TableMetadata(ctx, tblName)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SQLDriver implements driver.Database.
|
|
|
|
func (d *scratchDatabase) SQLDriver() SQLDriver {
|
|
|
|
return d.impl.SQLDriver()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Source implements driver.Database.
|
|
|
|
func (d *scratchDatabase) Source() *source.Source {
|
|
|
|
return d.impl.Source()
|
|
|
|
}
|
|
|
|
|
|
|
|
// SourceMetadata implements driver.Database.
|
|
|
|
func (d *scratchDatabase) SourceMetadata(ctx context.Context) (*source.Metadata, error) {
|
|
|
|
return d.impl.SourceMetadata(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close implements driver.Database.
|
|
|
|
func (d *scratchDatabase) Close() error {
|
2020-12-30 21:57:58 +03:00
|
|
|
d.mu.Lock()
|
|
|
|
defer d.mu.Unlock()
|
|
|
|
|
|
|
|
if d.closed {
|
|
|
|
panic("already closed")
|
|
|
|
}
|
|
|
|
|
|
|
|
d.log.Debugf("Closing scratch database [%s]", d.impl.Source())
|
|
|
|
|
|
|
|
//debug.PrintStack()
|
2020-08-06 20:58:47 +03:00
|
|
|
// No need to explicitly invoke c.impl.Close because it
|
|
|
|
// has already been added to c.cleanup.
|
2020-12-30 21:57:58 +03:00
|
|
|
err := d.cleanup.Run()
|
|
|
|
d.log.Debugf("Closed scratch database [%s]: err=%v", d.impl.Source(), err)
|
|
|
|
d.closed = true
|
|
|
|
return err
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|