Implement shell "database" driver
mattes opened this issue · comments
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 Driver
s 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?
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.
The bash/shell
driver is not yet implemented.
@mattes Still, if you would implement bash
, how would you store which migrations have been executed?