Changeset 243

Show
Ignore:
Timestamp:
09/28/07 20:08:33 (10 months ago)
Author:
lcrouch
Message:

#156 change DbDeployTask to use new PEAR DB_Deploy package

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php

    r223 r243  
    2020 */ 
    2121  
    22 require_once 'phing/Task.php'; 
    23 require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php'; 
    24  
     22require_once 'phing/Task.php' ; 
    2523 
    2624/** 
    2725 *  Generate SQL script for db using dbdeploy schema version table and delta scripts 
    2826 * 
    29  *  <dbdeploy url="mysql:host=localhost;dbname=test" userid="dbdeploy" password="dbdeploy" dir="db" outputfile="">  
     27 *  <dbdeploy configfile="dbdeploy/dev.ini" />  
    3028 *  
    3129 *  @author   Luke Crouch at SourceForge (http://sourceforge.net) 
     
    3634class DbDeployTask extends Task { 
    3735         
    38         public static $TABLE_NAME = 'changelog'; 
     36        protected $configFile ; 
     37         
     38        function main () { 
     39                try { 
     40                        /** 
     41                         * Ugly hack to check for DbDeploy PEAR package 
     42                         */ 
     43                        $config = new PEAR_Config(); 
     44                        $registry = new PEAR_Registry($config->get('php_dir')); 
     45                        $pkg_info = $registry->_packageInfo("Db_Deploy", null, "pear.php.net"); 
    3946 
    40         protected $url; 
    41         protected $userid; 
    42         protected $password; 
    43         protected $dir; 
    44         protected $outputFile = 'dbdeploy_deploy.sql'; 
    45         protected $undoOutputFile = 'dbdeploy_undo.sql'; 
    46         protected $deltaSet = 'Main'; 
    47         protected $lastChangeToApply = 999; 
    48         protected $dbmsSyntax = null; 
    49          
    50     function main() { 
    51         try{ 
    52                 // get correct DbmsSyntax object 
    53                 $dbms = substr($this->url, 0, strpos($this->url, ':')); 
    54                 $dbmsSyntaxFactory = new DbmsSyntaxFactory($dbms); 
    55                 $this->dbmsSyntax = $dbmsSyntaxFactory->getDbmsSyntax(); 
    56                  
    57                         // open file handles for output 
    58                 $outputFileHandle = fopen($this->outputFile, "w+"); 
    59                 $undoOutputFileHandle = fopen($this->undoOutputFile, "w+"); 
    60                  
    61                 // figure out which revisions are in the db already 
    62                         $this->appliedChangeNumbers = $this->getAppliedChangeNumbers(); 
    63                         $this->log('Current db revision: ' . $this->getLastChangeAppliedInDb()); 
    64                          
    65                         // generate sql file needed to take db to "lastChangeToApply" version 
    66                         $doSql = $this->doDeploy(); 
    67                         $undoSql = $this->undoDeploy(); 
    68                          
    69                         // write the do and undo SQL to their respective files 
    70                         fwrite($outputFileHandle, $doSql); 
    71                         fwrite($undoOutputFileHandle, $undoSql); 
    72                          
    73         } catch (Exception $e){ 
    74                 throw new BuildException($e); 
    75         } 
    76     } 
    77          
    78     function getAppliedChangeNumbers(){ 
    79         if(count($this->appliedChangeNumbers) == 0){ 
    80                 $this->log('Getting applied changed numbers from DB: ' . $this->url ); 
    81                 $appliedChangeNumbers = array(); 
    82                 $dbh = new PDO($this->url, $this->userid, $this->password); 
    83                 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    84                 $sql = "SELECT * FROM " . DbDeployTask::$TABLE_NAME . " WHERE delta_set = '$this->deltaSet' ORDER BY change_number"; 
    85                         foreach($dbh->query($sql) as $change){ 
    86                         $appliedChangeNumbers[] = $change['change_number']; 
    87                 } 
    88                 $this->appliedChangeNumbers = $appliedChangeNumbers; 
    89         } 
    90         return $this->appliedChangeNumbers; 
    91     } 
    92      
    93     function getLastChangeAppliedInDb(){ 
    94         return (count($this->appliedChangeNumbers) > 0) ? max($this->appliedChangeNumbers) : 0; 
    95     } 
    96  
    97     function doDeploy(){ 
    98         $sqlToPerformDeploy = ''; 
    99         $lastChangeAppliedInDb = $this->getLastChangeAppliedInDb();      
    100         $files = $this->getDeltasFilesArray(); 
    101         ksort($files); 
    102         foreach($files as $fileChangeNumber=>$fileName){ 
    103                 if($fileChangeNumber > $lastChangeAppliedInDb && $fileChangeNumber <= $this->lastChangeToApply){ 
    104                         $sqlToPerformDeploy .= '--------------- Fragment begins: ' . $fileChangeNumber . ' ---------------' . "\n"; 
    105                         $sqlToPerformDeploy .= 'INSERT INTO ' . DbDeployTask::$TABLE_NAME . ' (change_number, delta_set, start_dt, applied_by, description)'. 
    106                                         ' VALUES ('. $fileChangeNumber .', \''. $this->deltaSet .'\', '. $this->dbmsSyntax->generateTimestamp() .', \'dbdeploy\', \''. $fileName .'\');' . "\n"; 
    107                                 $fullFileName = $this->dir . '/' . $fileName; 
    108                         $fh = fopen($fullFileName, 'r'); 
    109                         $contents = fread($fh,  filesize($fullFileName)); 
    110                         $deploySQLFromFile = substr($contents,0,strpos($contents, '--//@UNDO'));                         
    111                         $sqlToPerformDeploy .= $deploySQLFromFile; 
    112                         $sqlToPerformDeploy .= 'UPDATE ' . DbDeployTask::$TABLE_NAME . ' SET complete_dt = ' . $this->dbmsSyntax->generateTimestamp() . ' WHERE change_number = ' . $fileChangeNumber . ' AND delta_set = \'' . $this->deltaSet . '\';' . "\n"; 
    113                         $sqlToPerformDeploy .= '--------------- Fragment ends: ' . $fileChangeNumber . ' ---------------' . "\n"; 
    114                 } 
    115         } 
    116                 return $sqlToPerformDeploy; 
    117     } 
    118      
    119     function undoDeploy(){ 
    120         $sqlToPerformUndo = ''; 
    121         $lastChangeAppliedInDb = $this->getLastChangeAppliedInDb();      
    122         $files = $this->getDeltasFilesArray(); 
    123         krsort($files); 
    124         foreach($files as $fileChangeNumber=>$fileName){ 
    125                 if($fileChangeNumber > $lastChangeAppliedInDb && $fileChangeNumber <= $this->lastChangeToApply){ 
    126                                 $fullFileName = $this->dir . '/' . $fileName; 
    127                         $fh = fopen($fullFileName, 'r'); 
    128                         $contents = fread($fh,  filesize($fullFileName)); 
    129                         $undoSQLFromFile = substr($contents,strpos($contents, '--//@UNDO')+9);                           
    130                         $sqlToPerformUndo .= $undoSQLFromFile; 
    131                         $sqlToPerformUndo .= 'DELETE FROM ' . DbDeployTask::$TABLE_NAME . ' WHERE change_number = ' . $fileChangeNumber . ' AND delta_set = \'' . $this->deltaSet . '\';' . "\n"; 
    132                         $sqlToPerformUndo .= '--------------- Fragment ends: ' . $fileChangeNumber . ' ---------------' . "\n"; 
    133                 } 
    134         } 
    135                 return $sqlToPerformUndo; 
    136     } 
    137      
    138    function getDeltasFilesArray(){ 
    139         $baseDir = realpath($this->dir); 
    140         $dh = opendir($baseDir); 
    141         $fileChangeNumberPrefix = ''; 
    142         while(($file = readdir($dh)) !== false){ 
    143                 if(preg_match('[\d+]', $file, $fileChangeNumberPrefix)){ 
    144                         $files[$fileChangeNumberPrefix[0]] = $file; 
    145                 } 
    146         } 
    147         return $files; 
    148     } 
    149      
    150         function setUrl($url){ 
    151                 $this->url = $url; 
     47                        if ($pkg_info != NULL){ 
     48                                @include_once 'DB/Deploy.php'; 
     49                                $dbdeploy = new Db_Deploy(); 
     50                                $dbdeploy->setConfigFile($this->configFile); 
     51                                $dbdeploy->fire(); 
     52                        } else { 
     53                                throw new BuildException("dbdeploy task depends on PEAR DbDeploy package being installed.", $this->getLocation()); 
     54                        } 
     55                } catch ( Exception $e ) { 
     56                        throw new BuildException ( $e ) ; 
     57                } 
    15258        } 
    15359         
    154         function setUserId($userid){ 
    155                 $this->userid = $userid
     60        public function setConfigFile($configFile){ 
     61                $this->configFile = $configFile
    15662        } 
    157          
    158         function setPassword($password){ 
    159                 $this->password = $password; 
    160         } 
    161  
    162         function setDir($dir){ 
    163                 $this->dir = $dir; 
    164         } 
    165  
    166         function setOutputFile($outputFile){ 
    167                 $this->outputFile = $outputFile; 
    168         } 
    169  
    170         function setUndoOutputFile($undoOutputFile){ 
    171                 $this->undoOutputFile = $undoOutputFile; 
    172         } 
    173          
    174         function setLastChangeToApply($lastChangeToApply){ 
    175                 $this->lastChangeToApply = $lastChangeToApply; 
    176         } 
    177  
    178         function setDeltaSet($deltaSet){ 
    179                 $this->deltaSet = $deltaSet; 
    180         } 
    181          
    182     /** 
    183      * Add a new fileset. 
    184      * @return FileSet 
    185      */ 
    186     public function createFileSet() { 
    187         $this->fileset = new FileSet(); 
    188         $this->filesets[] = $this->fileset; 
    189         return $this->fileset; 
    190     } 
    19163} 
    19264