+build go1.9

package postgres

import (
	
	
	
	
	
	nurl 
	
	

	
	
	multierror 
	
)

func () {
	 := Postgres{}
	database.Register("postgres", &)
	database.Register("postgresql", &)
}

var DefaultMigrationsTable = "schema_migrations"

var (
	ErrNilConfig      = fmt.Errorf("no config")
	ErrNoDatabaseName = fmt.Errorf("no database name")
	ErrNoSchema       = fmt.Errorf("no schema")
	ErrDatabaseDirty  = fmt.Errorf("database is dirty")
)

type Config struct {
	MigrationsTable string
	DatabaseName    string
	SchemaName      string
}

Locking and unlocking need to use the same connection
Open and WithInstance need to guarantee that config is never nil
	config *Config
}

func ( *sql.DB,  *Config) (database.Driver, error) {
	if  == nil {
		return nil, ErrNilConfig
	}

	if  := .Ping();  != nil {
		return nil, 
	}

	 := `SELECT CURRENT_DATABASE()`
	var  string
	if  := .QueryRow().Scan(&);  != nil {
		return nil, &database.Error{OrigErr: , Query: []byte()}
	}

	if len() == 0 {
		return nil, ErrNoDatabaseName
	}

	.DatabaseName = 

	 = `SELECT CURRENT_SCHEMA()`
	var  string
	if  := .QueryRow().Scan(&);  != nil {
		return nil, &database.Error{OrigErr: , Query: []byte()}
	}

	if len() == 0 {
		return nil, ErrNoSchema
	}

	.SchemaName = 

	if len(.MigrationsTable) == 0 {
		.MigrationsTable = DefaultMigrationsTable
	}

	,  := .Conn(context.Background())

	if  != nil {
		return nil, 
	}

	 := &Postgres{
		conn:   ,
		db:     ,
		config: ,
	}

	if  := .ensureVersionTable();  != nil {
		return nil, 
	}

	return , nil
}

func ( *Postgres) ( string) (database.Driver, error) {
	,  := nurl.Parse()
	if  != nil {
		return nil, 
	}

	,  := sql.Open("postgres", migrate.FilterCustomQuery().String())
	if  != nil {
		return nil, 
	}

	 := .Query().Get("x-migrations-table")

	,  := WithInstance(, &Config{
		DatabaseName:    .Path,
		MigrationsTable: ,
	})

	if  != nil {
		return nil, 
	}

	return , nil
}

func ( *Postgres) () error {
	 := .conn.Close()
	 := .db.Close()
	if  != nil ||  != nil {
		return fmt.Errorf("conn: %v, db: %v", , )
	}
	return nil
}
https://www.postgresql.org/docs/9.6/static/explicit-locking.html#ADVISORY-LOCKS
func ( *Postgres) () error {
	if .isLocked {
		return database.ErrLocked
	}

	,  := database.GenerateAdvisoryLockId(.config.DatabaseName, .config.SchemaName)
	if  != nil {
		return 
	}
This will either obtain the lock immediately and return true, or return false if the lock cannot be acquired immediately.
	 := `SELECT pg_advisory_lock($1)`
	if ,  := .conn.ExecContext(context.Background(), , );  != nil {
		return &database.Error{OrigErr: , Err: "try lock failed", Query: []byte()}
	}

	.isLocked = true
	return nil
}

func ( *Postgres) () error {
	if !.isLocked {
		return nil
	}

	,  := database.GenerateAdvisoryLockId(.config.DatabaseName, .config.SchemaName)
	if  != nil {
		return 
	}

	 := `SELECT pg_advisory_unlock($1)`
	if ,  := .conn.ExecContext(context.Background(), , );  != nil {
		return &database.Error{OrigErr: , Query: []byte()}
	}
	.isLocked = false
	return nil
}

func ( *Postgres) ( io.Reader) error {
	,  := ioutil.ReadAll()
	if  != nil {
		return 
	}
run migration
	 := string([:])
	if ,  := .conn.ExecContext(context.Background(), );  != nil {
		if ,  := .(*pq.Error);  {
			var  uint
			var  uint
			var  bool
			if .Position != "" {
				if ,  := strconv.ParseUint(.Position, 10, 64);  == nil {
					, ,  = computeLineFromPos(, int())
				}
			}
			 := fmt.Sprintf("migration failed: %s", .Message)
			if  {
				 = fmt.Sprintf("%s (column %d)", , )
			}
			if .Detail != "" {
				 = fmt.Sprintf("%s, %s", , .Detail)
			}
			return database.Error{OrigErr: , Err: , Query: , Line: }
		}
		return database.Error{OrigErr: , Err: "migration failed", Query: }
	}

	return nil
}

replace crlf with lf
pg docs: pos uses index 1 for the first character, and positions are measured in characters not bytes
	 := []rune()
	if  > len() {
		return 0, 0, false
	}
	 := [:]
	 = uint(runesCount(, newLine) + 1)
	 = uint( - 1 - runesLastIndex(, newLine))
	return , , true
}

const newLine = '\n'

func ( []rune,  rune) int {
	var  int
	for ,  := range  {
		if  ==  {
			++
		}
	}
	return 
}

func ( []rune,  rune) int {
	for  := len() - 1;  >= 0; -- {
		if [] ==  {
			return 
		}
	}
	return -1
}

func ( *Postgres) ( int,  bool) error {
	,  := .conn.BeginTx(context.Background(), &sql.TxOptions{})
	if  != nil {
		return &database.Error{OrigErr: , Err: "transaction start failed"}
	}

	 := `TRUNCATE ` + pq.QuoteIdentifier(.config.MigrationsTable)
	if ,  := .Exec();  != nil {
		if  := .Rollback();  != nil {
			 = multierror.Append(, )
		}
		return &database.Error{OrigErr: , Query: []byte()}
	}

	if  >= 0 {
		 = `INSERT INTO ` + pq.QuoteIdentifier(.config.MigrationsTable) + ` (version, dirty) VALUES ($1, $2)`
		if ,  := .Exec(, , );  != nil {
			if  := .Rollback();  != nil {
				 = multierror.Append(, )
			}
			return &database.Error{OrigErr: , Query: []byte()}
		}
	}

	if  := .Commit();  != nil {
		return &database.Error{OrigErr: , Err: "transaction commit failed"}
	}

	return nil
}

func ( *Postgres) () ( int,  bool,  error) {
	 := `SELECT version, dirty FROM ` + pq.QuoteIdentifier(.config.MigrationsTable) + ` LIMIT 1`
	 = .conn.QueryRowContext(context.Background(), ).Scan(&, &)
	switch {
	case  == sql.ErrNoRows:
		return database.NilVersion, false, nil

	case  != nil:
		if ,  := .(*pq.Error);  {
			if .Code.Name() == "undefined_table" {
				return database.NilVersion, false, nil
			}
		}
		return 0, false, &database.Error{OrigErr: , Query: []byte()}

	default:
		return , , nil
	}
}

select all tables in current schema
	 := `SELECT table_name FROM information_schema.tables WHERE table_schema=(SELECT current_schema()) AND table_type='BASE TABLE'`
	,  := .conn.QueryContext(context.Background(), )
	if  != nil {
		return &database.Error{OrigErr: , Query: []byte()}
	}
	defer func() {
		if  := .Close();  != nil {
			 = multierror.Append(, )
		}
	}()
delete one table after another
	 := make([]string, 0)
	for .Next() {
		var  string
		if  := .Scan(&);  != nil {
			return 
		}
		if len() > 0 {
			 = append(, )
		}
	}

delete one by one ...
		for ,  := range  {
			 = `DROP TABLE IF EXISTS ` + pq.QuoteIdentifier() + ` CASCADE`
			if ,  := .conn.ExecContext(context.Background(), );  != nil {
				return &database.Error{OrigErr: , Query: []byte()}
			}
		}
	}

	return nil
}
ensureVersionTable checks if versions table exists and, if not, creates it. Note that this function locks the database, which deviates from the usual convention of "caller locks" in the Postgres type.
func ( *Postgres) () ( error) {
	if  = .Lock();  != nil {
		return 
	}

	defer func() {
		if  := .Unlock();  != nil {
			if  == nil {
				 = 
			} else {
				 = multierror.Append(, )
			}
		}
	}()

	 := `CREATE TABLE IF NOT EXISTS ` + pq.QuoteIdentifier(.config.MigrationsTable) + ` (version bigint not null primary key, dirty boolean not null)`
	if _,  = .conn.ExecContext(context.Background(), );  != nil {
		return &database.Error{OrigErr: , Query: []byte()}
	}

	return nil