source: extensions/autoupdate/include/mysqldump.php @ 6167

Last change on this file since 6167 was 6167, checked in by patdenice, 14 years ago

Upgrade work for 2.1.
Language keys have not been inserted yet.

File size: 11.1 KB
Line 
1<?php
2/**
3* Dump MySQL database
4*
5* Here is an inline example:
6* <code>
7* $connection = @mysql_connect($dbhost,$dbuser,$dbpsw);
8* $dumper = new MySQLDump($dbname,'filename.sql',false,false);
9* $dumper->doDump();
10* </code>
11*
12* Special thanks to:
13* - Andrea Ingaglio <andrea@coders4fun.com> helping in development of all class code
14* - Dylan Pugh for precious advices halfing the size of the output file and for helping in debug
15*
16* @name    MySQLDump
17* @author  Daniele Viganò - CreativeFactory.it <daniele.vigano@creativefactory.it>
18* @version 2.20 - 02/11/2007
19* @license http://opensource.org/licenses/gpl-license.php GNU Public License
20*/
21
22class MySQLDump {
23        /**
24        * @access private
25        */
26        var $database = null;
27
28        /**
29        * @access private
30        */
31        var $compress = false;
32
33        /**
34        * @access private
35        */
36        var $hexValue = false;
37
38  /**
39        * The output filename
40        * @access private
41        */
42        var $filename = null;
43
44        /**
45        * The pointer of the output file
46        * @access private
47        */
48        var $file = null;
49
50        /**
51        * @access private
52        */
53        var $isWritten = false;
54
55        /**
56        * Class constructor
57        * @param string $db The database name
58        * @param string $filepath The file where the dump will be written
59        * @param boolean $compress It defines if the output file is compress (gzip) or not
60        * @param boolean $hexValue It defines if the outup values are base-16 or not
61        */
62        function MYSQLDump($db = null, $filepath = 'dump.sql', $compress = false, $hexValue = false){
63                $this->compress = $compress;
64                if ( !$this->setOutputFile($filepath) )
65                        return false;
66                return $this->setDatabase($db);
67        }
68
69        /**
70        * Sets the database to work on
71        * @param string $db The database name
72        */
73        function setDatabase($db){
74                $this->database = $db;
75                if ( !@mysql_select_db($this->database) )
76                        return false;
77                return true;
78  }
79
80        /**
81        * Returns the database where the class is working on
82        * @return string
83        */
84  function getDatabase(){
85                return $this->database;
86        }
87
88        /**
89        * Sets the output file type (It can be made only if the file hasn't been already written)
90        * @param boolean $compress If it's true, the output file will be compressed
91        */
92        function setCompress($compress){
93                if ( $this->isWritten )
94                        return false;
95                $this->compress = $compress;
96                $this->openFile($this->filename);
97                return true;
98  }
99
100        /**
101        * Returns if the output file is or not compressed
102        * @return boolean
103        */
104  function getCompress(){
105                return $this->compress;
106        }
107
108        /**
109        * Sets the output file
110        * @param string $filepath The file where the dump will be written
111        */
112        function setOutputFile($filepath){
113                if ( $this->isWritten )
114                        return false;
115                $this->filename = $filepath;
116                $this->file = $this->openFile($this->filename);
117                return $this->file;
118  }
119
120  /**
121        * Returns the output filename
122        * @return string
123        */
124  function getOutputFile(){
125                return $this->filename;
126        }
127
128        /**
129        * Writes to file the $table's structure
130        * @param string $table The table name
131        */
132  function getTableStructure($table){
133                if ( !$this->setDatabase($this->database) )
134                        return false;
135                // Structure Header
136                $structure = "-- \n";
137                $structure .= "-- Table structure for table `{$table}` \n";
138                $structure .= "-- \n\n";
139                // Dump Structure
140                $structure .= 'DROP TABLE IF EXISTS `'.$table.'`;'."\n";
141                $structure .= "CREATE TABLE `".$table."` (\n";
142                $records = @mysql_query('SHOW FIELDS FROM `'.$table.'`');
143                if ( @mysql_num_rows($records) == 0 )
144                        return false;
145                while ( $record = mysql_fetch_assoc($records) ) {
146                        $structure .= '`'.$record['Field'].'` '.$record['Type'];
147                        if ( !empty($record['Default']) )
148                                $structure .= ' DEFAULT \''.$record['Default'].'\'';
149                        if ( @strcmp($record['Null'],'YES') != 0 )
150                                $structure .= ' NOT NULL';
151                        if ( !empty($record['Extra']) )
152                                $structure .= ' '.$record['Extra'];
153                        $structure .= ",\n";
154                }
155                $structure = @ereg_replace(",\n$", null, $structure);
156
157                // Save all Column Indexes
158                $structure .= $this->getSqlKeysTable($table);
159                $structure .= "\n)";
160
161                //Save table engine
162                $records = @mysql_query("SHOW TABLE STATUS LIKE '".$table."'");
163
164                if ( $record = @mysql_fetch_assoc($records) ) {
165                        if ( !empty($record['Engine']) )
166                                $structure .= ' ENGINE='.$record['Engine'];
167                        if ( !empty($record['Auto_increment']) )
168                                $structure .= ' AUTO_INCREMENT='.$record['Auto_increment'];
169                }
170
171                $structure .= ";\n\n-- --------------------------------------------------------\n\n";
172                $this->saveToFile($this->file,$structure);
173        }
174
175        /**
176        * Writes to file the $table's data
177        * @param string $table The table name
178        * @param boolean $hexValue It defines if the output is base 16 or not
179        */
180        function getTableData($table,$hexValue = true) {
181                if ( !$this->setDatabase($this->database) )
182                        return false;
183                // Header
184                $data = "-- \n";
185                $data .= "-- Dumping data for table `$table` \n";
186                $data .= "-- \n\n";
187
188                $records = mysql_query('SHOW FIELDS FROM `'.$table.'`');
189                $num_fields = @mysql_num_rows($records);
190                if ( $num_fields == 0 )
191                        return false;
192                // Field names
193                $selectStatement = "SELECT ";
194                $insertStatement = "INSERT INTO `$table` (";
195                $hexField = array();
196                for ($x = 0; $x < $num_fields; $x++) {
197                        $record = @mysql_fetch_assoc($records);
198                        if ( ($hexValue) && ($this->isTextValue($record['Type'])) ) {
199                                $selectStatement .= 'HEX(`'.$record['Field'].'`)';
200                                $hexField [$x] = true;
201                        }
202                        else
203                                $selectStatement .= '`'.$record['Field'].'`';
204                        $insertStatement .= '`'.$record['Field'].'`';
205                        $insertStatement .= ", ";
206                        $selectStatement .= ", ";
207                }
208                $insertStatement = @substr($insertStatement,0,-2).') VALUES';
209                $selectStatement = @substr($selectStatement,0,-2).' FROM `'.$table.'`';
210
211                $records = @mysql_query($selectStatement);
212                $num_rows = @mysql_num_rows($records);
213                $num_fields = @mysql_num_fields($records);
214                // Dump data
215                if ( $num_rows > 0 ) {
216                        $data .= $insertStatement;
217                        for ($i = 0; $i < $num_rows; $i++) {
218                                $record = @mysql_fetch_assoc($records);
219                                $data .= ' (';
220                                for ($j = 0; $j < $num_fields; $j++) {
221                                        $field_name = @mysql_field_name($records, $j);
222                                        if ( @$hexField[$j] && (@strlen($record[$field_name]) > 0) )
223                                                $data .= "0x".$record[$field_name];
224                                        else
225                                                $data .= "'".@str_replace('\"','"',@mysql_escape_string($record[$field_name]))."'";
226                                        $data .= ',';
227                                }
228                                $data = @substr($data,0,-1).")";
229                                $data .= ( $i < ($num_rows-1) ) ? ',' : ';';
230                                $data .= "\n";
231                                //if data in greather than 1MB save
232                                if (strlen($data) > 1048576) {
233                                        $this->saveToFile($this->file,$data);
234                                        $data = '';
235                                }
236                        }
237                        $data .= "\n-- --------------------------------------------------------\n\n";
238                        $this->saveToFile($this->file,$data);
239                }
240        }
241
242  /**
243        * Writes to file all the selected database tables structure
244        * @return boolean
245        */
246        function getDatabaseStructure(){
247                $records = @mysql_query('SHOW TABLES');
248                if ( @mysql_num_rows($records) == 0 )
249                        return false;
250    $structure = '';
251                while ( $record = @mysql_fetch_row($records) ) {
252                        $structure .= $this->getTableStructure($record[0]);
253                }
254                return true;
255  }
256
257        /**
258        * Writes to file all the selected database tables data
259        * @param boolean $hexValue It defines if the output is base-16 or not
260        */
261        function getDatabaseData($hexValue = true){
262                $records = @mysql_query('SHOW TABLES');
263                if ( @mysql_num_rows($records) == 0 )
264                        return false;
265                while ( $record = @mysql_fetch_row($records) ) {
266                        $this->getTableData($record[0],$hexValue);
267                }
268  }
269
270        /**
271        * Writes to file the selected database dump
272        */
273        function doDump() {
274                $this->saveToFile($this->file,"SET FOREIGN_KEY_CHECKS = 0;\n\n");
275                $this->getDatabaseStructure();
276                $this->getDatabaseData($this->hexValue);
277                $this->saveToFile($this->file,"SET FOREIGN_KEY_CHECKS = 1;\n\n");
278                $this->closeFile($this->file);
279                return true;
280        }
281       
282        /**
283        * @deprecated Look at the doDump() method
284        */
285        function writeDump($filename) {
286                if ( !$this->setOutputFile($filename) )
287                        return false;
288                $this->doDump();
289    $this->closeFile($this->file);
290    return true;
291        }
292
293        /**
294        * @access private
295        */
296        function getSqlKeysTable ($table) {
297                $primary = "";
298                $unique = array();
299                $index = array();
300                $fulltext = array();
301                $results = mysql_query("SHOW KEYS FROM `{$table}`");
302                if ( @mysql_num_rows($results) == 0 )
303                        return false;
304                while($row = mysql_fetch_object($results)) {
305                        if (($row->Key_name == 'PRIMARY') AND ($row->Index_type == 'BTREE')) {
306                                if ( $primary == "" )
307                                        $primary = "  PRIMARY KEY  (`{$row->Column_name}`";
308                                else
309                                        $primary .= ", `{$row->Column_name}`";
310                        }
311                        if (($row->Key_name != 'PRIMARY') AND ($row->Non_unique == '0') AND ($row->Index_type == 'BTREE')) {
312                                if ( (empty($unique)) OR (empty($unique[$row->Key_name])) )
313                                        $unique[$row->Key_name] = "  UNIQUE KEY `{$row->Key_name}` (`{$row->Column_name}`";
314                                else
315                                        $unique[$row->Key_name] .= ", `{$row->Column_name}`";
316                        }
317                        if (($row->Key_name != 'PRIMARY') AND ($row->Non_unique == '1') AND ($row->Index_type == 'BTREE')) {
318                                if ( (empty($index)) OR (empty($index[$row->Key_name])) )
319                                        $index[$row->Key_name] = "  KEY `{$row->Key_name}` (`{$row->Column_name}`";
320                                else
321                                        $index[$row->Key_name] .= ", `{$row->Column_name}`";
322                        }
323                        if (($row->Key_name != 'PRIMARY') AND ($row->Non_unique == '1') AND ($row->Index_type == 'FULLTEXT')) {
324                                if ( (empty($fulltext)) OR (empty($fulltext[$row->Key_name])) )
325                                        $fulltext[$row->Key_name] = "  FULLTEXT `{$row->Key_name}` (`{$row->Column_name}`";
326                                else
327                                        $fulltext[$row->Key_name] .= ", `{$row->Column_name}`";
328                        }
329                }
330                $sqlKeyStatement = '';
331                // generate primary, unique, key and fulltext
332                if ( $primary != "" ) {
333                        $sqlKeyStatement .= ",\n";
334                        $primary .= ")";
335                        $sqlKeyStatement .= $primary;
336                }
337                if (!empty($unique)) {
338                        foreach ($unique as $keyName => $keyDef) {
339                                $sqlKeyStatement .= ",\n";
340                                $keyDef .= ")";
341                                $sqlKeyStatement .= $keyDef;
342
343                        }
344                }
345                if (!empty($index)) {
346                        foreach ($index as $keyName => $keyDef) {
347                                $sqlKeyStatement .= ",\n";
348                                $keyDef .= ")";
349                                $sqlKeyStatement .= $keyDef;
350                        }
351                }
352                if (!empty($fulltext)) {
353                        foreach ($fulltext as $keyName => $keyDef) {
354                                $sqlKeyStatement .= ",\n";
355                                $keyDef .= ")";
356                                $sqlKeyStatement .= $keyDef;
357                        }
358                }
359                return $sqlKeyStatement;
360        }
361
362  /**
363        * @access private
364        */
365        function isTextValue($field_type) {
366                switch ($field_type) {
367                        case "tinytext":
368                        case "text":
369                        case "mediumtext":
370                        case "longtext":
371                        case "binary":
372                        case "varbinary":
373                        case "tinyblob":
374                        case "blob":
375                        case "mediumblob":
376                        case "longblob":
377                                return True;
378                                break;
379                        default:
380                                return False;
381                }
382        }
383       
384        /**
385        * @access private
386        */
387        function openFile($filename) {
388                $file = false;
389                if ( $this->compress )
390                        $file = @gzopen($filename, "w9");
391                else
392                        $file = @fopen($filename, "w");
393                return $file;
394        }
395
396  /**
397        * @access private
398        */
399        function saveToFile($file, $data) {
400                if ( $this->compress )
401                        @gzwrite($file, $data);
402                else
403                        @fwrite($file, $data);
404                $this->isWritten = true;
405        }
406
407  /**
408        * @access private
409        */
410        function closeFile($file) {
411                if ( $this->compress )
412                        @gzclose($file);
413                else
414                        @fclose($file);
415        }
416}
417?>
Note: See TracBrowser for help on using the repository browser.