Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F102276034
PhabricatorDatabaseRefParser.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Feb 19, 00:33
Size
6 KB
Mime Type
text/x-php
Expires
Fri, Feb 21, 00:33 (2 d)
Engine
blob
Format
Raw Data
Handle
24313722
Attached To
rPH Phabricator
PhabricatorDatabaseRefParser.php
View Options
<?php
final
class
PhabricatorDatabaseRefParser
extends
Phobject
{
private
$defaultPort
=
3306
;
private
$defaultUser
;
private
$defaultPass
;
public
function
setDefaultPort
(
$default_port
)
{
$this
->
defaultPort
=
$default_port
;
return
$this
;
}
public
function
getDefaultPort
()
{
return
$this
->
defaultPort
;
}
public
function
setDefaultUser
(
$default_user
)
{
$this
->
defaultUser
=
$default_user
;
return
$this
;
}
public
function
getDefaultUser
()
{
return
$this
->
defaultUser
;
}
public
function
setDefaultPass
(
$default_pass
)
{
$this
->
defaultPass
=
$default_pass
;
return
$this
;
}
public
function
getDefaultPass
()
{
return
$this
->
defaultPass
;
}
public
function
newRefs
(
array
$config
)
{
$default_port
=
$this
->
getDefaultPort
();
$default_user
=
$this
->
getDefaultUser
();
$default_pass
=
$this
->
getDefaultPass
();
$refs
=
array
();
$master_count
=
0
;
foreach
(
$config
as
$key
=>
$server
)
{
$host
=
$server
[
'host'
];
$port
=
idx
(
$server
,
'port'
,
$default_port
);
$user
=
idx
(
$server
,
'user'
,
$default_user
);
$disabled
=
idx
(
$server
,
'disabled'
,
false
);
$pass
=
idx
(
$server
,
'pass'
);
if
(
$pass
)
{
$pass
=
new
PhutilOpaqueEnvelope
(
$pass
);
}
else
{
$pass
=
clone
$default_pass
;
}
$role
=
$server
[
'role'
];
$is_master
=
(
$role
==
'master'
);
$use_persistent
=
(
bool
)
idx
(
$server
,
'persistent'
,
false
);
$ref
=
id
(
new
PhabricatorDatabaseRef
())
->
setHost
(
$host
)
->
setPort
(
$port
)
->
setUser
(
$user
)
->
setPass
(
$pass
)
->
setDisabled
(
$disabled
)
->
setIsMaster
(
$is_master
)
->
setUsePersistentConnections
(
$use_persistent
);
if
(
$is_master
)
{
$master_count
++;
}
$refs
[
$key
]
=
$ref
;
}
$is_partitioned
=
(
$master_count
>
1
);
if
(
$is_partitioned
)
{
$default_ref
=
null
;
$partition_map
=
array
();
foreach
(
$refs
as
$key
=>
$ref
)
{
if
(!
$ref
->
getIsMaster
())
{
continue
;
}
$server
=
$config
[
$key
];
$partition
=
idx
(
$server
,
'partition'
);
if
(!
is_array
(
$partition
))
{
throw
new
Exception
(
pht
(
'Phabricator is configured with multiple master databases, '
.
'but master "%s" is missing a "partition" configuration key to '
.
'define application partitioning.'
,
$ref
->
getRefKey
()));
}
$application_map
=
array
();
foreach
(
$partition
as
$application
)
{
if
(
$application
===
'default'
)
{
if
(
$default_ref
)
{
throw
new
Exception
(
pht
(
'Multiple masters (databases "%s" and "%s") specify that '
.
'they are the "default" partition. Only one master may be '
.
'the default.'
,
$ref
->
getRefKey
(),
$default_ref
->
getRefKey
()));
}
else
{
$default_ref
=
$ref
;
$ref
->
setIsDefaultPartition
(
true
);
}
}
else
if
(
isset
(
$partition_map
[
$application
]))
{
throw
new
Exception
(
pht
(
'Multiple masters (databases "%s" and "%s") specify that '
.
'they are the partition for application "%s". Each '
.
'application may be allocated to only one partition.'
,
$partition_map
[
$application
]->
getRefKey
(),
$ref
->
getRefKey
(),
$application
));
}
else
{
// TODO: We should check that the application is valid, to
// prevent typos in application names. However, we do not
// currently have an efficient way to enumerate all of the valid
// application database names.
$partition_map
[
$application
]
=
$ref
;
$application_map
[
$application
]
=
$application
;
}
}
$ref
->
setApplicationMap
(
$application_map
);
}
}
else
{
// If we only have one master, make it the default.
foreach
(
$refs
as
$ref
)
{
if
(
$ref
->
getIsMaster
())
{
$ref
->
setIsDefaultPartition
(
true
);
}
}
}
$ref_map
=
array
();
$master_keys
=
array
();
foreach
(
$refs
as
$ref
)
{
$ref_key
=
$ref
->
getRefKey
();
if
(
isset
(
$ref_map
[
$ref_key
]))
{
throw
new
Exception
(
pht
(
'Multiple configured databases have the same internal '
.
'key, "%s". You may have listed a database multiple times.'
,
$ref_key
));
}
else
{
$ref_map
[
$ref_key
]
=
$ref
;
if
(
$ref
->
getIsMaster
())
{
$master_keys
[]
=
$ref_key
;
}
}
}
foreach
(
$refs
as
$key
=>
$ref
)
{
if
(
$ref
->
getIsMaster
())
{
continue
;
}
$server
=
$config
[
$key
];
$partition
=
idx
(
$server
,
'partition'
);
if
(
$partition
!==
null
)
{
throw
new
Exception
(
pht
(
'Database "%s" is configured as a replica, but specifies a '
.
'"partition". Only master databases may have a partition '
.
'configuration. Replicas use the same configuration as the '
.
'master they follow.'
,
$ref
->
getRefKey
()));
}
$master_key
=
idx
(
$server
,
'master'
);
if
(
$master_key
===
null
)
{
if
(
$is_partitioned
)
{
throw
new
Exception
(
pht
(
'Database "%s" is configured as a replica, but does not '
.
'specify which "master" it follows in configuration. Valid '
.
'masters are: %s.'
,
$ref
->
getRefKey
(),
implode
(
', '
,
$master_keys
)));
}
else
if
(
$master_keys
)
{
$master_key
=
head
(
$master_keys
);
}
else
{
throw
new
Exception
(
pht
(
'Database "%s" is configured as a replica, but there is no '
.
'master configured.'
,
$ref
->
getRefKey
()));
}
}
if
(!
isset
(
$ref_map
[
$master_key
]))
{
throw
new
Exception
(
pht
(
'Database "%s" is configured as a replica and specifies a '
.
'master ("%s"), but that master is not a valid master. Valid '
.
'masters are: %s.'
,
implode
(
', '
,
$master_keys
)));
}
$master_ref
=
$ref_map
[
$master_key
];
$ref
->
setMasterRef
(
$ref_map
[
$master_key
]);
$master_ref
->
addReplicaRef
(
$ref
);
}
return
array_values
(
$refs
);
}
}
Event Timeline
Log In to Comment