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

[3.1.0] Add Postgres Support #91

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
33c28ac
add a SchemaState proxy for Postgres
lupinitylabs Sep 5, 2024
e124b82
replace manual restore handling with `load()` from schemaState
lupinitylabs Sep 5, 2024
960e033
add new dropDb parameter for Postgres' `--clean` argument
lupinitylabs Sep 5, 2024
5da5ed8
add new exception for failed imports through SchemaState `load()`
lupinitylabs Sep 5, 2024
5259c81
update the changelog with all notable changes
lupinitylabs Sep 5, 2024
d4e8dee
print the full path to the dump folder, highlight output.
lupinitylabs Sep 5, 2024
97fc029
apply code style changes
lupinitylabs Sep 5, 2024
448605d
add laravel pint
lupinitylabs Sep 5, 2024
dfc6f71
update README to include Postgres support
lupinitylabs Sep 5, 2024
6071573
remove obsolete version attribute
lupinitylabs Sep 5, 2024
4968070
fix test to expect the new `FailedImportException`
lupinitylabs Sep 5, 2024
435eb43
fix changed prototype for `executeDumpProcess()`
lupinitylabs Sep 5, 2024
c7ed2f1
globally deactivate withoutCreateDb() since we are not dropping and c…
lupinitylabs Sep 5, 2024
cd5067a
revert dropping withoutCreateDb: this will hardcode the database name…
lupinitylabs Sep 5, 2024
5ae16fa
wipe the database manually before importing the dump, add new `---no-…
lupinitylabs Sep 5, 2024
5a7c3b0
ignore LogicExceptions while dropping views and types - not all datab…
lupinitylabs Sep 5, 2024
f5add55
extend the fail check to cater for the new wipe
lupinitylabs Sep 5, 2024
5b9dd58
remove obsolete FailedMysqlCommandException
lupinitylabs Sep 6, 2024
a9da03b
fix comments
lupinitylabs Sep 6, 2024
acb953c
Merge branch 'master' into feature/postgres-support
lupinitylabs Sep 6, 2024
4c3acbc
clarify the $dropDb comment
lupinitylabs Sep 25, 2024
1b6a0d5
update phpdocs for new exceptions
lupinitylabs Sep 25, 2024
d5caea9
update phpdoc for older exception
lupinitylabs Sep 25, 2024
6be3317
Merge remote-tracking branch 'origin/feature/postgres-support' into f…
lupinitylabs Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
# Changelog

All notable changes to `protector` will be documented in this file
All notable changes to `protector` will be documented in this file.

## 1.0.0 - 201X-XX-XX
## v3.1.0 - 2024-09-09

- Add PostgreSQL support

## v3.0.0 - 2024-03-15

- Add Laravel 11 Support

## v2.0.0 - 2023-02-23

- Add Laravel 10 compatibility
- Add support for laravel/sanctum ^3.0
- Use Laravel's SchemaState for creating dumps

## v1.5.0 - 2022-09-06

- Real time output for database migrations
- Added unit tests
- Fix MariaDB support

## v1.4.1 - 2022-03-24

- Fixed RDS compatibility

## v1.3.0 - 2022-03-04

- Added migration option
- Feature/download chunking
- Streaming

## v1.1.0 - 2021-08-04

- Migrations now need to be explicitly published, as they are optional for some use cases and because they might need to be modified. Run `php artisan vendor:publish --tag=protector.migrations` to publish the protector migration to your `database/migrations` folder.
- Removed the Guzzle dependency, as it is already required by Laravel.

## v1.0.1 - 2021-08-02

- initial release
- sending and receiving database dumps
- user identification through tokens
- optional sodium x25519 encryption
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ This package allows you to download, export and import your application's databa

## Supported databases

- Protector only supports MySQL databases at this point.
- MariaDB databases may work, but are currently not actively tested and supported.
- Protector only supports MySQL, MariaDB and PostgreSQL databases at the moment.
- Source and destination databases are currently not checked. Please make sure you run the same software in the same
versions to prevent issues.
- Because of different dump formats, pulling dumps from MariaDB and restoring them to MySQL will not work.
- Because of different dump formats, pulling dumps from MariaDB and restoring them to MySQL will not work. The same
of course applies to cross-database operations between MySQL and PostgreSQL.

## Notes

Expand Down Expand Up @@ -273,6 +273,10 @@ Likelihood of impact: low
- Access to the formerly public methods `getGitRevision()`, `getGitHeadDate()` or `getGitBranch()` is now protected.
You now need to call getMetaData() and extract the information from the returned array.

## Migration guide from Protector v2.x to v3.x

No breaking changes are expected.

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
Expand All @@ -285,8 +289,12 @@ tracker.
## Credits

- [Web Development team at Cybex GmbH - cybex-online.com](https://github.com/cybex-gmbh)
- [Gael Connan](https://github.com/gael-connan-cybex)
- [Jörn Heusinger](https://github.com/jheusinger)
- [Fabian Holy](https://github.com/holyfabi)
- [Oliver Matla](https://github.com/lupinitylabs)
- [Marco Szulik](https://github.com/mszulik)
- [All Contributors](../../contributors)
- [All Contributors](https://github.com/cybex-gmbh/laravel-protector/graphs/contributors)

## License

Expand Down
6 changes: 6 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"name": "Marco Szulik",
"email": "webdevelopment@cybex-online.com",
"role": "Developer"
},
{
"name": "Oliver Matla",
"email": "info@lupinitylabs.com",
"role": "Developer"
}
],
"require": {
Expand All @@ -33,6 +38,7 @@
"laravel/sanctum": "^4.0"
},
"require-dev": {
"laravel/pint": "^1.17",
"laravel/sail": "^1.26",
"orchestra/testbench": "^9.0",
"phpunit/phpunit": "^10.5"
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# For more information: https://laravel.com/docs/sail
version: '3'
services:
app:
container_name: ${DOCKER_CONTAINER_NAME:-protector_test}
Expand Down
38 changes: 38 additions & 0 deletions pint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"preset": "laravel",
"rules": {
"blank_line_before_statement": {
"statements": [
"break",
"continue",
"do",
"exit",
"for",
"foreach",
"if",
"phpdoc",
"return",
"switch",
"throw",
"try",
"while",
"yield",
"yield_from"
]
},
"class_attributes_separation": {
"elements": {
"const": "none",
"property": "none"
}
},
"concat_space": {
"spacing": "one"
},
"no_superfluous_phpdoc_tags": true,
"not_operator_with_successor_space": false,
"phpdoc_separation": true,
"phpdoc_trim_consecutive_blank_line_separation": true,
"single_line_empty_body": false
}
}
2 changes: 1 addition & 1 deletion src/Classes/AbstractMySqlSchemaStateProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function load($path)
$this->schemaState->load(...func_get_args());
}

protected function executeDumpProcess(Process $process, $output, array $variables): Process
protected function executeDumpProcess(Process $process, $output, array $variables, int $depth = 0): Process
{
return $this->schemaState->executeDumpProcess(...func_get_args());
}
Expand Down
62 changes: 62 additions & 0 deletions src/Classes/AbstractPostgresSchemaStateProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Cybex\Protector\Classes;

use Cybex\Protector\Protector;
use Illuminate\Database\Connection;
use Illuminate\Database\Schema\PostgresSchemaState;

/**
* This abstract class provides proxies to protected methods within the related MySqlSchemaState.
*/
abstract class AbstractPostgresSchemaStateProxy extends PostgresSchemaState
{
public function __construct(Connection $connection, protected PostgresSchemaState $schemaState, protected Protector $protector)
{
parent::__construct($connection);
}

/**
* {@inheritDoc}
*/
public function dump(Connection $connection, $path)
{
$this->schemaState->dump(...func_get_args());
}

/**
* {@inheritDoc}
*/
public function load($path)
{
$this->schemaState->load(...func_get_args());
}

protected function baseVariables(mixed $config): array
{
return $this->schemaState->baseVariables(...func_get_args());
}

/**
* Get the base dump command as a string.
*/
protected function baseDumpCommand(): string
{
return 'pg_dump ' . implode(' ', $this->getBaseDumpArguments());
}

/**
* Get the required base dump arguments as an array.
*/
protected function getBaseDumpArguments(): array
{
return [
'--no-owner', // do not output commands to set ownership of objects to match the original database.
'--no-acl', // do not output commands to set access privileges of objects to match the original database.
'--host="${:LARAVEL_LOAD_HOST}"',
'--port="${:LARAVEL_LOAD_PORT}"',
'--username="${:LARAVEL_LOAD_USER}"',
'--dbname="${:LARAVEL_LOAD_DATABASE}"',
];
}
}
50 changes: 50 additions & 0 deletions src/Classes/PostgresSchemaStateProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Cybex\Protector\Classes;

use Illuminate\Database\Connection;

/**
* This is a proxy to the PostgresSchemaState class which allows us to override methods to match our own requirements.
* Unfortunately, the class is not bound to the IOC container and thus cannot be switched out at framework level.
* However, you may extend this proxy, and override its app container binding with your custom implementation.
*/
class PostgresSchemaStateProxy extends AbstractPostgresSchemaStateProxy
{
/**
* {@inheritDoc}
*/
public function dump(Connection $connection, $path)
{
$this->makeProcess($this->baseDumpCommand() . ' > ' . $path)
->mustRun(
$this->output,
array_merge($this->baseVariables($this->connection->getConfig()
), [
'LARAVEL_LOAD_PATH' => $path,
]));
}

/**
* {@inheritDoc}
*/
public function load($path)
{
$this->schemaState->load(...func_get_args());
}

protected function getBaseDumpArguments(): array
{
$conditionalArguments = [
'--create' => $this->protector->shouldCreateDb(),
'--clean' => $this->protector->shouldCreateDb() && $this->protector->shouldDropDb(),
'--verbose' => $this->protector->shouldDumpComments(),
'--schema-only' => !$this->protector->shouldDumpData(),
];

return [
...parent::getBaseDumpArguments(),
...array_keys(array_filter($conditionalArguments)),
];
}
}
5 changes: 1 addition & 4 deletions src/Commands/ExportDump.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

/**
* Class ExportDump
* @package Cybex\Protector\Commands;
*/
class ExportDump extends Command
{
Expand All @@ -33,8 +32,6 @@ class ExportDump extends Command

/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
Expand All @@ -59,7 +56,7 @@ public function handle(): int
$this->protector->getDisk()->putFileAs($directory, new File($tempFilePath), $fileName);
unlink($tempFilePath);

$this->info(sprintf('Dump %s was created in %s', $fileName, $directory));
$this->info(sprintf('Dump <comment>%s</> was created in <comment>%s</>', $fileName, $this->protector->getDisk()->path($directory)));

return self::SUCCESS;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Commands/ImportDump.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class ImportDump extends Command
{--r|remote : Pull a fresh dump from the remote server as configured in the .env file. Will be used as fallback when combined with other options. }
{--flush : Delete all existing dumps in the dump folder when using a remote dump. }
{--l|latest : Import the most recent dump available in the configured dumps directory. }
{--m|migrate : Run database migrations after import. }';
{--m|migrate : Run database migrations after import. }
{--w|no-wipe : Do not wipe the database before importing the dump. }';

/**
* The console command description.
Expand Down
14 changes: 14 additions & 0 deletions src/Exceptions/FailedImportException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Cybex\Protector\Exceptions;

use Exception;

/**
* Class FailedShellCommandException
lupinitylabs marked this conversation as resolved.
Show resolved Hide resolved
*
* Thrown if a shell command couldn't be executed properly.
*/
class FailedImportException extends Exception
{
}
21 changes: 0 additions & 21 deletions src/Exceptions/FailedMysqlCommandException.php

This file was deleted.

14 changes: 14 additions & 0 deletions src/Exceptions/FailedWipeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Cybex\Protector\Exceptions;

use Exception;

/**
* Class FailedShellCommandException
lupinitylabs marked this conversation as resolved.
Show resolved Hide resolved
*
* Thrown if a shell command couldn't be executed properly.
*/
class FailedWipeException extends Exception
{
}
Loading