1
1
<?php
2
2
3
- backup_migrate_include ('destinations.db ' );
4
-
5
3
/**
6
4
* @file
7
5
* Functions to handle the direct to database destination.
8
6
*/
9
7
8
+ backup_migrate_include ('destinations.db ' );
9
+
10
10
/**
11
11
* A destination type for saving to a database server.
12
12
*
13
13
* @ingroup backup_migrate_destinations
14
14
*/
15
-
16
15
class backup_migrate_destination_db_mysql extends backup_migrate_destination_db {
16
+
17
+ /**
18
+ * Type name.
19
+ */
17
20
function type_name () {
18
21
return t ("MySQL Database " );
19
22
}
20
23
21
24
/**
22
- * Return a list of backup filetypes .
25
+ * Return a list of backup file types .
23
26
*/
24
27
function file_types () {
25
28
return array (
@@ -39,29 +42,31 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
39
42
}
40
43
41
44
/**
42
- * Declare any mysql databases defined in the settings.php file as a possible destination.
45
+ * Declare any databases defined in settings.php as a possible destination.
43
46
*/
44
47
function destinations () {
45
48
$ out = array ();
46
49
global $ databases ;
47
- foreach ((array )$ databases as $ db_key => $ target ) {
48
- foreach ((array )$ target as $ tgt_key => $ info ) {
50
+ foreach ((array ) $ databases as $ db_key => $ target ) {
51
+ foreach ((array ) $ target as $ tgt_key => $ info ) {
49
52
// Only mysql/mysqli supported by this destination.
50
53
$ key = $ db_key . ': ' . $ tgt_key ;
51
54
if ($ info ['driver ' ] === 'mysql ' ) {
52
55
$ url = $ info ['driver ' ] . ':// ' . $ info ['username ' ] . ': ' . $ info ['password ' ] . '@ ' . $ info ['host ' ] . (isset ($ info ['port ' ]) ? ': ' . $ info ['port ' ] : '' ) . '/ ' . $ info ['database ' ];
53
56
if ($ destination = backup_migrate_create_destination ('mysql ' , array ('url ' => $ url ))) {
54
- // Treat the default database differently because it is probably the only one available.
57
+ // Treat the default database differently because it is probably the
58
+ // only one available.
55
59
if ($ key == 'default:default ' ) {
56
60
$ destination ->set_id ('db ' );
57
61
$ destination ->set_name (t ('Default Database ' ));
58
- // Disallow backing up to the default database because that's confusing and potentially dangerous.
62
+ // Disallow backing up to the default database because that's
63
+ // confusing and potentially dangerous.
59
64
$ destination ->remove_op ('scheduled backup ' );
60
65
$ destination ->remove_op ('manual backup ' );
61
66
}
62
67
else {
63
- $ destination ->set_id ('db: ' . $ key );
64
- $ destination ->set_name ($ key .": " . $ destination ->get_display_location ());
68
+ $ destination ->set_id ('db: ' . $ key );
69
+ $ destination ->set_name ($ key . ": " . $ destination ->get_display_location ());
65
70
}
66
71
$ out [$ destination ->get_id ()] = $ destination ;
67
72
}
@@ -88,19 +93,23 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
88
93
"#type " => "checkbox " ,
89
94
"#title " => t ("Use mysqldump command " ),
90
95
"#default_value " => !empty ($ settings ['use_mysqldump ' ]),
91
- "#description " => t ("Use the mysqldump command line tool if available. This can be faster for large databases but will not work on all servers. Also exporting SQL views is not really solid with this option. EXPERIMENTAL " ),
96
+ "#description " => t ("Use the mysqldump command line tool if available.
97
+ This can be faster for large databases but will not work on all
98
+ servers. Also exporting SQL views is not really solid with this
99
+ option. EXPERIMENTAL "
100
+ ),
92
101
);
93
102
94
103
return $ form ;
95
104
}
96
105
97
-
98
106
/**
99
107
* Backup the databases to a file.
100
108
*
101
- * Returns a list of sql commands, one command per line.
102
- * That makes it easier to import without loading the whole file into memory.
103
- * The files are a little harder to read, but human-readability is not a priority
109
+ * Returns a list of sql commands, one command per line.
110
+ * That makes it easier to import without loading the whole file into memory.
111
+ * The files are a little harder to read, but human-readability is not a
112
+ * priority.
104
113
*/
105
114
function _backup_db_to_file ($ file , $ settings ) {
106
115
if (!empty ($ settings ->filters ['use_mysqldump ' ]) && $ this ->_backup_db_to_file_mysqldump ($ file , $ settings )) {
@@ -145,17 +154,15 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
145
154
}
146
155
}
147
156
148
-
149
157
/**
150
158
* Backup the databases to a file using the mysqldump command.
151
159
*/
152
160
function _backup_db_to_file_mysqldump ($ file , $ settings ) {
153
161
$ success = FALSE ;
154
162
$ nodata_tables = array ();
155
163
$ alltables = $ this ->_get_tables ();
156
-
157
-
158
164
$ command = 'mysqldump --result-file=%file --opt -Q --host=%host --port=%port --user=%user --password=%pass %db ' ;
165
+
159
166
$ args = array (
160
167
'%file ' => $ file ->filepath (),
161
168
'%host ' => $ this ->dest_url ['host ' ],
@@ -168,17 +175,17 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
168
175
// Ignore the excluded and no-data tables.
169
176
$ db = $ this ->dest_url ['path ' ];
170
177
if (!empty ($ settings ->filters ['exclude_tables ' ])) {
171
- foreach ((array )$ settings ->filters ['exclude_tables ' ] as $ table ) {
178
+ foreach ((array ) $ settings ->filters ['exclude_tables ' ] as $ table ) {
172
179
if (isset ($ alltables [$ table ])) {
173
- $ command .= ' --ignore-table= ' . $ db .'. ' . $ table ;
180
+ $ command .= ' --ignore-table= ' . $ db . '. ' . $ table ;
174
181
}
175
182
}
176
183
}
177
184
if (!empty ($ settings ->filters ['nodata_tables ' ])) {
178
- foreach ((array )$ settings ->filters ['nodata_tables ' ] as $ table ) {
185
+ foreach ((array ) $ settings ->filters ['nodata_tables ' ] as $ table ) {
179
186
if (isset ($ alltables [$ table ])) {
180
187
$ nodata_tables [] = $ table ;
181
- $ command .= ' --ignore-table= ' . $ db .'. ' . $ table ;
188
+ $ command .= ' --ignore-table= ' . $ db . '. ' . $ table ;
182
189
}
183
190
}
184
191
}
@@ -206,7 +213,8 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
206
213
return FALSE ;
207
214
}
208
215
if ($ line ) {
209
- // Prepare and execute the statement instead of the api function to avoid substitution of '{' etc.
216
+ // Prepare and execute the statement instead of the api function to
217
+ // avoid substitution of '{' etc.
210
218
$ stmt = $ conn ->prepare ($ line );
211
219
$ stmt ->execute ();
212
220
$ num ++;
@@ -222,19 +230,20 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
222
230
return $ num ;
223
231
}
224
232
225
-
226
233
/**
227
234
* Read a multiline sql command from a file.
228
235
*
229
- * Supports the formatting created by mysqldump, but won't handle multiline comments.
236
+ * Supports the formatting created by mysqldump, but won't handle multiline
237
+ * comments.
230
238
*/
231
239
function _read_sql_command_from_file ($ file ) {
232
240
$ out = '' ;
233
241
while ($ line = $ file ->read ()) {
234
242
$ first2 = substr ($ line , 0 , 2 );
235
243
$ first3 = substr ($ line , 0 , 2 );
236
244
237
- // Ignore single line comments. This function doesn't support multiline comments or inline comments.
245
+ // Ignore single line comments. This function doesn't support multiline
246
+ // comments or inline comments.
238
247
if ($ first2 != '-- ' && ($ first2 != '/* ' || $ first3 == '/*! ' )) {
239
248
$ out .= ' ' . trim ($ line );
240
249
// If a line ends in ; or */ it is a sql command.
@@ -275,9 +284,9 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
275
284
if ($ tables ) {
276
285
$ tables_escaped = array ();
277
286
foreach ($ tables as $ table ) {
278
- $ tables_escaped [] = '` ' . db_escape_table ($ table ) .'` WRITE ' ;
287
+ $ tables_escaped [] = '` ' . db_escape_table ($ table ) . '` WRITE ' ;
279
288
}
280
- $ this ->query ('LOCK TABLES ' . implode (', ' , $ tables_escaped ));
289
+ $ this ->query ('LOCK TABLES ' . implode (', ' , $ tables_escaped ));
281
290
}
282
291
}
283
292
@@ -293,11 +302,11 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
293
302
*/
294
303
function _get_tables () {
295
304
$ out = array ();
296
- // get auto_increment values and names of all tables
305
+ // Get auto_increment values and names of all tables.
297
306
$ tables = $ this ->query ("show table status " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
298
307
foreach ($ tables as $ table ) {
299
- // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default query behavior was changed.
300
- // See: http://drupal.org/node/1171866
308
+ // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default
309
+ // query behavior was changed. See: http://drupal.org/node/1171866.
301
310
$ table = array_change_key_case ($ table );
302
311
if (!empty ($ table ['engine ' ])) {
303
312
$ out [$ table ['name ' ]] = $ table ;
@@ -311,11 +320,11 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
311
320
*/
312
321
function _get_views () {
313
322
$ out = array ();
314
- // get auto_increment values and names of all tables
323
+ // Get auto_increment values and names of all tables.
315
324
$ tables = $ this ->query ("show table status " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
316
325
foreach ($ tables as $ table ) {
317
- // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default query behavior was changed.
318
- // See: http://drupal.org/node/1171866
326
+ // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default
327
+ // query behavior was changed. See: http://drupal.org/node/1171866
319
328
$ table = array_change_key_case ($ table );
320
329
if (empty ($ table ['engine ' ])) {
321
330
$ out [$ table ['name ' ]] = $ table ;
@@ -329,34 +338,36 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
329
338
*/
330
339
function _get_table_structure_sql ($ table ) {
331
340
$ out = "" ;
332
- $ result = $ this ->query ("SHOW CREATE TABLE ` " . $ table ['name ' ] ."` " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
341
+ $ result = $ this ->query ("SHOW CREATE TABLE ` " . $ table ['name ' ] . "` " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
333
342
foreach ($ result as $ create ) {
334
- // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default query behavior was changed.
335
- // See: http://drupal.org/node/1171866
343
+ // Lowercase the keys because between Drupal 7.12 and 7.13/14 the default
344
+ // query behavior was changed. See: http://drupal.org/node/1171866
336
345
$ create = array_change_key_case ($ create );
337
- $ out .= "DROP TABLE IF EXISTS ` " . $ table ['name ' ] ."`; \n" ;
338
- // Remove newlines and convert " to ` because PDO seems to convert those for some reason.
346
+ $ out .= "DROP TABLE IF EXISTS ` " . $ table ['name ' ] . "`; \n" ;
347
+ // Remove newlines and convert " to ` because PDO seems to convert those
348
+ // for some reason.
339
349
$ out .= strtr ($ create ['create table ' ], array ("\n" => ' ' , '" ' => '` ' ));
340
350
if ($ table ['auto_increment ' ]) {
341
- $ out .= " AUTO_INCREMENT= " . $ table ['auto_increment ' ];
351
+ $ out .= " AUTO_INCREMENT= " . $ table ['auto_increment ' ];
342
352
}
343
353
$ out .= "; \n" ;
344
354
}
345
355
return $ out ;
346
356
}
347
-
357
+
348
358
/**
349
359
* Get the sql for the structure of the given table.
350
360
*/
351
361
function _get_view_create_sql ($ view ) {
352
362
$ out = "" ;
353
- // Switch SQL mode to get rid of "CREATE ALGORITHM..." what requires more permissions + troubles with the DEFINER user
363
+ // Switch SQL mode to get rid of "CREATE ALGORITHM..." what requires more
364
+ // permissions + troubles with the DEFINER user.
354
365
$ sql_mode = $ this ->query ("SELECT @@SESSION.sql_mode " )->fetchField ();
355
366
$ this ->query ("SET sql_mode = 'ANSI' " );
356
367
$ result = $ this ->query ("SHOW CREATE VIEW ` " . $ view ['name ' ] . "` " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
357
368
$ this ->query ("SET SQL_mode = :mode " , array (':mode ' => $ sql_mode ));
358
369
foreach ($ result as $ create ) {
359
- $ out .= "DROP VIEW IF EXISTS ` " . $ view ['name ' ] ."`; \n" ;
370
+ $ out .= "DROP VIEW IF EXISTS ` " . $ view ['name ' ] . "`; \n" ;
360
371
$ out .= "SET sql_mode = 'ANSI'; \n" ;
361
372
$ out .= strtr ($ create ['Create View ' ], "\n" , " " ) . "; \n" ;
362
373
$ out .= "SET sql_mode = ' $ sql_mode'; \n" ;
@@ -365,47 +376,46 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
365
376
}
366
377
367
378
/**
368
- * Get the sql to insert the data for a given table
379
+ * Get the sql to insert the data for a given table.
369
380
*/
370
381
function _dump_table_data_sql_to_file ($ file , $ table ) {
371
- $ rows_per_line = config_get ('backup_migrate.settings ' ,'backup_migrate_data_rows_per_line ' );
372
- $ bytes_per_line = config_get ('backup_migrate.settings ' ,'backup_migrate_data_bytes_per_line ' );
373
-
382
+ $ rows_per_line = config_get ('backup_migrate.settings ' , 'backup_migrate_data_rows_per_line ' );
383
+ $ bytes_per_line = config_get ('backup_migrate.settings ' , 'backup_migrate_data_bytes_per_line ' );
374
384
$ lines = 0 ;
375
- $ data = $ this ->query ("SELECT * FROM ` " . $ table ['name ' ] ."` " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
385
+ $ data = $ this ->query ("SELECT * FROM ` " . $ table ['name ' ] . "` " , array (), array ('fetch ' => PDO ::FETCH_ASSOC ));
376
386
$ rows = $ bytes = 0 ;
377
387
378
- // Escape backslashes, PHP code, special chars
388
+ // Escape backslashes, PHP code, special chars.
379
389
$ search = array ('\\' , "' " , "\x00" , "\x0a" , "\x0d" , "\x1a" );
380
390
$ replace = array ('\\\\' , "'' " , '\0 ' , '\n ' , '\r ' , '\Z ' );
381
-
391
+
382
392
$ line = array ();
383
393
foreach ($ data as $ row ) {
384
394
// DB Escape the values.
385
395
$ items = array ();
386
396
foreach ($ row as $ key => $ value ) {
387
- $ items [] = is_null ($ value ) ? "null " : "' " . str_replace ($ search , $ replace , $ value ) ."' " ;
397
+ $ items [] = is_null ($ value ) ? "null " : "' " . str_replace ($ search , $ replace , $ value ) . "' " ;
388
398
}
389
-
399
+
390
400
// If there is a row to be added.
391
401
if ($ items ) {
392
402
// Start a new line if we need to.
393
403
if ($ rows == 0 ) {
394
- $ file ->write ("INSERT INTO ` " . $ table ['name ' ] ."` VALUES " );
404
+ $ file ->write ("INSERT INTO ` " . $ table ['name ' ] . "` VALUES " );
395
405
$ bytes = $ rows = 0 ;
396
406
}
397
407
// Otherwise add a comma to end the previous entry.
398
408
else {
399
409
$ file ->write (", " );
400
410
}
401
-
411
+
402
412
// Write the data itself.
403
413
$ sql = implode (', ' , $ items );
404
- $ file ->write ('( ' . $ sql .') ' );
414
+ $ file ->write ('( ' . $ sql . ') ' );
405
415
$ bytes += strlen ($ sql );
406
416
$ rows ++;
407
-
408
- // Finish the last line if we've added enough items
417
+
418
+ // Finish the last line if we've added enough items.
409
419
if ($ rows >= $ rows_per_line || $ bytes >= $ bytes_per_line ) {
410
420
$ file ->write ("; \n" );
411
421
$ lines ++;
@@ -418,7 +428,7 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
418
428
$ file ->write ("; \n" );
419
429
$ lines ++;
420
430
}
421
-
431
+
422
432
return $ lines ;
423
433
}
424
434
@@ -442,34 +452,34 @@ class backup_migrate_destination_db_mysql extends backup_migrate_destination_db
442
452
}
443
453
444
454
/**
445
- * The header for the top of the sql dump file. These commands set the connection
446
- * character encoding to help prevent encoding conversion issues.
455
+ * The header for the top of the sql dump file.
456
+ *
457
+ * These commands set the connection character encoding to help prevent
458
+ * encoding conversion issues.
447
459
*/
448
460
function _get_sql_file_header () {
449
461
return "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
450
- /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
451
- /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
452
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
453
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
454
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;
455
-
456
- SET NAMES utf8;
457
-
458
- " ;
462
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
463
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
464
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
465
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
466
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;
467
+ SET NAMES utf8;
468
+ " ;
459
469
}
460
-
470
+
461
471
/**
462
472
* The footer of the sql dump file.
463
473
*/
464
474
function _get_sql_file_footer () {
465
475
return "
466
-
467
- /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
468
- /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
469
- /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
470
- /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
471
- /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
472
- /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
473
- " ;
476
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
477
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
478
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
479
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
480
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
481
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
482
+ " ;
474
483
}
484
+
475
485
}
0 commit comments