UpdateDatabase.php
[Pman.Core] / UpdateDatabase.php
1 <?php
2
3 /**
4  *
5  * This applies database files from
6  * a) OLD - {MODULE}/DataObjects/XXXX.{dbtype}.sql
7  *
8  * b) NEW - {MODULE}/sql/XXX.sql (SHARED or translable)
9  *  and {MODULE}/{dbtype}/XXX.sql (SHARED or translable)
10  *
11  *
12  */
13
14 require_once 'Pman.php';
15 class Pman_Core_UpdateDatabase extends Pman
16 {
17     
18     static $cli_desc = "Update SQL - Beta (it will run updateData of all modules)";
19  
20     static $cli_opts = array(
21         'source' => array(
22             'desc' => 'Source directory for json files.',
23             'short' => 'f',
24             'default' => '',
25             'min' => 1,
26             'max' => 1,
27         ),
28         'prefix' => array(
29             'desc' => 'prefix for the passwrod',
30             'short' => 'p',
31             'default' => '',
32             'min' => 1,
33             'max' => 1,
34         ),
35         
36     );
37     
38     var $cli = false;
39     function getAuth() {
40         
41         
42         $ff = HTML_FlexyFramework::get();
43         if (!empty($ff->cli)) {
44             $this->cli = true;
45             return true;
46         }
47         
48         parent::getAuth(); // load company!
49         $au = $this->getAuthUser();
50         if (!$au || $au->company()->comptype != 'OWNER') {
51             $this->jerr("Not authenticated", array('authFailure' => true));
52         }
53         $this->authUser = $au;
54         return true;
55     }
56      
57     function get($args, $opt)
58     {
59         if($args == 'Person'){
60             print_r($opt);exit;
61         }
62         $this->importSQL();
63         $this->runUpdateModulesData();
64          
65     }
66     function output() {
67         return '';
68     }
69      /**
70      * imports SQL files from all DataObjects directories....
71      * 
72      * except any matching /migrate/
73      */
74     function importSQL()
75     {
76         
77         $ff = HTML_Flexyframework::get();
78         
79         $url = parse_url($ff->DB_DataObject['database']);
80         
81         $this->{'import' . $url['scheme']}($url);
82         
83     }
84     
85     /**
86      * mysql - does not support conversions.
87      * 
88      *
89      */
90     
91     
92     
93     function importmysql($url)
94     {
95         
96         // hide stuff for web..
97         
98         require_once 'System.php';
99         $cat = System::which('cat');
100         $mysql = System::which('mysql');
101         
102         $ar = $this->modulesList();
103         
104            
105         $mysql_cmd = $mysql .
106             ' -h ' . $url['host'] .
107             ' -u' . escapeshellarg($url['user']) .
108             (!empty($url['pass']) ? ' -p' . escapeshellarg($url['pass'])  :  '') .
109             ' ' . basename($url['path']);
110         echo $mysql_cmd . "\n" ;
111         
112         
113         // old -- DAtaObjects/*.sql
114         
115         foreach($ar as $m) {
116             
117             $fd = $this->rootDir. "/Pman/$m/DataObjects";
118             
119             foreach(glob($fd.'/*.sql') as $fn) {
120                 
121                  
122                 if (preg_match('/migrate/i', basename($fn))) { // skip migration scripts at present..
123                     continue;
124                 }
125                 // .my.sql but not .pg.sql
126                 if (preg_match('#\.[a-z]{2}\.sql#i', basename($fn))
127                     && !preg_match('#\.my\.sql#i', basename($fn))
128                 ) { // skip migration scripts at present..
129                     continue;
130                 }
131                 $cmd = "$mysql_cmd -f < " . escapeshellarg($fn) ;
132                 
133                 echo $cmd. ($this->cli ? "\n" : "<BR>\n");
134                 
135                 passthru($cmd);
136             
137                 
138             }
139             // new -- sql directory..
140             // new style will not support migrate ... they have to go into mysql-migrate.... directories..
141             // new style will not support pg.sql etc.. naming - that's what the direcotries are for..
142             $fd = $this->rootDir. "/Pman/$m/sql";
143             
144             foreach(glob($fd.'/*.sql') as $fn) {
145                 $cmd = "$mysql_cmd -f < " . escapeshellarg($fn) ;
146                 echo $cmd. ($this->cli ? "\n" : "<BR>\n");
147                 passthru($cmd);
148             }
149             $fd = $this->rootDir. "/Pman/$m/mysql";
150             
151             foreach(glob($fd.'/*.sql') as $fn) {
152                 $cmd = "$mysql_cmd -f < " . escapeshellarg($fn) ;
153                 echo $cmd. ($this->cli ? "\n" : "<BR>\n");
154                 passthru($cmd);
155             }
156               
157             
158             
159             
160             
161             
162         }
163         
164         
165         
166     }
167     /**
168      * postgresql import..
169      */
170     function importpgsql($url)
171     {
172         
173         // hide stuff for web..
174         
175         require_once 'System.php';
176         $cat = System::which('cat');
177         $psql = System::which('psql');
178         
179         $ar = $this->modulesList();
180         
181         if (!empty($url['pass'])) { 
182             putenv("PGPASSWORD=". $url['pass']);
183         }
184            
185         $psql_cmd = $psql .
186             ' -h ' . $url['host'] .
187             ' -U' . escapeshellarg($url['user']) .
188              ' ' . basename($url['path']);
189         echo $psql_cmd . "\n" ;
190         
191         
192         
193         
194         foreach($ar as $m) {
195             
196             $fd = $this->rootDir. "/Pman/$m/DataObjects";
197             
198             foreach(glob($fd.'/*.sql') as $bfn) {
199                 
200                  
201                 if (preg_match('/migrate/i', basename($bfn))) { // skip migration scripts at present..
202                     continue;
203                 }
204                 if (preg_match('#\.[a-z]{2}\.sql#i', basename($bfn))
205                     && !preg_match('#\.pg\.sql#i', basename($bfn))
206                 ) { // skip migration scripts at present..
207                     continue;
208                 }
209                 // files ending in .pg.sql are native postgres files..
210                 $fn = preg_match('#\.pg\.sql$#', basename($bfn)) ? false : $this->convertToPG($bfn);
211                 
212                 $cmd = "$psql_cmd  < " . escapeshellarg($fn ? $fn : $bfn) . ' 2>&1' ;
213                 
214                 echo "$bfn:   $cmd ". ($this->cli ? "\n" : "<BR>\n");
215                 
216                 
217                 passthru($cmd);
218                 
219                 if ($fn) {
220                     unlink($fn);
221                 }
222             }
223             
224             
225             
226             $fd = $this->rootDir. "/Pman/$m/sql";
227             // sql directory  - we try to convert..
228             foreach(glob($fd.'/*.sql') as $bfn) {
229                 $fn =  $this->convertToPG($bfn);
230                 $cmd = "$psql_cmd  < " . escapeshellarg($fn) ;
231                 echo $cmd. ($this->cli ? "\n" : "<BR>\n");
232                 passthru($cmd);
233             }
234             
235             // postgres specific directory..
236             
237             $fd = $this->rootDir. "/Pman/$m/pgsql";
238             
239             foreach(glob($fd.'/*.sql') as $fn) {
240                 $cmd = "$psql_cmd   < " . escapeshellarg($fn) ;
241                 echo $cmd. ($this->cli ? "\n" : "<BR>\n");
242                 passthru($cmd);
243             }
244             
245             
246             
247         }
248         
249     }
250     /**
251      * simple regex based convert mysql to pgsql...
252      */
253     function convertToPG($src)
254     {
255         $fn = $this->tempName('sql');
256         
257         $ret = array( ); // pad it a bit.
258         $extra = array("", "" );
259         
260         $tbl = false;
261         foreach(file($src) as $l) {
262             $l = trim($l);
263             
264             if (!strlen($l) || $l[0] == '#') {
265                 continue;
266             }
267             $m = array();
268             if (preg_match('#create\s+table\s+([a-z0-9_]+)#i',  $l, $m)) {
269                 $tbl = $m[1];
270                // $extra[]  =   "drop table {$tbl};";
271              }
272             // autoinc
273             if ($tbl && preg_match('#auto_increment#i',  $l, $m)) {
274                 $l = preg_replace('#auto_increment#i', "default nextval('{$tbl}_seq')", $l);
275                 $extra[]  =   "create sequence {$tbl}_seq;";
276               
277             }
278             $m = array();
279             if (preg_match('#alter\s+table\s+([a-z0-9_]+)\s+add\s+index\s+([^(]+)(.*)$#i',  $l, $m)) {
280                $l = "CREATE INDEX  {$m[1]}_{$m[2]} ON {$m[1]} {$m[3]}";
281              }
282             // ALTER TABLE core_event_audit ADD     INDEX looku
283             // CREATE INDEX 
284             
285             // basic types..
286             $l = preg_replace('#int\([0-9]+\)#i', 'INT', $l);
287             
288             $l = preg_replace('# datetime #i', ' TIMESTAMP WITHOUT TIME ZONE ', $l);
289             $l = preg_replace('# blob #i', ' TEXT ', $l);
290              $l = preg_replace('# longtext #i', ' TEXT ', $l);
291             //$l = preg_match('#int\([0-9]+\)#i', 'INT', $l);
292                             
293             $ret[] = $l;
294             
295             
296             
297             
298             
299             
300             
301         }
302         $ret = array_merge($extra,$ret);
303         
304         //echo implode("\n", $ret); //exit;
305         file_put_contents($fn, implode("\n", $ret));
306         
307         return $fn;
308     }
309     
310     function runUpdateModulesData()
311     {
312         $this->updateData();
313         $modules = $this->modulesList();
314         foreach ($modules as $module){
315             $file = $this->rootDir. "/Pman/$module/UpdateDatabase.php";
316             if($module == 'Core' || !file_exists($file)){
317                 continue;
318             }
319             require_once $file;
320             $class = "Pman_{$module}_UpdateDatabase";
321             $x = new $class;
322             if(!method_exists($x, 'updateData')){
323                 continue;
324             };
325             $x->updateData();
326         }
327                 
328     }
329     
330     function updateData()
331     {
332         // fill i18n data..
333         
334         $enum = DB_DataObject::Factory('core_enum');
335         $enum->initEnums(
336             array(
337                 array(
338                     'etype' => '',
339                     'name' => 'COMPTYPE',
340                     'display_name' =>  'Company Types',
341                     'cn' => array(
342                         array(
343                             'name' => 'OWNER',
344                             'display_name' => 'Owner',
345                             'seqid' => 999, // last...
346                         )
347                         
348                     )
349                 )
350             )
351         ); 
352     }
353     
354     
355 }