#!/usr/bin/php
<?php
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
  Codificación: UTF-8
  +----------------------------------------------------------------------+
  | Elastix version 2.0                                                  |
  | http://www.elastix.org                                               |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006 Palosanto Solutions S. A.                         |
  +----------------------------------------------------------------------+
  | Cdla. Nueva Kennedy Calle E 222 y 9na. Este                          |
  | Telfs. 2283-268, 2294-440, 2284-356                                  |
  | Guayaquil - Ecuador                                                  |
  | http://www.palosanto.com                                             |
  +----------------------------------------------------------------------+
  | The contents of this file are subject to the General Public License  |
  | (GPL) Version 2 (the "License"); you may not use this file except in |
  | compliance with the License. You may obtain a copy of the License at |
  | http://www.opensource.org/licenses/gpl-license.php                   |
  |                                                                      |
  | Software distributed under the License is distributed on an "AS IS"  |
  | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See  |
  | the License for the specific language governing rights and           |
  | limitations under the License.                                       |
  +----------------------------------------------------------------------+
  | The Original Code is: Elastix Open Source.                           |
  | The Initial Developer of the Original Code is PaloSanto Solutions    |
  +----------------------------------------------------------------------+
 */

/*
This script takes two argument, the first is the action (install,update,delete)
and the second argument is the database folder path where are files sqls. 
This script install, update and delete database.
*/


/*
    Arbol de carpetas
                        
                              1_network.sql
                    network/  2_network.sql
                              3_network.sql
                                 .
                                 .
                              
            delete/ iptables/  ....
        
                    dashboar/  ....





                              1_schema.sql
                    network/  2_schema.sql
                                   .
                                   .

   ...db/  install/ iptables/  ....

                    dashboar/  ....





            
                              1_2.0.4-1_2.0.4-3.sql
                    network/  2_2.0.1-3_2.0.4-4.sql
                                    .
                                    .

           update/  iptables/  ....

                    dashboar/  ....



           db.info

*/

/*
    Format for the file db.info

    [databaseName1]
    installation_force = no
    engine = sqlite3
    path = /var/www/db
    deletable = yes

    [databaseName2]
    installation_force = yes
    engine = sqlite3
    path = /var/www/db
    deletable = no

    [databaseName3]
      ...
      ...
      ...
*/


if ($argc < 2){
   die("Please specify the engine, the action and folder path files sqls.\n Usage: {$_SERVER['argv'][0]} install /usr/share/elastix/.../db/  version sql_export\n");
}

$documentRoot="/var/www/html";
require_once("$documentRoot/libs/misc.lib.php");
require_once("$documentRoot/configs/default.conf.php");
//global variables framework
global $arrConf;
require_once("$arrConf[basePath]/libs/paloSantoConfig.class.php");

$arrActions = array("install","update","delete");
if(isset($_SERVER['argv'][1]) & in_array($_SERVER['argv'][1],$arrActions)){
    if(isset($_SERVER['argv'][2])){
        $action      = $_SERVER['argv'][1];
        $path_folder = $_SERVER['argv'][2]; 
	    $sql_export  = isset($_SERVER['argv'][4])?$_SERVER['argv'][4]:false;
        $data        = getData($path_folder);
        $result      = 0;
        if(!$data){
            echo "Error reading the file $path_folder/db.info";
            return 1;
        }
        foreach($data as $key => $db){
                $password="";
                
                if($sql_export==false){
                    $confElastix = new paloConfig("/etc","elastix.conf"," = ","[[:space:]]*=[[:space:]]*");
                    $contentFile = $confElastix->leer_configuracion();
                    if($contentFile)
                        $password = $confElastix->privado_get_valor($contentFile,"mysqlrootpwd");
                }
        
                if($action=="install"){
                    if(!databaseExists($db['engine'],$key) || $db['installation_force'] == "yes"){
                        $install = executeFiles_SQL_install($db, $key, $password, $path_folder, $action, $sql_export);
                        $update = executeFiles_SQL_update($db, $key, "0.0.0-0", $password, $path_folder, "update", $sql_export);
                        if($install == 1 || $update == 1)
                            $result = 1;
                    }else{
                        echo "The database $key already exists.\n";
                    }
                }
	        else if($action=="update"){
                    if(databaseExists($db['engine'],$key)){
                        $version = isset($_SERVER['argv'][3])?$_SERVER['argv'][3]:false;
	                    if(isset($version) && !empty($version))
	                        $result = executeFiles_SQL_update($db, $key, $version, $password, $path_folder, $action, $sql_export);
                        else
                            echo "Has not been passed the version to the process of updating.\n";
                        $result = 0;
                    }else{
                        echo "The database $key does not exist.\nCreating the database $key.\n";
                        $install = executeFiles_SQL_install($db, $key, $password, $path_folder, "install", $sql_export);
                        $update = executeFiles_SQL_update($db, $key, "0.0.0-0", $password, $path_folder, $action, $sql_export);
                        if($install == 1 || $update == 1)
                            $result = 1;
                    }
                }
                else if($action=="delete"){
                    if($db['deletable'] == "yes")
                        $result = executeFiles_SQL_delete($db, $key, $password, $path_folder, $action, $sql_export);
                    else{
                        echo "The database $key is not deletable.\n";
                        $result = 1;
                    }
                    //echo "Nothing to be done in database. The action $action did have implementation yet.\n";
                    //return 0;
                }
            }
            return $result;
    }
    else{
        echo "Error: second arg not defined. Usage: {$_SERVER['argv'][0]} action path_folder_files_sqls\nThe actions will be: install, update and delete.\n";
        return 1;
    }
}
else{
echo "Error: first arg not defined. Usage: {$_SERVER['argv'][0]} action path_folder_files_sqls \n The actions will be: install, update and delete.\n";
return 1;
}
 

function executeFiles_SQL_install($data, $dbname, $password, $path_folder, $action, $sql_export=false)
{
   $arrFiles  = scandir("$path_folder/$action/$dbname");
   $arrFiles = sortArray($arrFiles);
   $mysqlRunning = false;
   if(is_array($arrFiles) && count($arrFiles)>0){
      if(ismysqlRunning())
         $mysqlRunning = true;
      elseif($data['engine'] == "mysql")
         echo "Mysql is shutdown.\n";
      foreach($arrFiles as $k => $file){// must only have sqls files valids.
         if(ereg("\.sql$",$file)){
            if($mysqlRunning || $data['engine'] != "mysql"){
	            if($sql_export==false){
                    if($data['engine'] == "mysql")
                        $command = "mysql -uroot -p$password < $path_folder/$action/$dbname/$file";
                    elseif($data['engine'] == "sqlite3"){
                        $command = 'sqlite3 '.$data['path'].'/'.$dbname.'.db ".read '.$path_folder.'/'.$action.'/'.$dbname.'/'.$file.'"';
                    }
                    else{
                        echo "Error, wrong engine in database $dbname ";
                        return 1;
                    }
                    echo "Executing $command ... \n";
	                exec($command,$arrConsole,$flatStatus);
                    echo "RETURN $flatStatus\n";
                    if($flatStatus != 0){
	                    print_r($arrConsole);
	                    echo "Error, Action $action database $dbname failed.\n";
		                return 1;
		            }
	            }
	            else{
	                echo  file_get_contents("$path_folder/$action/$dbname/$file");
	            }
            }
            else{
                $tmp = split("_",$file);
                $flag = 50 + (int)$tmp[0];
                echo "Copying $path_folder/$action/$dbname/$file to /var/spool/elastix-mysqldbscripts/$flag"."_schema-$dbname.sql\n";
                exec("cp $path_folder/$action/$dbname/$file /var/spool/elastix-mysqldbscripts/$flag"."_schema-$dbname.sql",$arrConsole,$flagStatus);
                echo "RETURN $flagStatus.\n";
                if($flagStatus != 0){
                    print_r($arrConsole);
                    echo "Error, Could not copy the file $file.\n";
                    return 1;
               }
            }
         }
      }
      if($data['engine'] == "sqlite3"){
        if(!chown($data['path']."/".$dbname.".db","asterisk")){ 
            echo "Could not change the owner to asterisk to the database $dbname.\n";
            return 1;
        }
        if(!chgrp($data['path']."/".$dbname.".db","asterisk")){ 
            echo "Could not change the group to asterisk to the database $dbname.\n";
            return 1;
        }
      }

      if($sql_export==false && ($data['engine'] != "mysql" || $mysqlRunning))
          echo "Successfull, Action $action database $dbname.\n";
      return 0;
   }else{
        echo "Nothing to be done in database $dbname.\n";
        return 0;
   }
}

function executeFiles_SQL_update($data, $dbname, $version, $password, $path_folder, $action, $sql_export=false)
{
    $stringsql = updatedatabase($version,$path_folder,$data,$action,$dbname);

    if(!is_null($stringsql) && !empty($stringsql)){
        if($sql_export==false){
            echo "Updating since $version\n";
            $fileupdate = "$path_folder/$action/$dbname/01-updates-database.sql";
            file_put_contents($fileupdate,$stringsql);
            if($data['engine'] == "mysql")
                $command = "mysql -uroot -p$password < $fileupdate";
            elseif($data['engine'] == "sqlite3"){
                $command = 'sqlite3 '.$data['path'].'/'.$dbname.'.db ".read '.$fileupdate.'"';
            }
            else{
                echo "Error, wrong engine in database $dbname";
                return 1;
            }
            echo "Executing $command... \n";
            exec($command,$arrConsole,$flatStatus);

            echo "RETURN $flatStatus\n";
            if($flatStatus != 0){
                echo "Error, Action $action database $dbname failed.\n";
                return 1;
            }
            else{
                echo "Successfull, Action $action database $dbname.\n";
                return 0;
            }

        }
        else{scandir("$path_folder/$action/$dbname");
            echo $stringsql;
            return 0;
        }
    }
    else{
        echo "Nothing to be done in database $dbname.\n";
        return 0;
    }
}

function executeFiles_SQL_delete($data, $dbname, $password, $path_folder, $action, $sql_export=false)
{
    $arrFiles  = scandir("$path_folder/$action/$dbname");
    $arrFiles = sortArray($arrFiles);
    if($sql_export==false){
        if($data['engine']=="mysql")
            $command = "mysqldump -uroot -p$password $dbname > /var/libs/mysql/$dbname.".date('Ymd').".dump";
        elseif($data['engine']=="sqlite3")
            $command = 'sqlite3 '.$data['path'].'/'.$dbname.'.db ".dump" > '.$data['path']."/$dbname.".date('Ymd').".dump";
        else{
            echo "Error, wrong engine in database $dbname.\n";
            return 1;
        }
        echo "Executing $command... \n";
        exec($command,$arrConsole,$flatStatus);
        echo "RETURN $flatStatus\n";
        if($flatStatus != 0){
            echo "Error, Action $action database $dbname failed.\n";
            return 1;
        }
        if($data['engine']=="sqlite3"){
            $command = "rm -rf $data[path]/$dbname.db";
            echo "Executing $command ... \n";
            exec($command,$arrConsole,$flatStatus);
            echo "RETURN $flatStatus\n";
            if($flatStatus != 0){
                print_r($arrConsole);
                echo "Error, Action $action database $dbname failed.\n";
                return 1;
            }
            echo "Successfull, Action $action database $dbname.\n";
            return 0;
        }
    }
    if(is_array($arrFiles) && count($arrFiles)>0){
      foreach($arrFiles as $k => $file){
         if(ereg("\.sql$",$file)){
            if($sql_export==false){ 
                if($data['engine']=="mysql"){
                    $command = "mysql -uroot -p$password < $path_folder/$action/$dbname/$file";
                    echo "Executing $command ... \n";
                    exec($command,$arrConsole,$flatStatus);
                    echo "RETURN $flatStatus\n";
                    if($flatStatus != 0){
                        print_r($arrConsole);
                        echo "Error, Action $action database $dbname failed.\n";
                        return 1;
                    }
                }
          }else{
              echo  file_get_contents("$path_folder/$action/$dbname/$file");
          }
        }
      }
      if($sql_export==false && $data['engine']!="sqlite3")
          echo "Successfull, Action $action database $dbname.\n";
      return 0;
    }
    else{
        echo "Nothing to be done in database $dbname.\n";
        return 0;
    }
}

function sortArray($arrFiles)
{
    $arrSort = array();
    foreach($arrFiles as $key => $file){
        if($file[0]!="."){
            $tmp = split("_",$file);
            if(isset($tmp[0]) && isset($tmp[1]))
                $arrSort[$tmp[0]] = $file;
        }
    }
    ksort($arrSort);
    return $arrSort;
}

function esmayor($cadenainteractual,$cadenadada)
{
     $versionreleasedada=split("-",$cadenadada);
     $versionreleaseinteractual=split("-",$cadenainteractual);
     $tmpdada = split(".",$versionreleasedada[0]);
     $tmpinteractual = split(".",$versionreleaseinteractual[0]);
     $primerodado = (int)$tmpdada[0];
     $segundodado = (isset($tmpdada[1]))? (int)$tmpdada[1]:0;
     $tercerodado = (isset($tmpdada[2]))? (int)$tmpdada[2]:0;
     $primerointeractual = (int)$tmpinteractual[0];
     $segundointeractual = (isset($tmpinteractual[1]))? (int)$tmpinteractual[1]:0;
     $tercerointeractual = (isset($tmpinteractual[2]))? (int)$tmpinteractual[2]:0;
     if($primerodado<$primerointeractual)
        return true;
     if($primerodado>$primerointeractual)
        return false;
     if($segundodado<$segundointeractual)
        return true;
     if($segundodado>$segundointeractual)
        return false;
     if($tercerodado<$tercerointeractual)
        return true;
     if($tercerodado>$tercerointeractual)
        return false;
    preg_match('/^([[:digit:]]*)([alfa|beta|rc]*)$/',$versionreleasedada[1],$regsdada);
    preg_match('/^([[:digit:]]*)([alfa|beta|rc]*)$/',$versionreleaseinteractual[1],$regsactual);

    if(cursor($regsdada[2])<cursor($regsactual[2]))
        return true;
    else if(cursor($regsdada[2])==cursor($regsactual[2])) 
    {
        if((int)$regsdada[1]<(int)$regsactual[1])
            return true;
        else
            return false;
    }
    else
        return false;
}


function getData($path_folder)
{
    $arrData = parse_ini_file($path_folder."/db.info",true);
    return $arrData;
}

/*
    esta funcion lo que hace es dado un valor de alpha,beta,rc o simplemente vacio da como 
    resultado 
*/
function cursor($valor)
{    
    if($valor=="alpha")
    {
       return 1;     
    }
    else if($valor=="beta")
    {
       return 2;     
    }
    else if($valor=="rc")
    {
       return 3;     
    }
    else if($valor=="") return 4;
} 
function imprimirArreglo($value, $dbname, $version_actual,$path_folder,$data)
{
   $update="";
   //si $value['before'] es mayor a $version_actual entra en la condicion
   //pero tambien $version_actual debe ser menor que $value['current']. 
   if(esmayor($value['current'],$version_actual)){
       $update= file_get_contents("$path_folder/update/$dbname/version_sql/$value[namefile]");
       $update=$update."\n\n";
   }
   return  $update;    
}    
//en esta funcion hay que comprobar que la variable $version_actual tiene que tener el mismo formato 
//que los nombres de los archivos de actualizacion en la carpeta /setup/db/update. 
//
function updatedatabase($version_actual,$path_folder,$data,$action,$dbname)
{
    $cadenareturn= "";    
    if(is_dir($path_folder."/update/$dbname/version_sql"))
    {
        $arrFiles = scandir("$path_folder/$action/$dbname/version_sql");
        $arrFilesSort = sortArray($arrFiles);
        if(is_array($arrFilesSort) && count($arrFilesSort)>0){
            foreach($arrFilesSort as $k => $file){

                if(is_file("$path_folder/update/$dbname/version_sql/$file"))
                {
                    if($file[strlen($file)-1]!="~" &&  $file[0]!="." )
                    {                            
                        list($id,$before,$currentt)=split('_',$file);
                        list($current)=split('.sql',$currentt);
                        $arrversion=array("id"=>$id,"before"=>$before,"current"=>$current,"namefile"=>$file);
                        $cadenareturn .= imprimirArreglo($arrversion, $dbname, $version_actual,$path_folder,$data);      
                    }
                } 
            }
        }  
        return $cadenareturn;
    }
    else return null;
}

function ismysqlRunning()
{
    exec("/sbin/service mysqld status &>/dev/null",$arrConsole,$flagStatus);
    if($flagStatus == 0)
        return true;
    else
        return false;
}

function databaseExists($engine,$dbname)
{
    if($engine == "mysql"){
        return is_dir("/var/lib/mysql/$dbname");
    }
    elseif($engine == "sqlite3"){
        return file_exists("/var/www/db/$dbname.db");
    }
}
?>
