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