23use InvalidArgumentException;
53 $dbr = $this->getReplicaDb();
55 $depsBlobByEntity = $this->fetchDependencyBlobs( $entities,
$dbr );
57 $storedPathsByEntity = [];
58 foreach ( $depsBlobByEntity as $entity => $depsBlob ) {
59 $storedPathsByEntity[$entity] = json_decode( $depsBlob,
true );
63 foreach ( $entities as $entity ) {
64 $paths = $storedPathsByEntity[$entity] ?? [];
75 if ( !$dataByEntity ) {
79 $dbw = $this->getPrimaryDB();
80 $depsBlobByEntity = $this->fetchDependencyBlobs( array_keys( $dataByEntity ), $dbw );
83 foreach ( $dataByEntity as $entity => $data ) {
84 list( $module, $variant ) = $this->getEntityNameComponents( $entity );
85 if ( !is_array( $data[self::KEY_PATHS] ) ) {
86 throw new InvalidArgumentException(
"Invalid entry for '$entity'" );
90 $paths = array_values( array_unique( $data[self::KEY_PATHS] ) );
91 sort( $paths, SORT_STRING );
92 $blob = json_encode( $paths, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
94 $existingBlob = $depsBlobByEntity[$entity] ??
null;
95 if (
$blob !== $existingBlob ) {
97 'md_module' => $module,
98 'md_skin' => $variant,
106 foreach ( $rows as $row ) {
110 [ [
'md_module',
'md_skin' ] ],
112 'md_deps' => $row[
'md_deps'],
119 public function remove(
$type, $entities ) {
127 $dbw = $this->getPrimaryDB();
128 $disjunctionConds = [];
129 foreach ( (array)$entities as $entity ) {
130 list( $module, $variant ) = $this->getEntityNameComponents( $entity );
131 $disjunctionConds[] = $dbw->makeList(
132 [
'md_skin' => $variant,
'md_module' => $module ],
137 if ( $disjunctionConds ) {
140 $dbw->makeList( $disjunctionConds, $dbw::LIST_OR ),
151 private function fetchDependencyBlobs( array $entities,
IDatabase $db ) {
152 $modulesByVariant = [];
153 foreach ( $entities as $entity ) {
154 list( $module, $variant ) = $this->getEntityNameComponents( $entity );
155 $modulesByVariant[$variant][] = $module;
158 $disjunctionConds = [];
159 foreach ( $modulesByVariant as $variant =>
$modules ) {
160 $disjunctionConds[] = $db->
makeList(
161 [
'md_skin' => $variant,
'md_module' =>
$modules ],
166 $depsBlobByEntity = [];
168 if ( $disjunctionConds ) {
171 [
'md_module',
'md_skin',
'md_deps' ],
172 $db->
makeList( $disjunctionConds, $db::LIST_OR ),
176 foreach (
$res as $row ) {
177 $entity =
"{$row->md_module}|{$row->md_skin}";
178 $depsBlobByEntity[$entity] = $row->md_deps;
182 return $depsBlobByEntity;
188 private function getReplicaDb() {
190 ->getConnectionRef(
DB_REPLICA, [],
false, ( $this->lb )::CONN_TRX_AUTOCOMMIT );
196 private function getPrimaryDb() {
198 ->getConnectionRef(
DB_PRIMARY, [],
false, ( $this->lb )::CONN_TRX_AUTOCOMMIT );
205 private function getEntityNameComponents( $entity ) {
206 $parts = explode(
'|', $entity, 2 );
207 if ( count( $parts ) !== 2 ) {
208 throw new InvalidArgumentException(
"Invalid module entity '$entity'" );