DataObjects/Builder_tables.php
[Pman.Builder] / DataObjects / Builder_tables.php
1 <?php
2 /**
3  * Table Definition for builder_tables
4  */
5 require_once 'DB/DataObject.php';
6
7 class Pman_Builder_DataObjects_Builder_tables extends DB_DataObject 
8 {
9     ###START_AUTOCODE
10     /* the code below is auto generated do not remove the above tag */
11
12     public $__table = 'builder_tables';      // table name
13     public $id;                              // int(11)  not_null primary_key auto_increment
14     public $name;                            // string(128)  not_null
15     public $descrip;                         // string(254)  not_null
16     public $parent_id;                       // int(11)  not_null multiple_key
17     public $dbschema;                        // blob(65535)  not_null blob
18
19     
20     /* the code above is auto generated do not remove the tag below */
21     ###END_AUTOCODE
22     
23     
24     function applyFilters($q, $au)
25     {
26         //DB_DataObject::debugLEvel(1);
27         if (!empty($q['_sync'])) {
28             $this->syncDatabase();
29             HTML_FlexyFramework::get()->page->jok("DONE");
30         }
31         
32         if(!empty($q['_dumpTable'])){
33             $this->dumpTable($q['_dump']);
34         }
35        
36     }
37     
38     function syncDatabase()
39     {
40         //DB_DataObject::debugLevel(1);
41         global $_DB_DATAOBJECT;
42         $x = DB_DataObject::factory('builder_tables');
43         $x->whereAdd("name != ''"); // real tables only..
44         $mine = $this->fetchAll('name', 'id');
45         
46         // ensure everything is loaded...
47         $tq = DB_DataObject::factory('builder_tables');
48         $tq->table();
49         $tq->links();
50         $tables = $_DB_DATAOBJECT['INI'][$tq->_database];
51         
52          
53         $ret = array();
54         $t = array_keys($tables);
55         sort($t);
56         
57         
58         // for postgres we can get descriptions - this should just fail in Mysql..
59         $desc= array();
60         $dsn = HTML_FlexyFramework::get()->database;
61         
62         if (preg_match('/^pgsql:/', $dsn )) {
63             $tq = DB_DataObject::factory('builder_tables');
64             $tq->query( "
65                 select relname, obj_description( oid) as desc FROM pg_catalog.pg_class
66                 ");
67             while ($tq->fetch()) {
68                 $desc[$tq->relname] = $tq->desc;
69             }
70         }
71         //   DB_DataObjecT::DebugLevel(1);
72         $tq = DB_DataObject::factory('builder_tables');
73         
74         require_once 'Services/JSON.php';
75         
76         $modids = array();
77         
78         
79         foreach( $t as $k) {
80             if (preg_match('/__keys$/', $k)) {
81                 continue;
82             }
83             // check it can be constructed..
84             // this might be problematic for 'new' tables...
85             $do = DB_DataObject::factory($k);
86             if (!is_a($do,'DB_DataObject')) {
87                 continue;
88             }
89             
90             // get's the module part out of the dataobject class name
91             // assumes '_' is not used in module name.
92             $mod = array_pop(
93                     explode('_',
94                         substr(get_class($do), 0, -1 * (strlen('_DataObject_') + strlen($k)+ 1))
95                     ));
96              
97             // should get 'ZZZ' part.. : XXX_ZZZZ_DataObject_xx_Builder
98             if (!isset($modids[$mod])) {
99                 $x = DB_DataObject::factory('builder_tables');
100                 $x->parent_id =0;
101                 $x->name = '';
102                 $x->descrip = $mod;
103                 $x->dbschema = '';
104                 if (!$x->find(true)) {
105                     $x->insert();
106                 } 
107                  $modids[$mod] = $x->id; 
108                 
109             }
110             
111             
112             
113             $set = array(
114                 'name' => $k,
115                 'descrip' => isset($desc[$k]) ? $desc[$k] : '',
116                 'dbschema' => Services_JSON::stringify($this->tableSchema($k),null,4),
117                // 'parent_id' =>  $modids[$mod],
118             );
119             
120             $do = clone($tq);
121             if (isset($mine[$k])) { 
122                 $do->get($mine[$k]);
123                 $dd = clone($do);
124                 $do->setFrom($set);
125                 if (empty($do->parent_id) || $do->parent_id < 1) {
126                     // allow user to modify this..
127                     $do->parent_id = $modids[$mod];
128                 }
129                 $do->update($dd);
130                 continue;
131             }
132             
133             $do->setFrom($set);
134             $do->parent_id = $modids[$mod];
135             $do->insert();
136         
137         }
138             
139         
140         
141     }
142     
143     
144     function tableSchema($tn)
145     {
146         static  $cache = array();
147         static  $types= array();
148         $do = DB_DataObject::factory($tn);
149         $tn = $do->tableName(); // cleaned up!
150
151
152         if (isset($cache[$tn])) {
153             return $cache[$tn];
154         }
155
156         // get a description if available..
157        
158              
159         $desc = array();
160         $dd = clone($do);
161         $dsn = HTML_FlexyFramework::get()->database;
162         if (preg_match('/^pgsql:/', $dsn)) {
163             
164             
165            // DB_DataObject::DebugLevel(1);
166             $dd->query("SELECT
167                     c.column_name as name,
168                     pgd.description as desc
169                 FROM pg_catalog.pg_statio_all_tables as st
170                     inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid)
171                     inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position and c.table_schema=st.schemaname and c.table_name=st.relname)
172                 WHERE
173                     c.table_schema = 'public' and c.table_name = '{$tn}'
174             ");
175             while($dd->fetch()) {
176                 $desc[$dd->name] = $dd->desc;
177             }
178         }
179         $defs =  $dd->getDatabaseConnection()->tableInfo($tn);
180         // add descriptions?
181         foreach($defs as $i=>$c) {
182             $defs[$i]['desc'] = isset($desc[$c['name']]) ? $desc[$c['name']] : '';
183         }
184         $cache[$tn]= $defs;
185      
186         return $cache[$tn];
187     }
188     
189     function dumpTable($tn)
190     {
191         $roo = HTML_FlexyFramework::get()->page;
192         
193         if(empty($tn)){
194             return;
195         }
196         
197         $do = DB_DataObject::factory($tn);
198         if (!is_a($do,'DB_DataObject')) {
199             return;
200         }
201         
202         $dsn = HTML_FlexyFramework::get()->database;
203         
204         $database = explode('@', $dsn);
205         
206         $ui = str_replace('mysql://', '', $database[0]);
207         
208         $user = array_shift(explode(':', $ui));
209         $pw = array_pop(explode(':', $ui));
210         
211         $host = array_shift(explode('/', $database[1]));
212         $dn = array_pop(explode('/', $database[1]));
213         
214         $cmd = "mysqldump -u{$user} ";
215         if(!empty($pw)){
216             $cmd .= "-p{$pw} ";
217         }
218         
219         $cmd .= "--no-create-info summit {$tn}";
220         
221         require_once 'System.php';
222             
223         $tmpdir  = System::mktemp("-d dump");
224
225         $path = $tmpdir . '/' . $tn . '.sql';
226         
227         ob_start();
228         
229         passthru($cmd);
230         
231         $data = ob_get_contents();
232         
233         ob_end_clean();
234         
235         file_put_contents($path, $data);
236         
237         header('Content-Description: File Transfer');
238         header ('Content-Type: application/octet-stream');
239         header("Content-Disposition: attachment; filename=\"".basename($path)."\";" );
240         header("Expires: 0");
241         header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
242         header("Pragma: public");
243         header('Content-Length: ' . filesize($path));
244         
245         @ob_clean();
246         flush();
247         readfile($path);
248         
249         exit;
250             
251         
252     }
253     
254 }