Skip to content

Commit 4d0224f

Browse files
authored
Merge pull request #7109 from morozov/view-editor
Introduce view editor
2 parents 03ea85e + 2829055 commit 4d0224f

File tree

6 files changed

+133
-3
lines changed

6 files changed

+133
-3
lines changed

UPGRADE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ awareness about deprecated code.
88

99
# Upgrade to 4.4
1010

11+
## Deprecated `View` features
12+
13+
The `View` constructor has been marked as internal. Use `View::editor()` to instantiate an editor and
14+
`ViewEditor::create()` to create a view.
15+
1116
## Deprecated `Sequence` features
1217

1318
1. The `Sequence` constructor has been marked as internal. Use `Sequence::editor()` to instantiate an editor and
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Schema\Exception;
6+
7+
use Doctrine\DBAL\Schema\Name\OptionallyQualifiedName;
8+
use Doctrine\DBAL\Schema\SchemaException;
9+
use LogicException;
10+
11+
use function sprintf;
12+
13+
final class InvalidViewDefinition extends LogicException implements SchemaException
14+
{
15+
public static function nameNotSet(): self
16+
{
17+
return new self('View name is not set.');
18+
}
19+
20+
public static function sqlNotSet(OptionallyQualifiedName $viewName): self
21+
{
22+
return new self(sprintf('SQL is not set for view %s.', $viewName->toString()));
23+
}
24+
}

src/Schema/View.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
class View extends AbstractNamedObject
1818
{
19+
/** @internal Use {@link View::editor()} to instantiate an editor and {@link ViewEditor::create()} to create a view. */
1920
public function __construct(string $name, private readonly string $sql)
2021
{
2122
parent::__construct($name);
@@ -30,4 +31,22 @@ public function getSql(): string
3031
{
3132
return $this->sql;
3233
}
34+
35+
/**
36+
* Instantiates a new view editor.
37+
*/
38+
public static function editor(): ViewEditor
39+
{
40+
return new ViewEditor();
41+
}
42+
43+
/**
44+
* Instantiates a new view editor and initializes it with the view's properties.
45+
*/
46+
public function edit(): ViewEditor
47+
{
48+
return self::editor()
49+
->setName($this->getObjectName())
50+
->setSQL($this->sql);
51+
}
3352
}

src/Schema/ViewEditor.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Schema;
6+
7+
use Doctrine\DBAL\Schema\Exception\InvalidViewDefinition;
8+
use Doctrine\DBAL\Schema\Name\OptionallyQualifiedName;
9+
10+
final class ViewEditor
11+
{
12+
private ?OptionallyQualifiedName $name = null;
13+
14+
private ?string $sql = null;
15+
16+
/** @internal Use {@link View::editor()} or {@link View::edit()} to create an instance */
17+
public function __construct()
18+
{
19+
}
20+
21+
public function setName(OptionallyQualifiedName $name): self
22+
{
23+
$this->name = $name;
24+
25+
return $this;
26+
}
27+
28+
/**
29+
* @param non-empty-string $unqualifiedName
30+
* @param ?non-empty-string $qualifier
31+
*/
32+
public function setUnquotedName(string $unqualifiedName, ?string $qualifier = null): self
33+
{
34+
$this->name = OptionallyQualifiedName::unquoted($unqualifiedName, $qualifier);
35+
36+
return $this;
37+
}
38+
39+
/**
40+
* @param non-empty-string $unqualifiedName
41+
* @param ?non-empty-string $qualifier
42+
*/
43+
public function setQuotedName(string $unqualifiedName, ?string $qualifier = null): self
44+
{
45+
$this->name = OptionallyQualifiedName::quoted($unqualifiedName, $qualifier);
46+
47+
return $this;
48+
}
49+
50+
public function setSQL(string $sql): self
51+
{
52+
$this->sql = $sql;
53+
54+
return $this;
55+
}
56+
57+
public function create(): View
58+
{
59+
if ($this->name === null) {
60+
throw InvalidViewDefinition::nameNotSet();
61+
}
62+
63+
if ($this->sql === null) {
64+
throw InvalidViewDefinition::sqlNotSet($this->name);
65+
}
66+
67+
return new View(
68+
$this->name->toString(),
69+
$this->sql,
70+
);
71+
}
72+
}

tests/Functional/Schema/PostgreSQLSchemaManagerTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,10 @@ public function testListTablesExcludesViews(): void
408408
$name = 'list_tables_excludes_views_test_view';
409409
$sql = 'SELECT * from list_tables_excludes_views';
410410

411-
$view = new View($name, $sql);
411+
$view = View::editor()
412+
->setUnquotedName($name)
413+
->setSQL($sql)
414+
->create();
412415

413416
$this->schemaManager->createView($view);
414417

tests/Functional/Schema/SchemaManagerFunctionalTestCase.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,11 @@ public function testListTablesDoesNotIncludeViews(): void
235235

236236
$sql = 'SELECT * FROM test_table_for_view';
237237

238-
$view = new View('test_view', $sql);
238+
$view = View::editor()
239+
->setUnquotedName('test_view')
240+
->setSQL($sql)
241+
->create();
242+
239243
$this->schemaManager->createView($view);
240244

241245
$tables = $this->schemaManager->listTables();
@@ -788,7 +792,10 @@ public function testCreateAndListViews(): void
788792
$name = 'doctrine_test_view';
789793
$sql = 'SELECT * FROM view_test_table';
790794

791-
$view = new View($name, $sql);
795+
$view = View::editor()
796+
->setUnquotedName($name)
797+
->setSQL($sql)
798+
->create();
792799

793800
$this->schemaManager->createView($view);
794801

0 commit comments

Comments
 (0)