mattes / migrate

Database migrations. CLI and Golang library.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement shell "database" driver

mattes opened this issue · comments

commented
Implement shell "database" driver

I've been thinking about this for quite some time. I think the root issue why this issue has not been fixed is that the Driver interface is too broad in scope. Really, it has two orthogonal responsibilities:

  • To run the actual migrations, ie. run the shell command, ALTER a table etc.
  • To keep track of which migrations have been applied, lock database and mark migrations as applied etc.

To avoid having to implement a "shell driver" for every database backend, I instead propose that Driver is split up into two interfaces; (for now) call them Migrator and MigrationRepository:

type Migrator interface {
	Open(url string) (Driver, error)
	Close() error
	Run(migration io.Reader) error
}

type MigrationRepository interface {
	Open(url string) (Driver, error)
	Close() error
	Lock() error
	Unlock() error
	SetVersion(version int, dirty bool) error
	Version() (version int, dirty bool, err error)
	Drop() error
}

The nice thing is that all Driver implementations already implement these two interfaces. One challenge is that Open(...) and Close() only are supposed to be called once per implementation. This could be worked around by wrapping all Driver implementations in a SingleOpenCloseDriver which makes sure to only delegate Open/Close calls to the actual delegate if not called before. As soon as all Drivers have been split up into two different implementations, SingleOpenCloseDriver can be ditched.

Clearly, this change would also require that CLI would take a -migrator and a -repository URLs to define which migrator and database that should be used. For backwards compatibility -database could hang around, and be a shortcut for setting -migrator and -repository to the same value.

What are you thoughts on this?

commented

I think there is a misunderstanding. When I wrote shell I meant bash.

For your specific case, I believe the source driver is the equivalent to your proposed Migrator interface.

@mattes Hm, so if shell is implemented, where can I find it? https://github.com/mattes/migrate/tree/master/database/shell seem to be empty.

commented

The bash/shell driver is not yet implemented.

@mattes Still, if you would implement bash, how would you store which migrations have been executed?