Advertisement
Guest User

Untitled

a guest
Apr 6th, 2017
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.79 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Ifsnop\Mysqldump;
  4.  
  5. use Exception;
  6. use PDO;
  7. use PDOException;
  8.  
  9.  
  10. class Mysqldump
  11. {
  12.  
  13. const MAXLINESIZE = 1000000;
  14.  
  15.  
  16. const GZIP = 'Gzip';
  17. const BZIP2 = 'Bzip2';
  18. const NONE = 'None';
  19.  
  20.  
  21. const UTF8 = 'utf8';
  22. const UTF8MB4 = 'utf8mb4';
  23.  
  24.  
  25. public $user;
  26.  
  27. public $pass;
  28.  
  29. public $dsn;
  30.  
  31. public $fileName = 'php://output';
  32.  
  33.  
  34. private $tables = array();
  35. private $views = array();
  36. private $triggers = array();
  37. private $procedures = array();
  38. private $dbHandler = null;
  39. private $dbType;
  40. private $compressManager;
  41. private $typeAdapter;
  42. private $dumpSettings = array();
  43. private $pdoSettings = array();
  44. private $version;
  45. private $tableColumnTypes = array();
  46.  
  47. private $dbName;
  48.  
  49. private $host;
  50.  
  51. private $dsnArray = array();
  52.  
  53. public function __construct(
  54. $dsn = '',
  55. $user = '',
  56. $pass = '',
  57. $dumpSettings = array(),
  58. $pdoSettings = array()
  59. ) {
  60. $dumpSettingsDefault = array(
  61. 'include-tables' => array(),
  62. 'exclude-tables' => array(),
  63. 'compress' => Mysqldump::NONE,
  64. 'no-data' => array(),
  65. 'reset-auto-increment' => false,
  66. 'add-drop-table' => false,
  67. 'single-transaction' => true,
  68. 'lock-tables' => true,
  69. 'add-locks' => true,
  70. 'extended-insert' => true,
  71. 'complete-insert' => false,
  72. 'disable-keys' => true,
  73. 'where' => '',
  74. 'no-create-info' => false,
  75. 'skip-triggers' => false,
  76. 'add-drop-trigger' => true,
  77. 'routines' => false,
  78. 'hex-blob' => true, /* faster than escaped content */
  79. 'databases' => false,
  80. 'add-drop-database' => false,
  81. 'skip-tz-utc' => false,
  82. 'no-autocommit' => true,
  83. 'default-character-set' => Mysqldump::UTF8,
  84. 'skip-comments' => false,
  85. 'skip-dump-date' => false,
  86. 'init_commands' => array(),
  87. 'net_buffer_length' => self::MAXLINESIZE,
  88. /* deprecated */
  89. 'disable-foreign-keys-check' => true
  90. );
  91.  
  92. $pdoSettingsDefault = array(
  93. PDO::ATTR_PERSISTENT => true,
  94. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  95. PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false
  96. );
  97.  
  98. $this->user = $user;
  99. $this->pass = $pass;
  100. $this->parseDsn($dsn);
  101. $this->pdoSettings = self::array_replace_recursive($pdoSettingsDefault, $pdoSettings);
  102. $this->dumpSettings = self::array_replace_recursive($dumpSettingsDefault, $dumpSettings);
  103.  
  104. $this->dumpSettings['init_commands'][] = "SET NAMES " . $this->dumpSettings['default-character-set'];
  105.  
  106. if (false === $this->dumpSettings['skip-tz-utc']) {
  107. $this->dumpSettings['init_commands'][] = "SET TIME_ZONE='+00:00'";
  108. }
  109.  
  110. $diff = array_diff(array_keys($this->dumpSettings), array_keys($dumpSettingsDefault));
  111. if (count($diff)>0) {
  112. throw new Exception("Unexpected value in dumpSettings: (" . implode(",", $diff) . ")");
  113. }
  114.  
  115. if ( !is_array($this->dumpSettings['include-tables']) ||
  116. !is_array($this->dumpSettings['exclude-tables']) ) {
  117. throw new Exception("Include-tables and exclude-tables should be arrays");
  118. }
  119.  
  120. // Dump the same views as tables, mimic mysqldump behaviour
  121. $this->dumpSettings['include-views'] = $this->dumpSettings['include-tables'];
  122.  
  123. // Create a new compressManager to manage compressed output
  124. $this->compressManager = CompressManagerFactory::create($this->dumpSettings['compress']);
  125. }
  126.  
  127. /**
  128. * Destructor of Mysqldump. Unsets dbHandlers and database objects.
  129. *
  130. */
  131. public function __destruct()
  132. {
  133. $this->dbHandler = null;
  134. }
  135.  
  136.  
  137. public static function array_replace_recursive($array1, $array2)
  138. {
  139. if (function_exists('array_replace_recursive')) {
  140. return array_replace_recursive($array1, $array2);
  141. }
  142.  
  143. foreach ($array2 as $key => $value) {
  144. if (is_array($value)) {
  145. $array1[$key] = self::array_replace_recursive($array1[$key], $value);
  146. } else {
  147. $array1[$key] = $value;
  148. }
  149. }
  150. return $array1;
  151. }
  152.  
  153.  
  154. private function parseDsn($dsn)
  155. {
  156. if (empty($dsn) || (false === ($pos = strpos($dsn, ":")))) {
  157. throw new Exception("Empty DSN string");
  158. }
  159.  
  160. $this->dsn = $dsn;
  161. $this->dbType = strtolower(substr($dsn, 0, $pos));
  162.  
  163. if (empty($this->dbType)) {
  164. throw new Exception("Missing database type from DSN string");
  165. }
  166.  
  167. $dsn = substr($dsn, $pos + 1);
  168.  
  169. foreach(explode(";", $dsn) as $kvp) {
  170. $kvpArr = explode("=", $kvp);
  171. $this->dsnArray[strtolower($kvpArr[0])] = $kvpArr[1];
  172. }
  173.  
  174. if (empty($this->dsnArray['host']) &&
  175. empty($this->dsnArray['unix_socket'])) {
  176. throw new Exception("Missing host from DSN string");
  177. }
  178. $this->host = (!empty($this->dsnArray['host'])) ?
  179. $this->dsnArray['host'] :
  180. $this->dsnArray['unix_socket'];
  181.  
  182. if (empty($this->dsnArray['dbname'])) {
  183. throw new Exception("Missing database name from DSN string");
  184. }
  185.  
  186. $this->dbName = $this->dsnArray['dbname'];
  187.  
  188. return true;
  189. }
  190.  
  191.  
  192. private function connect()
  193. {
  194.  
  195. try {
  196. switch ($this->dbType) {
  197. case 'sqlite':
  198. $this->dbHandler = @new PDO("sqlite:" . $this->dbName, null, null, $this->pdoSettings);
  199. break;
  200. case 'mysql':
  201. case 'pgsql':
  202. case 'dblib':
  203. $this->dbHandler = @new PDO(
  204. $this->dsn,
  205. $this->user,
  206. $this->pass,
  207. $this->pdoSettings
  208. );
  209. foreach($this->dumpSettings['init_commands'] as $stmt) {
  210. $this->dbHandler->exec($stmt);
  211. }
  212. $this->version = $this->dbHandler->getAttribute(PDO::ATTR_SERVER_VERSION);
  213. break;
  214. default:
  215. throw new Exception("Unsupported database type (" . $this->dbType . ")");
  216. }
  217. } catch (PDOException $e) {
  218. throw new Exception(
  219. "Connection to " . $this->dbType . " failed with message: " .
  220. $e->getMessage()
  221. );
  222. }
  223.  
  224. if ( is_null($this->dbHandler) ) {
  225. throw new Exception("Connection to ". $this->dbType . "failed");
  226. }
  227.  
  228. $this->dbHandler->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
  229. $this->typeAdapter = TypeAdapterFactory::create($this->dbType, $this->dbHandler);
  230. }
  231.  
  232. /**
  233. * Main call
  234. *
  235. * @param string $filename Name of file to write sql dump to
  236. * @return null
  237. */
  238. public function start($filename = '')
  239. {
  240. // Output file can be redefined here
  241. if (!empty($filename)) {
  242. $this->fileName = $filename;
  243. }
  244.  
  245. // Connect to database
  246. $this->connect();
  247.  
  248. // Create output file
  249. $this->compressManager->open($this->fileName);
  250.  
  251. // Write some basic info to output file
  252. $this->compressManager->write($this->getDumpFileHeader());
  253.  
  254. // Store server settings and use sanner defaults to dump
  255. $this->compressManager->write(
  256. $this->typeAdapter->backup_parameters($this->dumpSettings)
  257. );
  258.  
  259. if ($this->dumpSettings['databases']) {
  260. $this->compressManager->write(
  261. $this->typeAdapter->getDatabaseHeader($this->dbName)
  262. );
  263. if ($this->dumpSettings['add-drop-database']) {
  264. $this->compressManager->write(
  265. $this->typeAdapter->add_drop_database($this->dbName)
  266. );
  267. }
  268. }
  269.  
  270. // Get table, view and trigger structures from database
  271. $this->getDatabaseStructure();
  272.  
  273. if ($this->dumpSettings['databases']) {
  274. $this->compressManager->write(
  275. $this->typeAdapter->databases($this->dbName)
  276. );
  277. }
  278.  
  279.  
  280. if (0 < count($this->dumpSettings['include-tables'])) {
  281. $name = implode(",", $this->dumpSettings['include-tables']);
  282. throw new Exception("Table (" . $name . ") not found in database");
  283. }
  284.  
  285. $this->exportTables();
  286. $this->exportViews();
  287. $this->exportTriggers();
  288. $this->exportProcedures();
  289.  
  290. $this->compressManager->write(
  291. $this->typeAdapter->restore_parameters($this->dumpSettings)
  292. );
  293. $this->compressManager->write($this->getDumpFileFooter());
  294.  
  295. $this->compressManager->close();
  296. }
  297.  
  298.  
  299. private function getDumpFileHeader()
  300. {
  301. $header = '';
  302. if ( !$this->dumpSettings['skip-comments'] ) {
  303. // Some info about software, source and time
  304. $header = "-- mysqldump-php https://github.com/ifsnop/mysqldump-php" . PHP_EOL .
  305. "--" . PHP_EOL .
  306. "-- Host: {$this->host}\tDatabase: {$this->dbName}" . PHP_EOL .
  307. "-- ------------------------------------------------------" . PHP_EOL;
  308.  
  309. if ( !empty($this->version) ) {
  310. $header .= "-- Server version \t" . $this->version . PHP_EOL;
  311. }
  312.  
  313. if ( !$this->dumpSettings['skip-dump-date'] ) {
  314. $header .= "-- Date: " . date('r') . PHP_EOL . PHP_EOL;
  315. }
  316. }
  317. return $header;
  318. }
  319.  
  320.  
  321. private function getDumpFileFooter()
  322. {
  323. $footer = '';
  324. if (!$this->dumpSettings['skip-comments']) {
  325. $footer .= '-- Dump completed';
  326. if (!$this->dumpSettings['skip-dump-date']) {
  327. $footer .= ' on: ' . date('r');
  328. }
  329. $footer .= PHP_EOL;
  330. }
  331.  
  332. return $footer;
  333. }
  334.  
  335.  
  336. private function getDatabaseStructure()
  337. {
  338. // Listing all tables from database
  339. if (empty($this->dumpSettings['include-tables'])) {
  340. // include all tables for now, blacklisting happens later
  341. foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->dbName)) as $row) {
  342. array_push($this->tables, current($row));
  343. }
  344. } else {
  345. foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->dbName)) as $row) {
  346. if (in_array(current($row), $this->dumpSettings['include-tables'], true)) {
  347. array_push($this->tables, current($row));
  348. $elem = array_search(
  349. current($row),
  350. $this->dumpSettings['include-tables']
  351. );
  352. unset($this->dumpSettings['include-tables'][$elem]);
  353. }
  354. }
  355. }
  356.  
  357. // Listing all views from database
  358. if (empty($this->dumpSettings['include-views'])) {
  359. // include all views for now, blacklisting happens later
  360. foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->dbName)) as $row) {
  361. array_push($this->views, current($row));
  362. }
  363. } else {
  364. // include only the tables mentioned in include-tables
  365. foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->dbName)) as $row) {
  366. if (in_array(current($row), $this->dumpSettings['include-views'], true)) {
  367. array_push($this->views, current($row));
  368. $elem = array_search(
  369. current($row),
  370. $this->dumpSettings['include-views']
  371. );
  372. unset($this->dumpSettings['include-views'][$elem]);
  373. }
  374. }
  375. }
  376.  
  377. // Listing all triggers from database
  378. if (false === $this->dumpSettings['skip-triggers']) {
  379. foreach ($this->dbHandler->query($this->typeAdapter->show_triggers($this->dbName)) as $row) {
  380. array_push($this->triggers, $row['Trigger']);
  381. }
  382. }
  383.  
  384. // Listing all procedures from database
  385. if ($this->dumpSettings['routines']) {
  386. foreach ($this->dbHandler->query($this->typeAdapter->show_procedures($this->dbName)) as $row) {
  387. array_push($this->procedures, $row['procedure_name']);
  388. }
  389. }
  390. }
  391.  
  392.  
  393. private function matches($table, $arr) {
  394. $match = false;
  395.  
  396. foreach ($arr as $pattern) {
  397. if ( '/' != $pattern[0] ) {
  398. continue;
  399. }
  400. if ( 1 == preg_match($pattern, $table) ) {
  401. $match = true;
  402. }
  403. }
  404.  
  405. return in_array($table, $arr) || $match;
  406. }
  407.  
  408. private function exportTables()
  409. {
  410. // Exporting tables one by one
  411. foreach ($this->tables as $table) {
  412. if ( $this->matches($table, $this->dumpSettings['exclude-tables']) ) {
  413. continue;
  414. }
  415. $this->getTableStructure($table);
  416. if ( false === $this->dumpSettings['no-data'] ) { // don't break compatibility with old trigger
  417. $this->listValues($table);
  418. } else if ( true === $this->dumpSettings['no-data']
  419. || $this->matches($table, $this->dumpSettings['no-data']) ) {
  420. continue;
  421. } else {
  422. $this->listValues($table);
  423. }
  424. }
  425. }
  426.  
  427. private function exportViews()
  428. {
  429. if (false === $this->dumpSettings['no-create-info']) {
  430. // Exporting views one by one
  431. foreach ($this->views as $view) {
  432. if ( $this->matches($view, $this->dumpSettings['exclude-tables']) ) {
  433. continue;
  434. }
  435. $this->tableColumnTypes[$view] = $this->getTableColumnTypes($view);
  436. $this->getViewStructureTable($view);
  437. }
  438. foreach ($this->views as $view) {
  439. if ( $this->matches($view, $this->dumpSettings['exclude-tables']) ) {
  440. continue;
  441. }
  442. $this->getViewStructureView($view);
  443. }
  444. }
  445. }
  446.  
  447. /**
  448. * Exports all the triggers found in database
  449. *
  450. * @return null
  451. */
  452. private function exportTriggers()
  453. {
  454. // Exporting triggers one by one
  455. foreach ($this->triggers as $trigger) {
  456. $this->getTriggerStructure($trigger);
  457. }
  458. }
  459.  
  460. /**
  461. * Exports all the procedures found in database
  462. *
  463. * @return null
  464. */
  465. private function exportProcedures()
  466. {
  467. // Exporting triggers one by one
  468. foreach ($this->procedures as $procedure) {
  469. $this->getProcedureStructure($procedure);
  470. }
  471. }
  472.  
  473.  
  474. private function getTableStructure($tableName)
  475. {
  476. if (!$this->dumpSettings['no-create-info']) {
  477. $ret = '';
  478. if (!$this->dumpSettings['skip-comments']) {
  479. $ret = "--" . PHP_EOL .
  480. "-- Table structure for table `$tableName`" . PHP_EOL .
  481. "--" . PHP_EOL . PHP_EOL;
  482. }
  483. $stmt = $this->typeAdapter->show_create_table($tableName);
  484. foreach ($this->dbHandler->query($stmt) as $r) {
  485. $this->compressManager->write($ret);
  486. if ($this->dumpSettings['add-drop-table']) {
  487. $this->compressManager->write(
  488. $this->typeAdapter->drop_table($tableName)
  489. );
  490. }
  491. $this->compressManager->write(
  492. $this->typeAdapter->create_table($r, $this->dumpSettings)
  493. );
  494. break;
  495. }
  496. }
  497. $this->tableColumnTypes[$tableName] = $this->getTableColumnTypes($tableName);
  498. return;
  499. }
  500.  
  501.  
  502. private function getTableColumnTypes($tableName) {
  503. $columnTypes = array();
  504. $columns = $this->dbHandler->query(
  505. $this->typeAdapter->show_columns($tableName)
  506. );
  507. $columns->setFetchMode(PDO::FETCH_ASSOC);
  508.  
  509. foreach($columns as $key => $col) {
  510. $types = $this->typeAdapter->parseColumnType($col);
  511. $columnTypes[$col['Field']] = array(
  512. 'is_numeric'=> $types['is_numeric'],
  513. 'is_blob' => $types['is_blob'],
  514. 'type' => $types['type'],
  515. 'type_sql' => $col['Type']
  516. );
  517. }
  518.  
  519. return $columnTypes;
  520. }
  521.  
  522.  
  523. private function getViewStructureTable($viewName)
  524. {
  525. if (!$this->dumpSettings['skip-comments']) {
  526. $ret = "--" . PHP_EOL .
  527. "-- Stand-In structure for view `${viewName}`" . PHP_EOL .
  528. "--" . PHP_EOL . PHP_EOL;
  529. $this->compressManager->write($ret);
  530. }
  531. $stmt = $this->typeAdapter->show_create_view($viewName);
  532.  
  533. // create views as tables, to resolve dependencies
  534. foreach ($this->dbHandler->query($stmt) as $r) {
  535. if ($this->dumpSettings['add-drop-table']) {
  536. $this->compressManager->write(
  537. $this->typeAdapter->drop_view($viewName)
  538. );
  539. }
  540.  
  541. $this->compressManager->write(
  542. $this->createStandInTable($viewName)
  543. );
  544. break;
  545. }
  546. }
  547.  
  548. function createStandInTable($viewName) {
  549. $ret = array();
  550. foreach($this->tableColumnTypes[$viewName] as $k => $v) {
  551. $ret[] = "`${k}` ${v['type_sql']}";
  552. }
  553. $ret = implode(PHP_EOL . ",", $ret);
  554.  
  555. $ret = "CREATE TABLE IF NOT EXISTS `$viewName` (" .
  556. PHP_EOL . $ret . PHP_EOL . ");" . PHP_EOL;
  557.  
  558. return $ret;
  559. }
  560.  
  561.  
  562. private function getViewStructureView($viewName)
  563. {
  564. if (!$this->dumpSettings['skip-comments']) {
  565. $ret = "--" . PHP_EOL .
  566. "-- View structure for view `${viewName}`" . PHP_EOL .
  567. "--" . PHP_EOL . PHP_EOL;
  568. $this->compressManager->write($ret);
  569. }
  570. $stmt = $this->typeAdapter->show_create_view($viewName);
  571.  
  572. foreach ($this->dbHandler->query($stmt) as $r) {
  573. // because we must replace table with view, we should delete it
  574. $this->compressManager->write(
  575. $this->typeAdapter->drop_view($viewName)
  576. );
  577. $this->compressManager->write(
  578. $this->typeAdapter->create_view($r)
  579. );
  580. break;
  581. }
  582. }
  583.  
  584.  
  585. private function getTriggerStructure($triggerName)
  586. {
  587. $stmt = $this->typeAdapter->show_create_trigger($triggerName);
  588. foreach ($this->dbHandler->query($stmt) as $r) {
  589. if ($this->dumpSettings['add-drop-trigger']) {
  590. $this->compressManager->write(
  591. $this->typeAdapter->add_drop_trigger($triggerName)
  592. );
  593. }
  594. $this->compressManager->write(
  595. $this->typeAdapter->create_trigger($r)
  596. );
  597. return;
  598. }
  599. }
  600.  
  601.  
  602. private function getProcedureStructure($procedureName)
  603. {
  604. if (!$this->dumpSettings['skip-comments']) {
  605. $ret = "--" . PHP_EOL .
  606. "-- Dumping routines for database '" . $this->dbName . "'" . PHP_EOL .
  607. "--" . PHP_EOL . PHP_EOL;
  608. $this->compressManager->write($ret);
  609. }
  610. $stmt = $this->typeAdapter->show_create_procedure($procedureName);
  611. foreach ($this->dbHandler->query($stmt) as $r) {
  612. $this->compressManager->write(
  613. $this->typeAdapter->create_procedure($r, $this->dumpSettings)
  614. );
  615. return;
  616. }
  617. }
  618.  
  619.  
  620. private function escape($tableName, $row)
  621. {
  622. $ret = array();
  623. $columnTypes = $this->tableColumnTypes[$tableName];
  624. foreach ($row as $colName => $colValue) {
  625. if (is_null($colValue)) {
  626. $ret[] = "NULL";
  627. } elseif ($this->dumpSettings['hex-blob'] && $columnTypes[$colName]['is_blob']) {
  628. if ($columnTypes[$colName]['type'] == 'bit' || !empty($colValue)) {
  629. $ret[] = "0x${colValue}";
  630. } else {
  631. $ret[] = "''";
  632. }
  633. } elseif ($columnTypes[$colName]['is_numeric']) {
  634. $ret[] = $colValue;
  635. } else {
  636. $ret[] = $this->dbHandler->quote($colValue);
  637. }
  638. }
  639. return $ret;
  640. }
  641.  
  642.  
  643. private function listValues($tableName)
  644. {
  645. $this->prepareListValues($tableName);
  646.  
  647. $onlyOnce = true;
  648. $lineSize = 0;
  649.  
  650. $colStmt = $this->getColumnStmt($tableName);
  651. $stmt = "SELECT $colStmt FROM `$tableName`";
  652.  
  653. if ($this->dumpSettings['where']) {
  654. $stmt .= " WHERE {$this->dumpSettings['where']}";
  655. }
  656. $resultSet = $this->dbHandler->query($stmt);
  657. $resultSet->setFetchMode(PDO::FETCH_ASSOC);
  658.  
  659. foreach ($resultSet as $row) {
  660. $vals = $this->escape($tableName, $row);
  661. if ($onlyOnce || !$this->dumpSettings['extended-insert']) {
  662.  
  663. if ($this->dumpSettings['complete-insert']) {
  664. $lineSize += $this->compressManager->write(
  665. "INSERT INTO `$tableName` (`" .
  666. implode("`, `", array_keys($this->tableColumnTypes[$tableName])) .
  667. "`) VALUES (" . implode(",", $vals) . ")"
  668. );
  669. } else {
  670. $lineSize += $this->compressManager->write(
  671. "INSERT INTO `$tableName` VALUES (" . implode(",", $vals) . ")"
  672. );
  673. }
  674. $onlyOnce = false;
  675. } else {
  676. $lineSize += $this->compressManager->write(",(" . implode(",", $vals) . ")");
  677. }
  678. if (($lineSize > $this->dumpSettings['net_buffer_length']) ||
  679. !$this->dumpSettings['extended-insert']) {
  680. $onlyOnce = true;
  681. $lineSize = $this->compressManager->write(";" . PHP_EOL);
  682. }
  683. }
  684. $resultSet->closeCursor();
  685.  
  686. if (!$onlyOnce) {
  687. $this->compressManager->write(";" . PHP_EOL);
  688. }
  689.  
  690. $this->endListValues($tableName);
  691. }
  692.  
  693. function prepareListValues($tableName)
  694. {
  695. if (!$this->dumpSettings['skip-comments']) {
  696. $this->compressManager->write(
  697. "--" . PHP_EOL .
  698. "-- Dumping data for table `$tableName`" . PHP_EOL .
  699. "--" . PHP_EOL . PHP_EOL
  700. );
  701. }
  702.  
  703. if ($this->dumpSettings['single-transaction']) {
  704. $this->dbHandler->exec($this->typeAdapter->setup_transaction());
  705. $this->dbHandler->exec($this->typeAdapter->start_transaction());
  706. }
  707.  
  708. if ($this->dumpSettings['lock-tables']) {
  709. $this->typeAdapter->lock_table($tableName);
  710. }
  711.  
  712. if ($this->dumpSettings['add-locks']) {
  713. $this->compressManager->write(
  714. $this->typeAdapter->start_add_lock_table($tableName)
  715. );
  716. }
  717.  
  718. if ($this->dumpSettings['disable-keys']) {
  719. $this->compressManager->write(
  720. $this->typeAdapter->start_add_disable_keys($tableName)
  721. );
  722. }
  723.  
  724. if ($this->dumpSettings['no-autocommit']) {
  725. $this->compressManager->write(
  726. $this->typeAdapter->start_disable_autocommit()
  727. );
  728. }
  729.  
  730. return;
  731. }
  732.  
  733. function endListValues($tableName)
  734. {
  735. if ($this->dumpSettings['disable-keys']) {
  736. $this->compressManager->write(
  737. $this->typeAdapter->end_add_disable_keys($tableName)
  738. );
  739. }
  740.  
  741. if ($this->dumpSettings['add-locks']) {
  742. $this->compressManager->write(
  743. $this->typeAdapter->end_add_lock_table($tableName)
  744. );
  745. }
  746.  
  747. if ($this->dumpSettings['single-transaction']) {
  748. $this->dbHandler->exec($this->typeAdapter->commit_transaction());
  749. }
  750.  
  751. if ($this->dumpSettings['lock-tables']) {
  752. $this->typeAdapter->unlock_table($tableName);
  753. }
  754.  
  755. // Commit to enable autocommit
  756. if ($this->dumpSettings['no-autocommit']) {
  757. $this->compressManager->write(
  758. $this->typeAdapter->end_disable_autocommit()
  759. );
  760. }
  761.  
  762. $this->compressManager->write(PHP_EOL);
  763.  
  764. return;
  765. }
  766.  
  767.  
  768. function getColumnStmt($tableName)
  769. {
  770. $colStmt = array();
  771. foreach($this->tableColumnTypes[$tableName] as $colName => $colType) {
  772. if ($colType['type'] == 'bit' && $this->dumpSettings['hex-blob']) {
  773. $colStmt[] = "LPAD(HEX(`${colName}`),2,'0') AS `${colName}`";
  774. } else if ($colType['is_blob'] && $this->dumpSettings['hex-blob']) {
  775. $colStmt[] = "HEX(`${colName}`) AS `${colName}`";
  776. } else {
  777. $colStmt[] = "`${colName}`";
  778. }
  779. }
  780. $colStmt = implode($colStmt, ",");
  781.  
  782. return $colStmt;
  783. }
  784. }
  785.  
  786.  
  787. abstract class CompressMethod
  788. {
  789. public static $enums = array(
  790. "None",
  791. "Gzip",
  792. "Bzip2"
  793. );
  794.  
  795. /**
  796. * @param string $c
  797. * @return boolean
  798. */
  799. public static function isValid($c)
  800. {
  801. return in_array($c, self::$enums);
  802. }
  803. }
  804.  
  805. abstract class CompressManagerFactory
  806. {
  807. /**
  808. * @param string $c
  809. * @return CompressBzip2|CompressGzip|CompressNone
  810. */
  811. public static function create($c)
  812. {
  813. $c = ucfirst(strtolower($c));
  814. if (! CompressMethod::isValid($c)) {
  815. throw new Exception("Compression method ($c) is not defined yet");
  816. }
  817.  
  818. $method = __NAMESPACE__ . "\\" . "Compress" . $c;
  819.  
  820. return new $method;
  821. }
  822. }
  823.  
  824. class CompressBzip2 extends CompressManagerFactory
  825. {
  826. private $fileHandler = null;
  827.  
  828. public function __construct()
  829. {
  830. if (! function_exists("bzopen")) {
  831. throw new Exception("Compression is enabled, but bzip2 lib is not installed or configured properly");
  832. }
  833. }
  834.  
  835. /**
  836. * @param string $filename
  837. */
  838. public function open($filename)
  839. {
  840. $this->fileHandler = bzopen($filename, "w");
  841. if (false === $this->fileHandler) {
  842. throw new Exception("Output file is not writable");
  843. }
  844.  
  845. return true;
  846. }
  847.  
  848. public function write($str)
  849. {
  850. if (false === ($bytesWritten = bzwrite($this->fileHandler, $str))) {
  851. throw new Exception("Writting to file failed! Probably, there is no more free space left?");
  852. }
  853. return $bytesWritten;
  854. }
  855.  
  856. public function close()
  857. {
  858. return bzclose($this->fileHandler);
  859. }
  860. }
  861.  
  862. class CompressGzip extends CompressManagerFactory
  863. {
  864. private $fileHandler = null;
  865.  
  866. public function __construct()
  867. {
  868. if (! function_exists("gzopen")) {
  869. throw new Exception("Compression is enabled, but gzip lib is not installed or configured properly");
  870. }
  871. }
  872.  
  873. /**
  874. * @param string $filename
  875. */
  876. public function open($filename)
  877. {
  878. $this->fileHandler = gzopen($filename, "wb");
  879. if (false === $this->fileHandler) {
  880. throw new Exception("Output file is not writable");
  881. }
  882.  
  883. return true;
  884. }
  885.  
  886. public function write($str)
  887. {
  888. if (false === ($bytesWritten = gzwrite($this->fileHandler, $str))) {
  889. throw new Exception("Writting to file failed! Probably, there is no more free space left?");
  890. }
  891. return $bytesWritten;
  892. }
  893.  
  894. public function close()
  895. {
  896. return gzclose($this->fileHandler);
  897. }
  898. }
  899.  
  900. class CompressNone extends CompressManagerFactory
  901. {
  902. private $fileHandler = null;
  903.  
  904. /**
  905. * @param string $filename
  906. */
  907. public function open($filename)
  908. {
  909. $this->fileHandler = fopen($filename, "wb");
  910. if (false === $this->fileHandler) {
  911. throw new Exception("Output file is not writable");
  912. }
  913.  
  914. return true;
  915. }
  916.  
  917. public function write($str)
  918. {
  919. if (false === ($bytesWritten = fwrite($this->fileHandler, $str))) {
  920. throw new Exception("Writting to file failed! Probably, there is no more free space left?");
  921. }
  922. return $bytesWritten;
  923. }
  924.  
  925. public function close()
  926. {
  927. return fclose($this->fileHandler);
  928. }
  929. }
  930.  
  931. /**
  932. * Enum with all available TypeAdapter implementations
  933. *
  934. */
  935. abstract class TypeAdapter
  936. {
  937. public static $enums = array(
  938. "Sqlite",
  939. "Mysql"
  940. );
  941.  
  942. /**
  943. * @param string $c
  944. * @return boolean
  945. */
  946. public static function isValid($c)
  947. {
  948. return in_array($c, self::$enums);
  949. }
  950. }
  951.  
  952. /**
  953. * TypeAdapter Factory
  954. *
  955. */
  956. abstract class TypeAdapterFactory
  957. {
  958. /**
  959. * @param string $c Type of database factory to create (Mysql, Sqlite,...)
  960. * @param PDO $dbHandler
  961. */
  962. public static function create($c, $dbHandler = null)
  963. {
  964. $c = ucfirst(strtolower($c));
  965. if (! TypeAdapter::isValid($c)) {
  966. throw new Exception("Database type support for ($c) not yet available");
  967. }
  968. $method = __NAMESPACE__ . "\\" . "TypeAdapter" . $c;
  969. return new $method($dbHandler);
  970. }
  971.  
  972. /**
  973. * function databases Add sql to create and use database
  974. * @todo make it do something with sqlite
  975. */
  976. public function databases()
  977. {
  978. return "";
  979. }
  980.  
  981. public function show_create_table($tableName)
  982. {
  983. return "SELECT tbl_name as 'Table', sql as 'Create Table' " .
  984. "FROM sqlite_master " .
  985. "WHERE type='table' AND tbl_name='$tableName'";
  986. }
  987.  
  988. /**
  989. * function create_table Get table creation code from database
  990. * @todo make it do something with sqlite
  991. */
  992. public function create_table($row, $dumpSettings)
  993. {
  994. return "";
  995. }
  996.  
  997. public function show_create_view($viewName)
  998. {
  999. return "SELECT tbl_name as 'View', sql as 'Create View' " .
  1000. "FROM sqlite_master " .
  1001. "WHERE type='view' AND tbl_name='$viewName'";
  1002. }
  1003.  
  1004. /**
  1005. * function create_view Get view creation code from database
  1006. * @todo make it do something with sqlite
  1007. */
  1008. public function create_view($row)
  1009. {
  1010. return "";
  1011. }
  1012.  
  1013.  
  1014. public function show_create_trigger($triggerName)
  1015. {
  1016. return "";
  1017. }
  1018.  
  1019.  
  1020. public function create_trigger($triggerName)
  1021. {
  1022. return "";
  1023. }
  1024.  
  1025. /**
  1026. * function create_procedure Modify procedure code, add delimiters, etc
  1027. * @todo make it do something with sqlite
  1028. */
  1029. public function create_procedure($procedureName, $dumpSettings)
  1030. {
  1031. return "";
  1032. }
  1033.  
  1034. public function show_tables()
  1035. {
  1036. return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
  1037. }
  1038.  
  1039. public function show_views()
  1040. {
  1041. return "SELECT tbl_name FROM sqlite_master WHERE type='view'";
  1042. }
  1043.  
  1044. public function show_triggers()
  1045. {
  1046. return "SELECT name FROM sqlite_master WHERE type='trigger'";
  1047. }
  1048.  
  1049. public function show_columns()
  1050. {
  1051. if (func_num_args() != 1) {
  1052. return "";
  1053. }
  1054.  
  1055. $args = func_get_args();
  1056.  
  1057. return "pragma table_info(${args[0]})";
  1058. }
  1059.  
  1060. public function show_procedures()
  1061. {
  1062. return "";
  1063. }
  1064.  
  1065. public function setup_transaction()
  1066. {
  1067. return "";
  1068. }
  1069.  
  1070. public function start_transaction()
  1071. {
  1072. return "BEGIN EXCLUSIVE";
  1073. }
  1074.  
  1075. public function commit_transaction()
  1076. {
  1077. return "COMMIT";
  1078. }
  1079.  
  1080. public function lock_table()
  1081. {
  1082. return "";
  1083. }
  1084.  
  1085. public function unlock_table()
  1086. {
  1087. return "";
  1088. }
  1089.  
  1090. public function start_add_lock_table()
  1091. {
  1092. return PHP_EOL;
  1093. }
  1094.  
  1095. public function end_add_lock_table()
  1096. {
  1097. return PHP_EOL;
  1098. }
  1099.  
  1100. public function start_add_disable_keys()
  1101. {
  1102. return PHP_EOL;
  1103. }
  1104.  
  1105. public function end_add_disable_keys()
  1106. {
  1107. return PHP_EOL;
  1108. }
  1109.  
  1110. public function start_disable_foreign_keys_check()
  1111. {
  1112. return PHP_EOL;
  1113. }
  1114.  
  1115. public function end_disable_foreign_keys_check()
  1116. {
  1117. return PHP_EOL;
  1118. }
  1119.  
  1120. public function add_drop_database()
  1121. {
  1122. return PHP_EOL;
  1123. }
  1124.  
  1125. public function add_drop_trigger()
  1126. {
  1127. return PHP_EOL;
  1128. }
  1129.  
  1130. public function drop_table()
  1131. {
  1132. return PHP_EOL;
  1133. }
  1134.  
  1135. public function drop_view()
  1136. {
  1137. return PHP_EOL;
  1138. }
  1139.  
  1140. public function parseColumnType($colType)
  1141. {
  1142. return array();
  1143. }
  1144.  
  1145. public function backup_parameters()
  1146. {
  1147. return PHP_EOL;
  1148. }
  1149.  
  1150. public function restore_parameters()
  1151. {
  1152. return PHP_EOL;
  1153. }
  1154. }
  1155.  
  1156. class TypeAdapterPgsql extends TypeAdapterFactory
  1157. {
  1158. }
  1159.  
  1160. class TypeAdapterDblib extends TypeAdapterFactory
  1161. {
  1162. }
  1163.  
  1164. class TypeAdapterSqlite extends TypeAdapterFactory
  1165. {
  1166. }
  1167.  
  1168. class TypeAdapterMysql extends TypeAdapterFactory
  1169. {
  1170.  
  1171. private $dbHandler = null;
  1172.  
  1173.  
  1174. public $mysqlTypes = array(
  1175. 'numerical' => array(
  1176. 'bit',
  1177. 'tinyint',
  1178. 'smallint',
  1179. 'mediumint',
  1180. 'int',
  1181. 'integer',
  1182. 'bigint',
  1183. 'real',
  1184. 'double',
  1185. 'float',
  1186. 'decimal',
  1187. 'numeric'
  1188. ),
  1189. 'blob' => array(
  1190. 'tinyblob',
  1191. 'blob',
  1192. 'mediumblob',
  1193. 'longblob',
  1194. 'binary',
  1195. 'varbinary',
  1196. 'bit',
  1197. 'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
  1198. 'point',
  1199. 'linestring',
  1200. 'polygon',
  1201. 'multipoint',
  1202. 'multilinestring',
  1203. 'multipolygon',
  1204. 'geometrycollection',
  1205. )
  1206. );
  1207.  
  1208. public function __construct ($dbHandler)
  1209. {
  1210. $this->dbHandler = $dbHandler;
  1211. }
  1212.  
  1213. public function databases()
  1214. {
  1215. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1216. $args = func_get_args();
  1217. $databaseName = $args[0];
  1218.  
  1219. $resultSet = $this->dbHandler->query("SHOW VARIABLES LIKE 'character_set_database';");
  1220. $characterSet = $resultSet->fetchColumn(1);
  1221. $resultSet->closeCursor();
  1222.  
  1223. $resultSet = $this->dbHandler->query("SHOW VARIABLES LIKE 'collation_database';");
  1224. $collationDb = $resultSet->fetchColumn(1);
  1225. $resultSet->closeCursor();
  1226. $ret = "";
  1227.  
  1228. $ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `${databaseName}`".
  1229. " /*!40100 DEFAULT CHARACTER SET ${characterSet} " .
  1230. " COLLATE ${collationDb} */;" . PHP_EOL . PHP_EOL .
  1231. "USE `${databaseName}`;" . PHP_EOL . PHP_EOL;
  1232.  
  1233. return $ret;
  1234. }
  1235.  
  1236. public function show_create_table($tableName)
  1237. {
  1238. return "SHOW CREATE TABLE `$tableName`";
  1239. }
  1240.  
  1241. public function show_create_view($viewName)
  1242. {
  1243. return "SHOW CREATE VIEW `$viewName`";
  1244. }
  1245.  
  1246. public function show_create_trigger($triggerName)
  1247. {
  1248. return "SHOW CREATE TRIGGER `$triggerName`";
  1249. }
  1250.  
  1251. public function show_create_procedure($procedureName)
  1252. {
  1253. return "SHOW CREATE PROCEDURE `$procedureName`";
  1254. }
  1255.  
  1256. public function create_table( $row, $dumpSettings )
  1257. {
  1258. if ( !isset($row['Create Table']) ) {
  1259. throw new Exception("Error getting table code, unknown output");
  1260. }
  1261.  
  1262. $createTable = $row['Create Table'];
  1263. if ( $dumpSettings['reset-auto-increment'] ) {
  1264. $match = "/AUTO_INCREMENT=[0-9]+/s";
  1265. $replace = "";
  1266. $createTable = preg_replace($match, $replace, $createTable);
  1267. }
  1268.  
  1269. $ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
  1270. "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
  1271. $createTable . ";" . PHP_EOL .
  1272. "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
  1273. PHP_EOL;
  1274. return $ret;
  1275. }
  1276.  
  1277. public function create_view($row)
  1278. {
  1279. $ret = "";
  1280. if (!isset($row['Create View'])) {
  1281. throw new Exception("Error getting view structure, unknown output");
  1282. }
  1283.  
  1284. $triggerStmt = $row['Create View'];
  1285.  
  1286. $triggerStmtReplaced1 = str_replace(
  1287. "CREATE ALGORITHM",
  1288. "/*!50001 CREATE ALGORITHM",
  1289. $triggerStmt
  1290. );
  1291. $triggerStmtReplaced2 = str_replace(
  1292. " DEFINER=",
  1293. " */" . PHP_EOL . "/*!50013 DEFINER=",
  1294. $triggerStmtReplaced1
  1295. );
  1296. $triggerStmtReplaced3 = str_replace(
  1297. " VIEW ",
  1298. " */" . PHP_EOL . "/*!50001 VIEW ",
  1299. $triggerStmtReplaced2
  1300. );
  1301. if (false === $triggerStmtReplaced1 ||
  1302. false === $triggerStmtReplaced2 ||
  1303. false === $triggerStmtReplaced3) {
  1304. $triggerStmtReplaced = $triggerStmt;
  1305. } else {
  1306. $triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
  1307. }
  1308.  
  1309. $ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
  1310. return $ret;
  1311. }
  1312.  
  1313. public function create_trigger($row)
  1314. {
  1315. $ret = "";
  1316. if (!isset($row['SQL Original Statement'])) {
  1317. throw new Exception("Error getting trigger code, unknown output");
  1318. }
  1319.  
  1320. $triggerStmt = $row['SQL Original Statement'];
  1321. $triggerStmtReplaced = str_replace(
  1322. "CREATE DEFINER",
  1323. "/*!50003 CREATE*/ /*!50017 DEFINER",
  1324. $triggerStmt
  1325. );
  1326. $triggerStmtReplaced = str_replace(
  1327. " TRIGGER",
  1328. "*/ /*!50003 TRIGGER",
  1329. $triggerStmtReplaced
  1330. );
  1331. if ( false === $triggerStmtReplaced ) {
  1332. $triggerStmtReplaced = $triggerStmt;
  1333. }
  1334.  
  1335. $ret .= "DELIMITER ;;" . PHP_EOL .
  1336. $triggerStmtReplaced . "*/;;" . PHP_EOL .
  1337. "DELIMITER ;" . PHP_EOL . PHP_EOL;
  1338. return $ret;
  1339. }
  1340.  
  1341. public function create_procedure($row, $dumpSettings)
  1342. {
  1343. $ret = "";
  1344. if (!isset($row['Create Procedure'])) {
  1345. throw new Exception("Error getting procedure code, unknown output. " .
  1346. "Please check 'https://bugs.mysql.com/bug.php?id=14564'");
  1347. }
  1348. $procedureStmt = $row['Create Procedure'];
  1349.  
  1350. $ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
  1351. $row['Procedure'] . "` */;" . PHP_EOL .
  1352. "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
  1353. "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
  1354. "DELIMITER ;;" . PHP_EOL .
  1355. $procedureStmt . " ;;" . PHP_EOL .
  1356. "DELIMITER ;" . PHP_EOL .
  1357. "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
  1358.  
  1359. return $ret;
  1360. }
  1361.  
  1362. public function show_tables()
  1363. {
  1364. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1365. $args = func_get_args();
  1366. return "SELECT TABLE_NAME AS tbl_name " .
  1367. "FROM INFORMATION_SCHEMA.TABLES " .
  1368. "WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='${args[0]}'";
  1369. }
  1370.  
  1371. public function show_views()
  1372. {
  1373. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1374. $args = func_get_args();
  1375. return "SELECT TABLE_NAME AS tbl_name " .
  1376. "FROM INFORMATION_SCHEMA.TABLES " .
  1377. "WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='${args[0]}'";
  1378. }
  1379.  
  1380. public function show_triggers()
  1381. {
  1382. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1383. $args = func_get_args();
  1384. return "SHOW TRIGGERS FROM `${args[0]}`;";
  1385. }
  1386.  
  1387. public function show_columns()
  1388. {
  1389. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1390. $args = func_get_args();
  1391. return "SHOW COLUMNS FROM `${args[0]}`;";
  1392. }
  1393.  
  1394. public function show_procedures()
  1395. {
  1396. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1397. $args = func_get_args();
  1398. return "SELECT SPECIFIC_NAME AS procedure_name " .
  1399. "FROM INFORMATION_SCHEMA.ROUTINES " .
  1400. "WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='${args[0]}'";
  1401. }
  1402.  
  1403. public function setup_transaction()
  1404. {
  1405. return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
  1406. }
  1407.  
  1408. public function start_transaction()
  1409. {
  1410. return "START TRANSACTION";
  1411. }
  1412.  
  1413. public function commit_transaction()
  1414. {
  1415. return "COMMIT";
  1416. }
  1417.  
  1418. public function lock_table()
  1419. {
  1420. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1421. $args = func_get_args();
  1422. return $this->dbHandler->exec("LOCK TABLES `${args[0]}` READ LOCAL");
  1423.  
  1424. }
  1425.  
  1426. public function unlock_table()
  1427. {
  1428. return $this->dbHandler->exec("UNLOCK TABLES");
  1429. }
  1430.  
  1431. public function start_add_lock_table()
  1432. {
  1433. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1434. $args = func_get_args();
  1435. return "LOCK TABLES `${args[0]}` WRITE;" . PHP_EOL;
  1436. }
  1437.  
  1438. public function end_add_lock_table()
  1439. {
  1440. return "UNLOCK TABLES;" . PHP_EOL;
  1441. }
  1442.  
  1443. public function start_add_disable_keys()
  1444. {
  1445. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1446. $args = func_get_args();
  1447. return "/*!40000 ALTER TABLE `${args[0]}` DISABLE KEYS */;" .
  1448. PHP_EOL;
  1449. }
  1450.  
  1451. public function end_add_disable_keys()
  1452. {
  1453. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1454. $args = func_get_args();
  1455. return "/*!40000 ALTER TABLE `${args[0]}` ENABLE KEYS */;" .
  1456. PHP_EOL;
  1457. }
  1458.  
  1459. public function start_disable_autocommit()
  1460. {
  1461. return "SET autocommit=0;" . PHP_EOL;
  1462. }
  1463.  
  1464. public function end_disable_autocommit()
  1465. {
  1466. return "COMMIT;" . PHP_EOL;
  1467. }
  1468.  
  1469. public function add_drop_database()
  1470. {
  1471. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1472. $args = func_get_args();
  1473. return "/*!40000 DROP DATABASE IF EXISTS `${args[0]}`*/;" .
  1474. PHP_EOL . PHP_EOL;
  1475. }
  1476.  
  1477. public function add_drop_trigger()
  1478. {
  1479. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1480. $args = func_get_args();
  1481. return "DROP TRIGGER IF EXISTS `${args[0]}`;" . PHP_EOL;
  1482. }
  1483.  
  1484. public function drop_table()
  1485. {
  1486. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1487. $args = func_get_args();
  1488. return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL;
  1489. }
  1490.  
  1491. public function drop_view()
  1492. {
  1493. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1494. $args = func_get_args();
  1495. return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL .
  1496. "/*!50001 DROP VIEW IF EXISTS `${args[0]}`*/;" . PHP_EOL;
  1497. }
  1498.  
  1499. public function getDatabaseHeader()
  1500. {
  1501. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1502. $args = func_get_args();
  1503. return "--" . PHP_EOL .
  1504. "-- Current Database: `${args[0]}`" . PHP_EOL .
  1505. "--" . PHP_EOL . PHP_EOL;
  1506. }
  1507.  
  1508. /**
  1509. * Decode column metadata and fill info structure.
  1510. * type, is_numeric and is_blob will always be available.
  1511. *
  1512. * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
  1513. * @return array
  1514. */
  1515. public function parseColumnType($colType)
  1516. {
  1517. $colInfo = array();
  1518. $colParts = explode(" ", $colType['Type']);
  1519.  
  1520. if($fparen = strpos($colParts[0], "("))
  1521. {
  1522. $colInfo['type'] = substr($colParts[0], 0, $fparen);
  1523. $colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
  1524. $colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
  1525. }
  1526. else
  1527. {
  1528. $colInfo['type'] = $colParts[0];
  1529. }
  1530. $colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
  1531. $colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
  1532.  
  1533. return $colInfo;
  1534. }
  1535.  
  1536. public function backup_parameters()
  1537. {
  1538. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1539. $args = func_get_args();
  1540. $dumpSettings = $args[0];
  1541. $ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
  1542. "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
  1543. "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
  1544. "/*!40101 SET NAMES " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL;
  1545.  
  1546. if (false === $dumpSettings['skip-tz-utc']) {
  1547. $ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
  1548. "/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
  1549. }
  1550.  
  1551. $ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
  1552. "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
  1553. "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
  1554. "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
  1555.  
  1556. return $ret;
  1557. }
  1558.  
  1559. public function restore_parameters()
  1560. {
  1561. $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
  1562. $args = func_get_args();
  1563. $dumpSettings = $args[0];
  1564. $ret = "";
  1565.  
  1566. if (false === $dumpSettings['skip-tz-utc']) {
  1567. $ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
  1568. }
  1569.  
  1570. $ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
  1571. "/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
  1572. "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
  1573. "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
  1574. "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
  1575. "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
  1576. "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
  1577.  
  1578. return $ret;
  1579. }
  1580.  
  1581.  
  1582. private function check_parameters($num_args, $expected_num_args, $method_name)
  1583. {
  1584. if ( $num_args != $expected_num_args ) {
  1585. throw new Exception("Unexpected parameter passed to $method_name");
  1586. }
  1587. return;
  1588. }
  1589. }
  1590. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement