@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3abstract class PhabricatorFactDimension extends PhabricatorFactDAO {
4
5 abstract protected function getDimensionColumnName();
6
7 final public function newDimensionID($key, $create = false) {
8 $map = $this->newDimensionMap(array($key), $create);
9 return idx($map, $key);
10 }
11
12 final public function newDimensionUnmap(array $ids) {
13 if (!$ids) {
14 return array();
15 }
16
17 $conn = $this->establishConnection('r');
18 $column = $this->getDimensionColumnName();
19
20 $rows = queryfx_all(
21 $conn,
22 'SELECT id, %C FROM %T WHERE id IN (%Ld)',
23 $column,
24 $this->getTableName(),
25 $ids);
26 $rows = ipull($rows, $column, 'id');
27
28 return $rows;
29 }
30
31 final public function newDimensionMap(array $keys, $create = false) {
32 if (!$keys) {
33 return array();
34 }
35
36 $conn = $this->establishConnection('r');
37 $column = $this->getDimensionColumnName();
38
39 $rows = queryfx_all(
40 $conn,
41 'SELECT id, %C FROM %T WHERE %C IN (%Ls)',
42 $column,
43 $this->getTableName(),
44 $column,
45 $keys);
46 $rows = ipull($rows, 'id', $column);
47
48 $map = array();
49 $need = array();
50 foreach ($keys as $key) {
51 if (isset($rows[$key])) {
52 $map[$key] = (int)$rows[$key];
53 } else {
54 $need[] = $key;
55 }
56 }
57
58 if (!$need) {
59 return $map;
60 }
61
62 if (!$create) {
63 return $map;
64 }
65
66 $sql = array();
67 foreach ($need as $key) {
68 $sql[] = qsprintf(
69 $conn,
70 '(%s)',
71 $key);
72 }
73
74 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
75 foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
76 queryfx(
77 $conn,
78 'INSERT IGNORE INTO %T (%C) VALUES %LQ',
79 $this->getTableName(),
80 $column,
81 $chunk);
82 }
83 unset($unguarded);
84
85 $rows = queryfx_all(
86 $conn,
87 'SELECT id, %C FROM %T WHERE %C IN (%Ls)',
88 $column,
89 $this->getTableName(),
90 $column,
91 $need);
92 $rows = ipull($rows, 'id', $column);
93
94 foreach ($need as $key) {
95 if (isset($rows[$key])) {
96 $map[$key] = (int)$rows[$key];
97 } else {
98 throw new Exception(
99 pht(
100 'Failed to load or generate dimension ID ("%s") for dimension '.
101 'key "%s".',
102 get_class($this),
103 $key));
104 }
105 }
106
107 return $map;
108 }
109
110}