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