1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Doctrine\ODM\MongoDB\Tools\Console\Command\Schema; |
6
|
|
|
|
7
|
|
|
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; |
8
|
|
|
use Doctrine\ODM\MongoDB\SchemaManager; |
9
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
10
|
|
|
use Symfony\Component\Console\Input\InputOption; |
11
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
12
|
|
|
use function array_filter; |
13
|
|
|
use function sprintf; |
14
|
|
|
use function ucfirst; |
15
|
|
|
|
16
|
|
|
class CreateCommand extends AbstractCommand |
17
|
|
|
{ |
18
|
|
|
/** @var string[] */ |
19
|
|
|
private $createOrder = [self::COLLECTION, self::INDEX]; |
20
|
|
|
|
21
|
|
|
/** @var int|null */ |
22
|
|
|
private $timeout; |
23
|
|
|
|
24
|
|
|
protected function configure() |
25
|
|
|
{ |
26
|
|
|
$this |
27
|
|
|
->setName('odm:schema:create') |
28
|
|
|
->addOption('class', 'c', InputOption::VALUE_REQUIRED, 'Document class to process (default: all classes)') |
29
|
|
|
->addOption('timeout', 't', InputOption::VALUE_OPTIONAL, 'Timeout (ms) for acknowledged index creation') |
30
|
|
|
->addOption(self::COLLECTION, null, InputOption::VALUE_NONE, 'Create collections') |
31
|
|
|
->addOption(self::INDEX, null, InputOption::VALUE_NONE, 'Create indexes') |
32
|
|
|
->setDescription('Create databases, collections and indexes for your documents') |
33
|
|
|
; |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
37
|
|
|
{ |
38
|
|
|
$create = array_filter($this->createOrder, function ($option) use ($input) { |
39
|
|
|
return $input->getOption($option); |
40
|
|
|
}); |
41
|
|
|
|
42
|
|
|
// Default to the full creation order if no options were specified |
43
|
|
|
$create = empty($create) ? $this->createOrder : $create; |
44
|
|
|
|
45
|
|
|
$class = $input->getOption('class'); |
46
|
|
|
|
47
|
|
|
$timeout = $input->getOption('timeout'); |
48
|
|
|
$this->timeout = isset($timeout) ? (int) $timeout : null; |
49
|
|
|
|
50
|
|
|
$sm = $this->getSchemaManager(); |
51
|
|
|
$isErrored = false; |
52
|
|
|
|
53
|
|
View Code Duplication |
foreach ($create as $option) { |
|
|
|
|
54
|
|
|
try { |
55
|
|
|
if (isset($class)) { |
56
|
|
|
$this->{'processDocument' . ucfirst($option)}($sm, $class); |
57
|
|
|
} else { |
58
|
|
|
$this->{'process' . ucfirst($option)}($sm); |
59
|
|
|
} |
60
|
|
|
$output->writeln(sprintf( |
61
|
|
|
'Created <comment>%s%s</comment> for <info>%s</info>', |
62
|
|
|
$option, |
63
|
|
|
(isset($class) ? ($option === self::INDEX ? '(es)' : '') : ($option === self::INDEX ? 'es' : 's')), |
64
|
|
|
($class ?? 'all classes') |
65
|
|
|
)); |
66
|
|
|
} catch (\Throwable $e) { |
67
|
|
|
$output->writeln('<error>' . $e->getMessage() . '</error>'); |
68
|
|
|
$isErrored = true; |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
return $isErrored ? 255 : 0; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
protected function processDocumentCollection(SchemaManager $sm, $document) |
76
|
|
|
{ |
77
|
|
|
$sm->createDocumentCollection($document); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
protected function processCollection(SchemaManager $sm) |
81
|
|
|
{ |
82
|
|
|
$sm->createCollections(); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
protected function processDocumentDb(SchemaManager $sm, $document) |
86
|
|
|
{ |
87
|
|
|
throw new \BadMethodCallException('A database is created automatically by MongoDB (>= 3.0).'); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
protected function processDb(SchemaManager $sm) |
91
|
|
|
{ |
92
|
|
|
throw new \BadMethodCallException('A database is created automatically by MongoDB (>= 3.0).'); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
protected function processDocumentIndex(SchemaManager $sm, $document) |
96
|
|
|
{ |
97
|
|
|
$sm->ensureDocumentIndexes($document, $this->timeout); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
protected function processIndex(SchemaManager $sm) |
101
|
|
|
{ |
102
|
|
|
$sm->ensureIndexes($this->timeout); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
protected function processDocumentProxy(SchemaManager $sm, $document) |
106
|
|
|
{ |
107
|
|
|
$classMetadata = $this->getMetadataFactory()->getMetadataFor($document); |
108
|
|
|
|
109
|
|
|
if ($classMetadata->isEmbeddedDocument || $classMetadata->isMappedSuperclass || $classMetadata->isQueryResultDocument) { |
110
|
|
|
return; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$this->getDocumentManager()->getProxyFactory()->generateProxyClasses([$classMetadata]); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
protected function processProxy(SchemaManager $sm) |
117
|
|
|
{ |
118
|
|
|
$classes = array_filter($this->getMetadataFactory()->getAllMetadata(), function (ClassMetadata $classMetadata) { |
119
|
|
|
return ! $classMetadata->isEmbeddedDocument && ! $classMetadata->isMappedSuperclass && ! $classMetadata->isQueryResultDocument; |
120
|
|
|
}); |
121
|
|
|
|
122
|
|
|
$this->getDocumentManager()->getProxyFactory()->generateProxyClasses($classes); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.