3 final class PhabricatorDatabaseRefParser
6 private $defaultPort = 3306;
10 public function setDefaultPort($default_port) {
11 $this->defaultPort
= $default_port;
15 public function getDefaultPort() {
16 return $this->defaultPort
;
19 public function setDefaultUser($default_user) {
20 $this->defaultUser
= $default_user;
24 public function getDefaultUser() {
25 return $this->defaultUser
;
28 public function setDefaultPass($default_pass) {
29 $this->defaultPass
= $default_pass;
33 public function getDefaultPass() {
34 return $this->defaultPass
;
37 public function newRefs(array $config) {
38 $default_port = $this->getDefaultPort();
39 $default_user = $this->getDefaultUser();
40 $default_pass = $this->getDefaultPass();
45 foreach ($config as $key => $server) {
46 $host = $server['host'];
47 $port = idx($server, 'port', $default_port);
48 $user = idx($server, 'user', $default_user);
49 $disabled = idx($server, 'disabled', false);
51 $pass = idx($server, 'pass');
53 $pass = new PhutilOpaqueEnvelope($pass);
55 $pass = clone $default_pass;
58 $role = $server['role'];
59 $is_master = ($role == 'master');
61 $use_persistent = (bool)idx($server, 'persistent', false);
63 $ref = id(new PhabricatorDatabaseRef())
68 ->setDisabled($disabled)
69 ->setIsMaster($is_master)
70 ->setUsePersistentConnections($use_persistent);
79 $is_partitioned = ($master_count > 1);
80 if ($is_partitioned) {
82 $partition_map = array();
83 foreach ($refs as $key => $ref) {
84 if (!$ref->getIsMaster()) {
88 $server = $config[$key];
89 $partition = idx($server, 'partition');
90 if (!is_array($partition)) {
93 'Phabricator is configured with multiple master databases, '.
94 'but master "%s" is missing a "partition" configuration key to '.
95 'define application partitioning.',
99 $application_map = array();
100 foreach ($partition as $application) {
101 if ($application === 'default') {
105 'Multiple masters (databases "%s" and "%s") specify that '.
106 'they are the "default" partition. Only one master may be '.
109 $default_ref->getRefKey()));
112 $ref->setIsDefaultPartition(true);
114 } else if (isset($partition_map[$application])) {
117 'Multiple masters (databases "%s" and "%s") specify that '.
118 'they are the partition for application "%s". Each '.
119 'application may be allocated to only one partition.',
120 $partition_map[$application]->getRefKey(),
124 // TODO: We should check that the application is valid, to
125 // prevent typos in application names. However, we do not
126 // currently have an efficient way to enumerate all of the valid
127 // application database names.
129 $partition_map[$application] = $ref;
130 $application_map[$application] = $application;
134 $ref->setApplicationMap($application_map);
137 // If we only have one master, make it the default.
138 foreach ($refs as $ref) {
139 if ($ref->getIsMaster()) {
140 $ref->setIsDefaultPartition(true);
146 $master_keys = array();
147 foreach ($refs as $ref) {
148 $ref_key = $ref->getRefKey();
149 if (isset($ref_map[$ref_key])) {
152 'Multiple configured databases have the same internal '.
153 'key, "%s". You may have listed a database multiple times.',
156 $ref_map[$ref_key] = $ref;
157 if ($ref->getIsMaster()) {
158 $master_keys[] = $ref_key;
163 foreach ($refs as $key => $ref) {
164 if ($ref->getIsMaster()) {
168 $server = $config[$key];
170 $partition = idx($server, 'partition');
171 if ($partition !== null) {
174 'Database "%s" is configured as a replica, but specifies a '.
175 '"partition". Only master databases may have a partition '.
176 'configuration. Replicas use the same configuration as the '.
177 'master they follow.',
181 $master_key = idx($server, 'master');
182 if ($master_key === null) {
183 if ($is_partitioned) {
186 'Database "%s" is configured as a replica, but does not '.
187 'specify which "master" it follows in configuration. Valid '.
190 implode(', ', $master_keys)));
191 } else if ($master_keys) {
192 $master_key = head($master_keys);
196 'Database "%s" is configured as a replica, but there is no '.
197 'master configured.',
202 if (!isset($ref_map[$master_key])) {
205 'Database "%s" is configured as a replica and specifies a '.
206 'master ("%s"), but that master is not a valid master. Valid '.
210 implode(', ', $master_keys)));
213 $master_ref = $ref_map[$master_key];
214 $ref->setMasterRef($ref_map[$master_key]);
215 $master_ref->addReplicaRef($ref);
218 return array_values($refs);