Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
PersistentDatabaseCache.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Cache;
5
6use Iterator;
7use MediaWiki\Json\JsonCodec;
8use Wikimedia\Rdbms\IConnectionProvider;
9
17 private const VIRTUAL_DOMAIN = 'virtual-translate';
18 private const TABLE_NAME = 'translate_cache';
19
20 public function __construct(
21 private readonly IConnectionProvider $dbProvider,
22 private readonly JsonCodec $jsonCodec,
23 ) {
24 }
25
27 public function get( string ...$keynames ): array {
28 $dbr = $this->dbProvider->getReplicaDatabase( self::VIRTUAL_DOMAIN );
29 $rows = $dbr->newSelectQueryBuilder()
30 ->select( [ 'tc_key', 'tc_value', 'tc_exptime', 'tc_tag' ] )
31 ->from( self::TABLE_NAME )
32 ->where( [ 'tc_key' => $keynames ] )
33 ->caller( __METHOD__ )
34 ->fetchResultSet();
35
36 return $this->buildEntries( $rows );
37 }
38
40 public function getByTag( string $tag ): array {
41 $dbr = $this->dbProvider->getReplicaDatabase( self::VIRTUAL_DOMAIN );
42 $rows = $dbr->newSelectQueryBuilder()
43 ->select( [ 'tc_key', 'tc_value', 'tc_exptime', 'tc_tag' ] )
44 ->from( self::TABLE_NAME )
45 ->where( [ 'tc_tag' => $tag ] )
46 ->caller( __METHOD__ )
47 ->fetchResultSet();
48
49 return $this->buildEntries( $rows );
50 }
51
52 public function has( string $keyname ): bool {
53 $dbr = $this->dbProvider->getReplicaDatabase( self::VIRTUAL_DOMAIN );
54 $hasRow = $dbr->newSelectQueryBuilder()
55 ->select( 'tc_key' )
56 ->from( self::TABLE_NAME )
57 ->where( [ 'tc_key' => $keyname ] )
58 ->caller( __METHOD__ )
59 ->fetchRow();
60
61 return (bool)$hasRow;
62 }
63
64 public function hasEntryWithTag( string $tag ): bool {
65 $dbr = $this->dbProvider->getReplicaDatabase( self::VIRTUAL_DOMAIN );
66 $hasRow = $dbr->newSelectQueryBuilder()
67 ->select( 'tc_key' )
68 ->from( self::TABLE_NAME )
69 ->where( [ 'tc_tag' => $tag ] )
70 ->caller( __METHOD__ )
71 ->fetchRow();
72
73 return (bool)$hasRow;
74 }
75
76 public function set( PersistentCacheEntry ...$entries ): void {
77 $dbw = $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN );
78
79 foreach ( $entries as $entry ) {
80 $value = $this->jsonCodec->serialize( $entry->value() );
81 $dbw->newInsertQueryBuilder()
82 ->insertInto( self::TABLE_NAME )
83 ->row( [
84 'tc_key' => $entry->key(),
85 'tc_value' => $value,
86 'tc_exptime' => $dbw->timestampOrNull( $entry->exptime() ),
87 'tc_tag' => $entry->tag()
88 ] )
89 ->onDuplicateKeyUpdate()
90 ->uniqueIndexFields( [ 'tc_key' ] )
91 ->set( [
92 'tc_value' => $value,
93 'tc_exptime' => $dbw->timestampOrNull( $entry->exptime() ),
94 'tc_tag' => $entry->tag()
95 ] )
96 ->caller( __METHOD__ )
97 ->execute();
98 }
99 }
100
101 public function setExpiry( string $keyname, int $expiryTime ): void {
102 $dbw = $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN );
103 $dbw->newUpdateQueryBuilder()
104 ->update( self::TABLE_NAME )
105 ->set( [ 'tc_exptime' => $dbw->timestamp( $expiryTime ) ] )
106 ->where( [ 'tc_key' => $keyname ] )
107 ->caller( __METHOD__ )
108 ->execute();
109 }
110
111 public function delete( string ...$keynames ): void {
112 $dbw = $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN );
113 $dbw->newDeleteQueryBuilder()
114 ->deleteFrom( self::TABLE_NAME )
115 ->where( [ 'tc_key' => $keynames ] )
116 ->caller( __METHOD__ )
117 ->execute();
118 }
119
120 public function deleteEntriesWithTag( string $tag ): void {
121 $dbw = $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN );
122 $dbw->newDeleteQueryBuilder()
123 ->deleteFrom( self::TABLE_NAME )
124 ->where( [ 'tc_tag' => $tag ] )
125 ->caller( __METHOD__ )
126 ->execute();
127 }
128
129 public function clear(): void {
130 $dbw = $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN );
131 $dbw->newDeleteQueryBuilder()
132 ->deleteFrom( self::TABLE_NAME )
133 ->where( '*' )
134 ->caller( __METHOD__ )
135 ->execute();
136 }
137
139 private function buildEntries( Iterator $rows ): array {
140 $entries = [];
141 foreach ( $rows as $row ) {
142 $entries[] = new PersistentCacheEntry(
143 $row->tc_key,
144 $this->jsonCodec->deserialize( $row->tc_value ),
145 $row->tc_exptime ? (int)wfTimestamp( TS_UNIX, $row->tc_exptime ) : null,
146 $row->tc_tag
147 );
148 }
149
150 return $entries;
151 }
152}
A persistent cache implementation using the database.
Defines what method should be provided by a class implementing a persistent cache.