code: func NewMigratorWithLogger(db *sql.DB, adapter Migratable, migrationsPath string, logger Logger) (*Migrator, error) {
  	// Normalize the migrations path.
  	path := []byte(migrationsPath)
  	pathLength := len(path)
  	if path[pathLength-1] != '/' {
  		path = append(path, '/')
  	}
  
  	logger.Printf("Migrations path: %s", path)
  
  	migrator := Migrator{
  		db,
  		string(path),
  		adapter,
  		make(map[uint64]*Migration),
  		logger,
  	}
  
  	// Create the migrations table if it doesn't exist.
  	tableExists, err := migrator.MigrationTableExists()
  	if err != nil {
  		return nil, err
  	}
  	if !tableExists {
  		if err := migrator.CreateMigrationsTable(); err != nil {
  			return nil, err
  		}
  	}
  
  	// Get all metadata from the database.
  	if err := migrator.fetchMigrations(); err != nil {
  		return nil, err
  	}
  	if err := migrator.getMigrationStatuses(); err != nil {
  		return nil, err
  	}
  
  	return &migrator, nil
  }
docs: // Returns a new migrator with the specified logger.