func LockDBAndMigrate(logger lager.Logger, sqlDriver string, sqlDataSource string) (db.Conn, error) { var err error var dbLockConn db.Conn var dbConn db.Conn for { dbLockConn, err = db.WrapWithError(sql.Open(sqlDriver, sqlDataSource)) if err != nil { if strings.Contains(err.Error(), " dial ") { logger.Error("failed-to-open-db-retrying", err) time.Sleep(5 * time.Second) continue } return nil, err } break } lockName := crc32.ChecksumIEEE([]byte(sqlDriver + sqlDataSource)) for { _, err = dbLockConn.Exec(`select pg_advisory_lock($1)`, lockName) if err != nil { logger.Error("failed-to-acquire-lock-retrying", err) time.Sleep(5 * time.Second) continue } logger.Info("migration-lock-acquired") migrations := Translogrifier(logger, Migrations) dbConn, err = db.WrapWithError(migration.OpenWith(sqlDriver, sqlDataSource, migrations, safeGetVersion, safeSetVersion)) if err != nil { logger.Fatal("failed-to-run-migrations", err) } _, err = dbLockConn.Exec(`select pg_advisory_unlock($1)`, lockName) if err != nil { logger.Error("failed-to-release-lock", err) } dbLockConn.Close() break } return dbConn, nil }
package db_test import ( "time" "github.com/concourse/atc/db" "github.com/concourse/atc/db/fakes" "github.com/lib/pq" "github.com/pivotal-golang/lager/lagertest" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("PipelineDBFactory", func() { var dbConn db.Conn var listener *pq.Listener var pipelineDBFactory db.PipelineDBFactory var pipelinesDB *fakes.FakePipelinesDB BeforeEach(func() { postgresRunner.Truncate() dbConn = db.Wrap(postgresRunner.Open()) listener = pq.NewListener(postgresRunner.DataSourceName(), time.Second, time.Minute, nil) Eventually(listener.Ping, 5*time.Second).ShouldNot(HaveOccurred()) bus := db.NewNotificationsBus(listener, dbConn)
package metric_test import ( "errors" "github.com/concourse/atc/db" "github.com/concourse/atc/db/fakes" "github.com/concourse/atc/metric" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Counting Database Queries", func() { var ( underlyingConn *fakes.FakeConn countingConn db.Conn ) BeforeEach(func() { underlyingConn = new(fakes.FakeConn) countingConn = metric.CountQueries(underlyingConn) }) AfterEach(func() { err := countingConn.Close() Expect(err).NotTo(HaveOccurred()) }) It("passes through calls to the underlying connection", func() { countingConn.Ping()
"time" "github.com/concourse/atc/db" "github.com/concourse/atc/db/fakes" "github.com/pivotal-golang/lager/lagertest" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" ) var _ = Describe("Explain", func() { var ( logger *lagertest.TestLogger underlyingConn *fakes.FakeConn explainConn db.Conn ) BeforeEach(func() { logger = lagertest.NewTestLogger("explain") underlyingConn = new(fakes.FakeConn) explainConn = db.Explain(logger, underlyingConn, 100*time.Millisecond) }) AfterEach(func() { err := explainConn.Close() Ω(err).ShouldNot(HaveOccurred()) }) It("passes through calls to the underlying connection", func() {