Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Database Connection Helper Command #122

Merged
merged 13 commits into from
Feb 11, 2020
21 changes: 21 additions & 0 deletions docs/database.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Interacting with Database
igmoweb marked this conversation as resolved.
Show resolved Hide resolved

- You can log into MySQL and run any query in the default database (`wordpress`) by using:
igmoweb marked this conversation as resolved.
Show resolved Hide resolved

```sh
composer server db
```

- Use `composer server info` to retrieve MySQL info, connection details and forwarded ports:
igmoweb marked this conversation as resolved.
Show resolved Hide resolved

```sh
Root password: wordpress

Database: wordpress
User: wordpress
Password: wordpress

Version: 5.7.26-1debian9
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
Ports: 0.0.0.0:32791
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
```

65 changes: 64 additions & 1 deletion inc/composer/class-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected function configure() {
->setName( 'server' )
->setDescription( 'Altis Local Server' )
->setDefinition( [
new InputArgument( 'subcommand', null, 'start, stop, restart, cli, exec. shell, status. logs.' ),
new InputArgument( 'subcommand', null, 'start, stop, restart, cli, exec, shell, status, db, logs.' ),
new InputArgument( 'options', InputArgument::IS_ARRAY ),
] )
->setAliases( [ 'local-server' ] )
Expand All @@ -42,6 +42,10 @@ protected function configure() {
exec -- <command> eg: exec -- vendor/bin/phpcs
Open a shell:
shell
Database commands:
db Log into MySQL on the Database server
db spf Generates an SPF file for Sequel Pro
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
db info Prints out Database connection details
View the logs
logs <service> <service> can be php, nginx, db, s3, elasticsearch, xray
EOT
Expand All @@ -68,6 +72,8 @@ protected function execute( InputInterface $input, OutputInterface $output ) {
return $this->exec( $input, $output, 'wp' );
} elseif ( $subcommand === 'exec' ) {
return $this->exec( $input, $output );
} elseif ( $subcommand === 'db' ) {
return $this->db( $input, $output );
} elseif ( $subcommand === 'status' ) {
return $this->status( $input, $output );
} elseif ( $subcommand === 'logs' ) {
Expand Down Expand Up @@ -332,6 +338,63 @@ protected function shell( InputInterface $input, OutputInterface $output ) {
return $return_val;
}

protected function db( InputInterface $input, OutputInterface $output ) {
$db = $input->getArgument( 'options' )[0] ?? '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$db = $input->getArgument( 'options' )[0] ?? '';
$db = $input->getArgument( 'options' )[0] ?? null;

Just going to test this out, I think it's necessary for the default command to run.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested both ways and it always works but anyway, null looks slightly better

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh of course, the switch doesn't do strict matching. It's a == comparison 👍

$columns = exec( 'tput cols' );
$lines = exec( 'tput lines' );

$base_command_prefix = sprintf(
'cd %s; VOLUME=%s COMPOSE_PROJECT_NAME=%s',
'vendor/altis/local-server/docker',
escapeshellarg( getcwd() ),
$this->get_project_subdomain()
);

$base_command = sprintf(
"$base_command_prefix docker-compose exec -e COLUMNS=%d -e LINES=%d db",
$columns,
$lines
);

switch ( $db ) {
case 'info':
// Env variables
$env_variables = explode( PHP_EOL, shell_exec( "$base_command printenv" ) );
$values = array_reduce( $env_variables, function( $values, $env_variable_text ) {
$env_variable = explode( '=', $env_variable_text );
$values[ $env_variable[0] ] = $env_variable[1] ?? '';
return $values;
}, [] );

// Ports

// Find the container ID with Docker Compose
$db_container_id = shell_exec( "$base_command_prefix docker-compose ps -q db" );

// Retrrieve the forwarded ports using Docker and the container ID
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
$ports = shell_exec( sprintf( "$base_command_prefix docker ps --format '{{.Ports}}' --filter id=%s", $db_container_id ) );
preg_match( '/.*,\s([\d.]+:[\d]+)->.*/', $ports, $ports_matches );

$db_info = <<<EOT
<info>Root password</info>: ${values['MYSQL_ROOT_PASSWORD']}

<info>Database</info>: ${values['MYSQL_PASSWORD']}
<info>User</info>: ${values['MYSQL_USER']}
<info>Password</info>: ${values['MYSQL_PASSWORD']}

<comment>Version</comment>: ${values['MYSQL_VERSION']}
<comment>Ports</comment>: ${ports_matches[1]}
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
EOT;
echo $output->write( $db_info ) . PHP_EOL;
roborourke marked this conversation as resolved.
Show resolved Hide resolved
$return_val = 0;
break;
default:
igmoweb marked this conversation as resolved.
Show resolved Hide resolved
passthru( "$base_command mysql --database=wordpress --user=root -pwordpress", $return_val );
}

return $return_val;
}

/**
* Get the name of the project for the local subdomain
*
Expand Down