Skip to content

Commit b427249

Browse files
committed
dump user procedures. Closes #92
1 parent fea64ed commit b427249

File tree

5 files changed

+118
-9
lines changed

5 files changed

+118
-9
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ MySQLDump-PHP is the only library that supports:
2323
* output binary blobs as hex.
2424
* resolves view dependencies (using Stand-In tables).
2525
* output compared against original mysqldump. Linked to travis-ci testing system.
26+
* dumps stored procedures.
2627

2728
## Important
2829

29-
From version 2.0, connections to database are made using the standard DSN, documented in [PDO connection string](http://php.net/manual/en/ref.pdo-mysql.connection.php)
30+
From version 2.0, connections to database are made using the standard DSN, documented in [PDO connection string](http://php.net/manual/en/ref.pdo-mysql.connection.php).
3031

3132
## Requirements
3233

@@ -124,6 +125,7 @@ Refer to the [wiki](https://github.com/ifsnop/mysqldump-php/wiki/full-example) f
124125
'no-create-info' => false,
125126
'skip-triggers' => false,
126127
'add-drop-trigger' => true,
128+
'routines' => false,
127129
'hex-blob' => true,
128130
'databases' => false,
129131
'add-drop-database' => false,
@@ -175,6 +177,8 @@ Refer to the [wiki](https://github.com/ifsnop/mysqldump-php/wiki/full-example) f
175177
- http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_triggers
176178
- **add-drop-triggers**
177179
- http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_add-drop-trigger
180+
- **routines**
181+
- http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_routines
178182
- **hex-blob**
179183
- http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_hex-blob
180184
- **databases**

src/Ifsnop/Mysqldump/Mysqldump.php

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class Mysqldump
7070
private $tables = array();
7171
private $views = array();
7272
private $triggers = array();
73+
private $procedures = array();
7374
private $dbHandler;
7475
private $dbType;
7576
private $compressManager;
@@ -126,6 +127,7 @@ public function __construct(
126127
'no-create-info' => false,
127128
'skip-triggers' => false,
128129
'add-drop-trigger' => true,
130+
'routines' => false,
129131
'hex-blob' => true, /* faster than escaped content */
130132
'databases' => false,
131133
'add-drop-database' => false,
@@ -338,6 +340,7 @@ public function start($filename = '')
338340
$this->exportTables();
339341
$this->exportViews();
340342
$this->exportTriggers();
343+
$this->exportProcedures();
341344

342345
// Restore saved parameters
343346
$this->compressManager->write(
@@ -446,6 +449,13 @@ private function getDatabaseStructure()
446449
array_push($this->triggers, $row['Trigger']);
447450
}
448451
}
452+
453+
// Listing all procedures from database
454+
if ($this->dumpSettings['routines']) {
455+
foreach ($this->dbHandler->query($this->typeAdapter->show_procedures($this->dbName)) as $row) {
456+
array_push($this->procedures, $row['procedure_name']);
457+
}
458+
}
449459
}
450460

451461
/**
@@ -505,6 +515,19 @@ private function exportTriggers()
505515
}
506516
}
507517

518+
/**
519+
* Exports all the procedures found in database
520+
*
521+
* @return null
522+
*/
523+
private function exportProcedures()
524+
{
525+
// Exporting triggers one by one
526+
foreach ($this->procedures as $procedure) {
527+
$this->getProcedureStructure($procedure);
528+
}
529+
}
530+
508531
/**
509532
* Table structure extractor
510533
*
@@ -575,13 +598,12 @@ private function getTableColumnTypes($tableName) {
575598
*/
576599
private function getViewStructureTable($viewName)
577600
{
578-
$ret = '';
579601
if (!$this->dumpSettings['skip-comments']) {
580602
$ret = "--" . PHP_EOL .
581603
"-- Stand-In structure for view `${viewName}`" . PHP_EOL .
582604
"--" . PHP_EOL . PHP_EOL;
605+
$this->compressManager->write($ret);
583606
}
584-
$this->compressManager->write($ret);
585607
$stmt = $this->typeAdapter->show_create_view($viewName);
586608

587609
// create views as tables, to resolve dependencies
@@ -628,13 +650,12 @@ function createStandInTable($viewName) {
628650
*/
629651
private function getViewStructureView($viewName)
630652
{
631-
$ret = '';
632653
if (!$this->dumpSettings['skip-comments']) {
633654
$ret = "--" . PHP_EOL .
634655
"-- View structure for view `${viewName}`" . PHP_EOL .
635656
"--" . PHP_EOL . PHP_EOL;
657+
$this->compressManager->write($ret);
636658
}
637-
$this->compressManager->write($ret);
638659
$stmt = $this->typeAdapter->show_create_view($viewName);
639660

640661
// create views, to resolve dependencies
@@ -671,9 +692,30 @@ private function getTriggerStructure($triggerName)
671692
);
672693
return;
673694
}
674-
675695
}
676696

697+
/**
698+
* Procedure structure extractor
699+
*
700+
* @param string $procedureName Name of procedure to export
701+
* @return null
702+
*/
703+
private function getProcedureStructure($procedureName)
704+
{
705+
if (!$this->dumpSettings['skip-comments']) {
706+
$ret = "--" . PHP_EOL .
707+
"-- Dumping routines for database '" . $this->dbName . "'" . PHP_EOL .
708+
"--" . PHP_EOL . PHP_EOL;
709+
$this->compressManager->write($ret);
710+
}
711+
$stmt = $this->typeAdapter->show_create_procedure($procedureName);
712+
foreach ($this->dbHandler->query($stmt) as $r) {
713+
$this->compressManager->write(
714+
$this->typeAdapter->create_procedure($r, $this->dumpSettings)
715+
);
716+
return;
717+
}
718+
}
677719

678720
/**
679721
* Escape values with quotes when needed
@@ -1115,6 +1157,15 @@ public function create_trigger($triggerName)
11151157
return "";
11161158
}
11171159

1160+
/**
1161+
* function create_procedure Modify procedure code, add delimiters, etc
1162+
* @todo make it do something with sqlite
1163+
*/
1164+
public function create_procedure($procedureName, $dumpSettings)
1165+
{
1166+
return "";
1167+
}
1168+
11181169
public function show_tables()
11191170
{
11201171
return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
@@ -1141,6 +1192,11 @@ public function show_columns()
11411192
return "pragma table_info(${args[0]})";
11421193
}
11431194

1195+
public function show_procedures()
1196+
{
1197+
return "";
1198+
}
1199+
11441200
public function setup_transaction()
11451201
{
11461202
return "";
@@ -1329,6 +1385,11 @@ public function show_create_trigger($triggerName)
13291385
return "SHOW CREATE TRIGGER `$triggerName`";
13301386
}
13311387

1388+
public function show_create_procedure($procedureName)
1389+
{
1390+
return "SHOW CREATE PROCEDURE `$procedureName`";
1391+
}
1392+
13321393
public function create_table($row, $dumpSettings)
13331394
{
13341395
if (!isset($row['Create Table'])) {
@@ -1407,6 +1468,27 @@ public function create_trigger($row)
14071468
return $ret;
14081469
}
14091470

1471+
public function create_procedure($row, $dumpSettings)
1472+
{
1473+
$ret = "";
1474+
if (!isset($row['Create Procedure'])) {
1475+
throw new Exception("Error getting procedure code, unknown output. " .
1476+
"Please check 'https://bugs.mysql.com/bug.php?id=14564'");
1477+
}
1478+
$procedureStmt = $row['Create Procedure'];
1479+
1480+
$ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
1481+
$row['Procedure'] . "` */;" . PHP_EOL .
1482+
"/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
1483+
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
1484+
"DELIMITER ;;" . PHP_EOL .
1485+
$procedureStmt . " ;;" . PHP_EOL .
1486+
"DELIMITER ;" . PHP_EOL .
1487+
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
1488+
1489+
return $ret;
1490+
}
1491+
14101492
public function show_tables()
14111493
{
14121494
if (func_num_args() != 1) {
@@ -1444,7 +1526,6 @@ public function show_triggers()
14441526
return "SHOW TRIGGERS FROM `${args[0]}`;";
14451527
}
14461528

1447-
14481529
public function show_columns()
14491530
{
14501531
if (func_num_args() != 1) {
@@ -1456,6 +1537,20 @@ public function show_columns()
14561537
return "SHOW COLUMNS FROM `${args[0]}`;";
14571538
}
14581539

1540+
public function show_procedures()
1541+
{
1542+
if (func_num_args() != 1) {
1543+
throw new Exception("Unexpected parameter passed to " . __METHOD__);
1544+
}
1545+
1546+
$args = func_get_args();
1547+
1548+
return "SELECT SPECIFIC_NAME AS procedure_name " .
1549+
"FROM INFORMATION_SCHEMA.ROUTINES " .
1550+
"WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='${args[0]}'";
1551+
}
1552+
1553+
14591554
public function setup_transaction()
14601555
{
14611556
return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";

tests/test.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'disable-keys' => true,
2323
'skip-triggers' => false,
2424
'add-drop-trigger' => true,
25+
'routines' => true,
2526
'databases' => false,
2627
'add-drop-database' => false,
2728
'hex-blob' => true,
@@ -30,7 +31,7 @@
3031
);
3132

3233
$dump = new IMysqldump\Mysqldump(
33-
"mysql:host=localhost:3306;dbname=test001",
34+
"mysql:host=localhost;dbname=test001",
3435
"travis",
3536
"",
3637
$dumpSettings);

tests/test.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mysql -e "CREATE DATABASE test005;" 2> /dev/null
3131
mysql -e "CREATE DATABASE test006a;" 2> /dev/null
3232
mysql -e "CREATE DATABASE test006b;" 2> /dev/null
3333
mysql -e "GRANT ALL PRIVILEGES ON test001.* TO 'travis'@'localhost';" 2> /dev/null
34+
mysql -e "GRANT SELECT ON mysql.proc to 'travis'@'localhost';" 2> /dev/null
3435
mysql -e "GRANT ALL PRIVILEGES ON test002.* TO 'travis'@'localhost';" 2> /dev/null
3536
mysql -e "GRANT ALL PRIVILEGES ON test005.* TO 'travis'@'localhost';" 2> /dev/null
3637
mysql -e "GRANT ALL PRIVILEGES ON test006a.* TO 'travis'@'localhost';" 2> /dev/null
@@ -50,6 +51,7 @@ mysqldump -uroot test001 \
5051
--no-autocommit \
5152
--extended-insert=false \
5253
--hex-blob=true \
54+
--routines=true \
5355
> mysqldump_test001.sql
5456
ret[((index++))]=$?
5557

@@ -114,7 +116,6 @@ ret[((index++))]=$?
114116

115117
diff mysqldump_test005.filtered.sql mysqldump-php_test005.filtered.sql
116118
ret[((index++))]=$?
117-
118119
rm *.checksum 2> /dev/null
119120
rm *.filtered.sql 2> /dev/null
120121
rm mysqldump* 2> /dev/null

tests/test001.src.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,11 @@ CREATE TRIGGER before_test200_insert
126126
FOR EACH ROW set NEW.col = NEW.col + 1;
127127

128128
-- INSERT INTO `test200` VALUES (1,1); -- trigger tests
129+
130+
/*!50003 DROP PROCEDURE IF EXISTS `GetAllFromTest000` */;
131+
DELIMITER //
132+
CREATE PROCEDURE GetAllFromTest000()
133+
BEGIN
134+
SELECT * FROM test000;
135+
END //
136+
DELIMITER ;

0 commit comments

Comments
 (0)