Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14013645
D19379.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D19379.diff
View Options
diff --git a/resources/sql/autopatches/20180418.almanac.network.unique.php b/resources/sql/autopatches/20180418.almanac.network.unique.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20180418.almanac.network.unique.php
@@ -0,0 +1,46 @@
+<?php
+
+$table = new AlmanacNetwork();
+$conn = $table->establishConnection('w');
+
+queryfx(
+ $conn,
+ 'LOCK TABLES %T WRITE',
+ $table->getTableName());
+
+$seen = array();
+foreach (new LiskMigrationIterator($table) as $network) {
+ $name = $network->getName();
+
+ // If this is the first copy of this row we've seen, mark it as seen and
+ // move on.
+ if (empty($seen[$name])) {
+ $seen[$name] = 1;
+ continue;
+ }
+
+ // Otherwise, rename this row.
+ while (true) {
+ $new_name = $name.'-'.$seen[$name];
+ if (empty($seen[$new_name])) {
+ $network->setName($new_name);
+ try {
+ $network->save();
+ break;
+ } catch (AphrontDuplicateKeyQueryException $ex) {
+ // New name is a dupe of a network we haven't seen yet.
+ }
+ }
+ $seen[$name]++;
+ }
+ $seen[$new_name] = 1;
+}
+
+queryfx(
+ $conn,
+ 'ALTER TABLE %T ADD UNIQUE KEY `key_name` (name)',
+ $table->getTableName());
+
+queryfx(
+ $conn,
+ 'UNLOCK TABLES');
diff --git a/src/applications/almanac/query/AlmanacNetworkQuery.php b/src/applications/almanac/query/AlmanacNetworkQuery.php
--- a/src/applications/almanac/query/AlmanacNetworkQuery.php
+++ b/src/applications/almanac/query/AlmanacNetworkQuery.php
@@ -5,6 +5,7 @@
private $ids;
private $phids;
+ private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -20,6 +21,11 @@
return new AlmanacNetwork();
}
+ public function withNames(array $names) {
+ $this->names = $names;
+ return $this;
+ }
+
public function withNameNgrams($ngrams) {
return $this->withNgramsConstraint(
new AlmanacNetworkNameNgrams(),
@@ -47,6 +53,13 @@
$this->phids);
}
+ if ($this->names !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'network.name IN (%Ls)',
+ $this->names);
+ }
+
return $where;
}
diff --git a/src/applications/almanac/storage/AlmanacNetwork.php b/src/applications/almanac/storage/AlmanacNetwork.php
--- a/src/applications/almanac/storage/AlmanacNetwork.php
+++ b/src/applications/almanac/storage/AlmanacNetwork.php
@@ -24,8 +24,15 @@
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
- 'name' => 'text128',
+ 'name' => 'sort128',
'mailKey' => 'bytes20',
+
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_name' => array(
+ 'columns' => array('name'),
+ 'unique' => true,
+ ),
),
) + parent::getConfiguration();
}
diff --git a/src/applications/almanac/util/AlmanacNames.php b/src/applications/almanac/util/AlmanacNames.php
--- a/src/applications/almanac/util/AlmanacNames.php
+++ b/src/applications/almanac/util/AlmanacNames.php
@@ -6,57 +6,58 @@
if (strlen($name) < 3) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names must be '.
- 'at least 3 characters long.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'must be at least 3 characters long.'));
}
if (strlen($name) > 100) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may not '.
- 'be more than 100 characters long.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'may not be more than 100 characters long.'));
}
if (!preg_match('/^[a-z0-9.-]+\z/', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may only '.
- 'contain lowercase letters, numbers, hyphens, and periods.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'may only contain lowercase letters, numbers, hyphens, and '.
+ 'periods.'));
}
if (preg_match('/(^|\\.)\d+(\z|\\.)/', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may not '.
- 'have any segments containing only digits.'));
+ 'Almanac service, device, network, property and namespace names '.
+ 'may not have any segments containing only digits.'));
}
if (preg_match('/\.\./', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may not '.
- 'contain multiple consecutive periods.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'may not contain multiple consecutive periods.'));
}
if (preg_match('/\\.-|-\\./', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may not '.
- 'contain hyphens adjacent to periods.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'may not contain hyphens adjacent to periods.'));
}
if (preg_match('/--/', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names may not '.
- 'contain multiple consecutive hyphens.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'may not contain multiple consecutive hyphens.'));
}
if (!preg_match('/^[a-z0-9].*[a-z0-9]\z/', $name)) {
throw new Exception(
pht(
- 'Almanac service, device, property and namespace names must begin '.
- 'and end with a letter or number.'));
+ 'Almanac service, device, property, network and namespace names '.
+ 'must begin and end with a letter or number.'));
}
}
diff --git a/src/applications/almanac/xaction/AlmanacNetworkNameTransaction.php b/src/applications/almanac/xaction/AlmanacNetworkNameTransaction.php
--- a/src/applications/almanac/xaction/AlmanacNetworkNameTransaction.php
+++ b/src/applications/almanac/xaction/AlmanacNetworkNameTransaction.php
@@ -38,6 +38,37 @@
pht('Network name is required.'));
}
+ foreach ($xactions as $xaction) {
+ $name = $xaction->getNewValue();
+
+ $message = null;
+ try {
+ AlmanacNames::validateName($name);
+ } catch (Exception $ex) {
+ $message = $ex->getMessage();
+ }
+
+ if ($message !== null) {
+ $errors[] = $this->newInvalidError($message, $xaction);
+ continue;
+ }
+
+ if ($name === $object->getName()) {
+ continue;
+ }
+
+ $other = id(new AlmanacNetworkQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withNames(array($name))
+ ->executeOne();
+ if ($other && ($other->getID() != $object->getID())) {
+ $errors[] = $this->newInvalidError(
+ pht('Almanac networks must have unique names.'),
+ $xaction);
+ continue;
+ }
+ }
+
return $errors;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 3, 8:36 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6753329
Default Alt Text
D19379.diff (7 KB)
Attached To
Mode
D19379: Add unique constraint for Almanac network names
Attached
Detach File
Event Timeline
Log In to Comment