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