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