Skip to content

Commit

Permalink
connect to database described by dsn string
Browse files Browse the repository at this point in the history
  • Loading branch information
ifsnop committed Jul 30, 2015
1 parent cfc3a85 commit 448b1d2
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 58 deletions.
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ This is a php version of linux's mysqldump in terminal "$ mysqldump -u username

Out of the box, MySQLDump-PHP supports backing up table structures, the data itself, views and triggers.

## Important

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)

## Requirements

- PHP 5.3.0 or newer
Expand All @@ -30,22 +34,22 @@ Out of the box, MySQLDump-PHP supports backing up table structures, the data its
Using [Composer](http://getcomposer.org):

```
$ composer require ifsnop/mysqldump-php:1.*
$ composer require ifsnop/mysqldump-php:2.*
```

Or via json file:

````
"require": {
"ifsnop/mysqldump-php":"1.*"
"ifsnop/mysqldump-php":"2.*"
}
````

Using [Curl](http://curl.haxx.se):

```
$ curl --silent --location https://github.com/ifsnop/mysqldump-php/archive/v1.4.1.tar.gz | tar xvfz -
$ curl --silent --location https://github.com/ifsnop/mysqldump-php/archive/v2.0.0.tar.gz | tar xvfz -
```

## Getting started
Expand All @@ -58,7 +62,7 @@ With [Autoloader](http://www.php-fig.org/psr/psr-4/)/[Composer](http://getcompos
use Ifsnop\Mysqldump as IMysqldump;
try {
$dump = new IMysqldump\Mysqldump('database', 'username', 'password');
$dump = new IMysqldump\Mysqldump('mysql:host=localhost;dbname=testdb', 'username', 'password');
$dump->start('storage/work/dump.sql');
} catch (\Exception $e) {
echo 'mysqldump-php error: ' . $e->getMessage();
Expand All @@ -72,8 +76,8 @@ Plain old PHP:
```
<?php
include_once(dirname(__FILE__) . '/mysqldump-php-1.4.1/src/Ifsnop/Mysqldump/Mysqldump.php');
$dump = new Ifsnop\Mysqldump\Mysqldump( 'database', 'username', 'password');
include_once(dirname(__FILE__) . '/mysqldump-php-2.0.0/src/Ifsnop/Mysqldump/Mysqldump.php');
$dump = new Ifsnop\Mysqldump\Mysqldump('mysql:host=localhost;dbname=testdb', 'username', 'password');
$dump->start('storage/work/dump.sql');
?>
Expand All @@ -82,27 +86,20 @@ Plain old PHP:
Refer to the [wiki](https://github.com/ifsnop/mysqldump-php/wiki/full-example) for some examples and a comparision between mysqldump and mysqldump-php dumps.

## Constructor and default parameters

/**
* Constructor of Mysqldump. Note that in the case of an SQLite database
* connection, the filename must be in the $db parameter.
*
* @param string $db Database name
* @param string $dsn PDO DSN connection string
* @param string $user SQL account username
* @param string $pass SQL account password
* @param string $host SQL server to connect to
* @param string $type SQL database type ('mysql', 'sqlite', ...)
* @param array $dumpSettings SQL database settings
* @param array $pdoSettings PDO configured attributes
*
* @return null
*/
public function __construct(
$db = '',
$dsn = '',
$user = '',
$pass = '',
$host = 'localhost',
$type = 'mysql',
$dumpSettings = array(),
$pdoSettings = array()
)
Expand Down Expand Up @@ -237,8 +234,7 @@ it is identical tests are OK.

## TODO

Support connecting through a socket to database. Probably rewrite constructor
to support an array with parameters.
...

## Contributing

Expand Down
115 changes: 81 additions & 34 deletions src/Ifsnop/Mysqldump/Mysqldump.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,31 @@ class Mysqldump
const UTF8 = 'utf8';
const UTF8MB4 = 'utf8mb4';

// This can be set both on constructor or manually
public $host;
public $port;
// Keys to retrieve from DSN string
const DBNAME = 'dbname';
const DBTYPE = 'dbtype';
const DBHOST = 'host';
const DBSOCKET = 'unix_socket';

/**
* Database username
* @var string
*/
public $user;
/**
* Database password
* @var string
*/
public $pass;
public $db;
/**
* Connection string for PDO
* @var string
*/
public $dsn;
/**
* Destination filename
* @var string
*/
public $fileName;

// Internal stuff
Expand All @@ -65,25 +84,26 @@ class Mysqldump
private $pdoSettings = array();
private $version;
private $tableColumnTypes = array();
/**
* database name, parsed from dsn
* @var string
*/
private $dbName;

/**
* Constructor of Mysqldump. Note that in the case of an SQLite database
* connection, the filename must be in the $db parameter.
*
* @param string $db Database name
* @param string $dsn PDO DSN connection string
* @param string $user SQL account username
* @param string $pass SQL account password
* @param string $host SQL server to connect to
* @param string $type SQL database type
* @param array $dumpSettings SQL database settings
* @param array $pdoSettings PDO configured attributes
*/
public function __construct(
$db = '',
$dsn = '',
$user = '',
$pass = '',
$host = 'localhost',
$type = 'mysql',
$dumpSettings = array(),
$pdoSettings = array()
) {
Expand Down Expand Up @@ -120,20 +140,19 @@ public function __construct(
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false
);

$this->db = $db;
$this->user = $user;
$this->pass = $pass;
$this->dsn = $dsn;
$this->dbName = $this->getFromDsn($this->dsn, Mysqldump::DBNAME);
$this->dbType = $this->getFromDsn($this->dsn, Mysqldump::DBTYPE);
$this->host = $this->getFromDsn($this->dsn, Mysqldump::DBHOST) != "" ?
$this->getFromDsn($this->dsn, Mysqldump::DBHOST) :
$this->getFromDsn($this->dsn, Mysqldump::DBSOCKET);

$colonPos = strpos($host, ':');
if (false !== $colonPos) {
$this->port = substr($host, $colonPos + 1);
$this->host = substr($host, 0, $colonPos);
} else {
$this->port = null;
$this->host = $host;
if (empty($this->host)) {
throw new Exception("Missing host from DSN string");
}

$this->dbType = strtolower($type);
$this->pdoSettings = self::array_replace_recursive($pdoSettingsDefault, $pdoSettings);
$this->dumpSettings = self::array_replace_recursive($dumpSettingsDefault, $dumpSettings);

Expand Down Expand Up @@ -175,6 +194,38 @@ public static function array_replace_recursive($array1, $array2)
return $array1;
}

/**
* Parse DSN string and extract dbname value
* Several examples of a DSN string
* mysql:host=localhost;dbname=testdb
* mysql:host=localhost;port=3307;dbname=testdb
* mysql:unix_socket=/tmp/mysql.sock;dbname=testdb
*
* @param string $dsn dsn string to parse
*
* @return string
*/
private function getFromDsn($dsn, $search = Mysqldump::DBNAME)
{
if (empty($dsn) || (false === ($pos = strpos($dsn, ":")))) {
return "";
}

if (Mysqldump::DBTYPE == $search) {
return substr($dsn, 0, $pos);
}

$dsn = substr($dsn, $pos + 1);

foreach(explode(";", $dsn) as $kvp) {
$kvpArr = explode("=", $kvp);
if (0 == strcmp($kvpArr[0], $search)) {
return $kvpArr[1];
}
}
return "";
}

/**
* Connect with PDO
*
Expand All @@ -186,17 +237,13 @@ private function connect()
try {
switch ($this->dbType) {
case 'sqlite':
$this->dbHandler = @new PDO("sqlite:" . $this->db, null, null, $this->pdoSettings);
$this->dbHandler = @new PDO("sqlite:" . $this->dbName, null, null, $this->pdoSettings);
break;
case 'mysql':
case 'pgsql':
case 'dblib':
$dsn = $this->dbType .
":host=" . $this->host .
(isset($this->port) ? ";port=" . $this->port : "") .
";dbname=" . $this->db;
$this->dbHandler = @new PDO(
$dsn,
$this->dsn,
$this->user,
$this->pass,
$this->pdoSettings
Expand Down Expand Up @@ -253,11 +300,11 @@ public function start($filename = '')

if ($this->dumpSettings['databases']) {
$this->compressManager->write(
$this->typeAdapter->getDatabaseHeader($this->db)
$this->typeAdapter->getDatabaseHeader($this->dbName)
);
if ($this->dumpSettings['add-drop-database']) {
$this->compressManager->write(
$this->typeAdapter->add_drop_database($this->db)
$this->typeAdapter->add_drop_database($this->dbName)
);
}
}
Expand All @@ -267,7 +314,7 @@ public function start($filename = '')

if ($this->dumpSettings['databases']) {
$this->compressManager->write(
$this->typeAdapter->databases($this->db)
$this->typeAdapter->databases($this->dbName)
);
}

Expand Down Expand Up @@ -305,7 +352,7 @@ private function getDumpFileHeader()
// Some info about software, source and time
$header = "-- mysqldump-php https://github.com/ifsnop/mysqldump-php" . PHP_EOL .
"--" . PHP_EOL .
"-- Host: {$this->host}\tDatabase: {$this->db}" . PHP_EOL .
"-- Host: {$this->host}\tDatabase: {$this->dbName}" . PHP_EOL .
"-- ------------------------------------------------------" . PHP_EOL;

if (!empty($this->version)) {
Expand Down Expand Up @@ -347,12 +394,12 @@ private function getDatabaseStructure()
// Listing all tables from database
if (empty($this->dumpSettings['include-tables'])) {
// include all tables for now, blacklisting happens later
foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->db)) as $row) {
foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->dbName)) as $row) {
array_push($this->tables, current($row));
}
} else {
// include only the tables mentioned in include-tables
foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->db)) as $row) {
foreach ($this->dbHandler->query($this->typeAdapter->show_tables($this->dbName)) as $row) {
if (in_array(current($row), $this->dumpSettings['include-tables'], true)) {
array_push($this->tables, current($row));
$elem = array_search(
Expand All @@ -367,12 +414,12 @@ private function getDatabaseStructure()
// Listing all views from database
if (empty($this->dumpSettings['include-tables'])) {
// include all views for now, blacklisting happens later
foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->db)) as $row) {
foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->dbName)) as $row) {
array_push($this->views, current($row));
}
} else {
// include only the tables mentioned in include-tables
foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->db)) as $row) {
foreach ($this->dbHandler->query($this->typeAdapter->show_views($this->dbName)) as $row) {
if (in_array(current($row), $this->dumpSettings['include-tables'], true)) {
array_push($this->views, current($row));
$elem = array_search(
Expand All @@ -386,7 +433,7 @@ private function getDatabaseStructure()

// Listing all triggers from database
if (false === $this->dumpSettings['skip-triggers']) {
foreach ($this->dbHandler->query($this->typeAdapter->show_triggers($this->db)) as $row) {
foreach ($this->dbHandler->query($this->typeAdapter->show_triggers($this->dbName)) as $row) {
array_push($this->triggers, $row['Trigger']);
}
}
Expand Down
17 changes: 10 additions & 7 deletions tests/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,29 @@
);

$dump = new IMysqldump\Mysqldump(
"test001",
"mysql:host=localhost:3306;dbname=test001",
"travis",
"",
"localhost:3306",
"mysql",
$dumpSettings);

$dump->start("mysqldump-php_test001.sql");


$dumpSettings['default-character-set'] = IMysqldump\Mysqldump::UTF8MB4;

$dump = new IMysqldump\Mysqldump(
"test002",
"mysql:host=localhost;dbname=test002",
"travis",
"",
"localhost",
"mysql",
$dumpSettings);

$dump->start("mysqldump-php_test002.sql");

$dump = new IMysqldump\Mysqldump(
"mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=test002",
"travis",
"",
$dumpSettings);

$dump->start("mysqldump-php_test003.sql");

exit;
4 changes: 4 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ cat mysqldump_test001.sql | grep ^INSERT > mysqldump_test001.filtered.sql
cat mysqldump_test002.sql | grep ^INSERT > mysqldump_test002.filtered.sql
cat mysqldump-php_test001.sql | grep ^INSERT > mysqldump-php_test001.filtered.sql
cat mysqldump-php_test002.sql | grep ^INSERT > mysqldump-php_test002.filtered.sql
cat mysqldump-php_test003.sql | grep ^INSERT > mysqldump-php_test003.filtered.sql

diff test001.filtered.sql mysqldump_test001.filtered.sql
ret[7]=$?
Expand All @@ -75,6 +76,9 @@ ret[11]=$?
diff test002.src.checksum mysqldump-php_test002.checksum
ret[12]=$?

diff mysqldump-php_test002.filtered.sql mysqldump-php_test003.filtered.sql
ret[13]=$?

rm *.checksum 2> /dev/null
rm *.filtered.sql 2> /dev/null
rm mysqldump* 2> /dev/null
Expand Down

0 comments on commit 448b1d2

Please sign in to comment.