diff --git a/DBV.php b/DBV.php
index d2a9e1d..9a02898 100644
--- a/DBV.php
+++ b/DBV.php
@@ -176,6 +176,60 @@ public function revisionsAction()
}
}
+ public function jumptoAction(){
+
+ $final_revision = isset($_POST['revision']) ? intval($_POST['revision']) : 0;
+ $current_revision = $this->_getCurrentRevision();
+ $revisions = $this->_getRevisions();
+
+ foreach($revisions as $revision){
+
+ //move forward
+ if($revision > $current_revision && $revision <= $final_revision){
+
+ $files = $this->_getRevisionFiles($revision);
+ if (count($files)) {
+ foreach ($files as $file) {
+ $file = DBV_REVISIONS_PATH . DS . $revision . DS . $file;
+ if (!$this->_runFile($file)) {
+ break 2;
+ }
+ }
+ }
+
+ //rollback
+ }elseif($revision <= $current_revision && $revision > $final_revision){
+
+ $files = $this->_getRevisionRollbackFiles($revision);
+
+ if (count($files)) {
+ foreach ($files as $file) {
+ $file = DBV_REVISIONS_PATH . DS . $revision . DS . 'rollback' . DS . $file;
+ if (!$this->_runFile($file)) {
+ break 2;
+ }
+ }
+ }
+ }
+ }
+
+ $this->_setCurrentRevision($final_revision);
+
+ $this->confirm(__("Jumped to revision #{revision}", array('revision' => "$final_revision")));
+ if ($this->_isXMLHttpRequest()) {
+ $return = array(
+ 'messages' => array(),
+ 'revision' => $this->_getCurrentRevision()
+ );
+ foreach ($this->_log as $message) {
+ $return['messages'][$message['type']][] = $message['message'];
+ }
+ $this->_json($return);
+
+ } else {
+ $this->indexAction();
+ }
+ }
public function saveRevisionFileAction()
{
@@ -332,18 +386,28 @@ protected function _getRevisions()
protected function _getCurrentRevision()
{
- $file = DBV_META_PATH . DS . 'revision';
- if (file_exists($file)) {
- return intval(file_get_contents($file));
+ if(DB_REVISION_LOG){
+ return $this->_getAdapter()->getCurrentRevision();
+ }else{
+ $file = DBV_META_PATH . DS . 'revision';
+ if (file_exists($file)) {
+ return intval(file_get_contents($file));
+ }
}
return 0;
}
protected function _setCurrentRevision($revision)
{
- $file = DBV_META_PATH . DS . 'revision';
- if (!@file_put_contents($file, $revision)) {
- $this->error("Cannot write revision file");
+
+ if(DB_REVISION_LOG){
+ $commit = ($_POST['commit'])? $_POST['commit'] : 'NULL';
+ $this->_getAdapter()->setRevision($revision, $commit);
+ }else{
+ $file = DBV_META_PATH . DS . 'revision';
+ if (!@file_put_contents($file, $revision)) {
+ $this->error("Cannot write revision file");
+ }
}
}
@@ -362,6 +426,21 @@ protected function _getRevisionFiles($revision)
return $return;
}
+ protected function _getRevisionRollbackFiles($revision)
+ {
+ $dir = DBV_REVISIONS_PATH . DS . $revision . DS . 'rollback';
+ $return = array();
+
+ foreach (new DirectoryIterator($dir) as $file) {
+ if ($file->isFile() && pathinfo($file->getFilename(), PATHINFO_EXTENSION) == 'sql') {
+ $return[] = $file->getBasename();
+ }
+ }
+
+ sort($return, SORT_REGULAR);
+ return $return;
+ }
+
protected function _getRevisionFileContents($revision, $file)
{
$path = DBV_REVISIONS_PATH . DS . $revision . DS . $file;
@@ -372,6 +451,19 @@ protected function _getRevisionFileContents($revision, $file)
return false;
}
+ public function findRevisionFromCommit($commit){
+
+ if(DB_REVISION_LOG && $commit){
+ return $this->_getAdapter()->getRevision($commit);
+ }else{
+ $this->error("You can only find revisions if you save them to the database.");
+ }
+ }
+
+ public function findLastRevision(){
+ return array_shift($this->_getRevisions());
+ }
+
public function log($item)
{
$this->_log[] = $item;
diff --git a/cl.php b/cl.php
new file mode 100644
index 0000000..4e434cf
--- /dev/null
+++ b/cl.php
@@ -0,0 +1,44 @@
+findLastRevision();
+ $_POST['commit'] = $argv[2];
+}elseif($argv[1] === 'rev' && $argv[2]){
+ $_POST['revision'] = $argv[2];
+}elseif($argv[1] === 'commit' && $argv[2]){
+ $rev = $dbv->findRevisionFromCommit($argv[2]);
+ if($rev){
+ $_POST['revision'] = $rev;
+ }else{
+ die('Could not find revision');
+ }
+}else{
+ die("No valid arguments found. Please use 'last', 'rev' or 'commit'");
+}
+
+$dbv->authenticate();
+$dbv->dispatch();
diff --git a/config.php.sample b/config.php.sample
index 7a18293..653a231 100644
--- a/config.php.sample
+++ b/config.php.sample
@@ -26,6 +26,12 @@ define('DB_ADAPTER', 'MySQL');
define('DS', DIRECTORY_SEPARATOR);
define('DBV_ROOT_PATH', dirname(__FILE__));
+/**
+* Use db for keeping track of current revision in the database and specify the table
+*/
+define('DB_REVISION_LOG', true);
+define('DB_REVISION_TABLE', 'dbv_revisions');
+
/**
* Only edit this lines if you want to place your schema files in custom locations
* @see http://dbv.vizuina.com/documentation/#optional-settings
diff --git a/install.sql b/install.sql
new file mode 100644
index 0000000..2c3fb09
--- /dev/null
+++ b/install.sql
@@ -0,0 +1,6 @@
+CREATE TABLE `dbv_revisions` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `commit` varchar(255) DEFAULT NULL,
+ `revision` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
\ No newline at end of file
diff --git a/lib/adapters/MySQL.php b/lib/adapters/MySQL.php
index 7d498a8..6772be4 100644
--- a/lib/adapters/MySQL.php
+++ b/lib/adapters/MySQL.php
@@ -87,4 +87,17 @@ public function getSchemaObject($name)
return $return;
}
+ public function getCurrentRevision(){
+ $result = $this->query("SELECT revision FROM " . DB_REVISION_TABLE . " ORDER BY id DESC LIMIT 1")->fetchColumn();
+ return ($result)? (int) $result : 0;
+ }
+
+ public function getRevision($commit){
+ $result = $this->query("SELECT revision FROM " . DB_REVISION_TABLE . " WHERE commit='" . $commit . "' ORDER BY id DESC LIMIT 1")->fetchColumn();
+ return ($result)? (int) $result : false;
+ }
+
+ public function setRevision($revision, $commit){
+ $this->query("INSERT INTO " . DB_REVISION_TABLE . " (commit, revision) VALUES ('" . $commit . "'," . $revision . ")");
+ }
}
diff --git a/templates/revisions.php b/templates/revisions.php
index bc89261..c1d1130 100644
--- a/templates/revisions.php
+++ b/templates/revisions.php
@@ -57,6 +57,20 @@
+
+
If you select a revision lower then the current one it will run the rollback script for every revision inbetween the current and the selected revision. + Place your rollback script in a folder 'rollback' within the revision folder. All scripts within that folder will be run.
+