Index: trunk/phase3/maintenance/archives/patch-oi_metadata.sql |
— | — | @@ -1,16 +1,16 @@ |
2 | | -
|
3 | | -ALTER TABLE /*$wgDBprefix*/oldimage
|
4 | | - DROP INDEX oi_name,
|
5 | | - ADD INDEX oi_name_timestamp (oi_name,oi_timestamp),
|
6 | | - ADD INDEX oi_name_archive_name (oi_name,oi_archive_name),
|
7 | | - ADD oi_metadata mediumblob NOT NULL,
|
8 | | - ADD oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
|
9 | | - ADD oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
|
10 | | - ADD oi_minor_mime varchar(32) NOT NULL default "unknown",
|
11 | | - ADD oi_deleted tinyint(1) unsigned NOT NULL default '0';
|
| 2 | +-- |
| 3 | +-- patch-indexes.sql |
| 4 | +-- |
| 5 | +-- Add data to allow for direct reference to old images |
| 6 | +-- They can be included into pages |
| 7 | +-- |
| 8 | + |
| 9 | +ALTER TABLE /*$wgDBprefix*/oldimage |
| 10 | + DROP INDEX oi_name, |
| 11 | + ADD INDEX oi_name_timestamp (oi_name,oi_timestamp), |
| 12 | + ADD INDEX oi_name_archive_name (oi_name,oi_archive_name), |
| 13 | + ADD oi_metadata mediumblob NOT NULL, |
| 14 | + ADD oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL, |
| 15 | + ADD oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown", |
| 16 | + ADD oi_minor_mime varchar(32) NOT NULL default "unknown", |
| 17 | + ADD oi_deleted tinyint(1) unsigned NOT NULL default '0'; |
Property changes on: trunk/phase3/maintenance/archives/patch-oi_metadata.sql |
___________________________________________________________________ |
Added: svn:eol-style |
12 | 18 | + native |
Property changes on: trunk/phase3/maintenance/language/digit2html.php |
___________________________________________________________________ |
Added: svn:eol-style |
13 | 19 | + native |
Index: trunk/phase3/includes/filerepo/OldLocalFile.php |
— | — | @@ -1,222 +1,222 @@ |
2 | | -<?php
|
3 | | -
|
4 | | -/**
|
5 | | - * Class to represent a file in the oldimage table
|
6 | | - *
|
7 | | - * @addtogroup FileRepo
|
8 | | - */
|
9 | | -class OldLocalFile extends LocalFile {
|
10 | | - var $requestedTime, $archive_name;
|
11 | | -
|
12 | | - const CACHE_VERSION = 1;
|
13 | | - const MAX_CACHE_ROWS = 20;
|
14 | | -
|
15 | | - function newFromTitle( $title, $repo, $time ) {
|
16 | | - return new self( $title, $repo, $time, null );
|
17 | | - }
|
18 | | -
|
19 | | - function newFromArchiveName( $title, $repo, $archiveName ) {
|
20 | | - return new self( $title, $repo, null, $archiveName );
|
21 | | - }
|
22 | | -
|
23 | | - function newFromRow( $row, $repo ) {
|
24 | | - $title = Title::makeTitle( NS_IMAGE, $row->oi_name );
|
25 | | - $file = new self( $title, $repo, null, $row->oi_archive_name );
|
26 | | - $file->loadFromRow( $row, 'oi_' );
|
27 | | - return $file;
|
28 | | - }
|
29 | | -
|
30 | | - /**
|
31 | | - * @param Title $title
|
32 | | - * @param FileRepo $repo
|
33 | | - * @param string $time Timestamp or null to load by archive name
|
34 | | - * @param string $archiveName Archive name or null to load by timestamp
|
35 | | - */
|
36 | | - function __construct( $title, $repo, $time, $archiveName ) {
|
37 | | - parent::__construct( $title, $repo );
|
38 | | - $this->requestedTime = $time;
|
39 | | - $this->archive_name = $archiveName;
|
40 | | - if ( is_null( $time ) && is_null( $archiveName ) ) {
|
41 | | - throw new MWException( __METHOD__.': must specify at least one of $time or $archiveName' );
|
42 | | - }
|
43 | | - }
|
44 | | -
|
45 | | - function getCacheKey() {
|
46 | | - $hashedName = md5($this->getName());
|
47 | | - return wfMemcKey( 'oldfile', $hashedName );
|
48 | | - }
|
49 | | -
|
50 | | - function getArchiveName() {
|
51 | | - if ( !isset( $this->archive_name ) ) {
|
52 | | - $this->load();
|
53 | | - }
|
54 | | - return $this->archive_name;
|
55 | | - }
|
56 | | -
|
57 | | - function isOld() {
|
58 | | - return true;
|
59 | | - }
|
60 | | -
|
61 | | - /**
|
62 | | - * Try to load file metadata from memcached. Returns true on success.
|
63 | | - */
|
64 | | - function loadFromCache() {
|
65 | | - global $wgMemc;
|
66 | | - wfProfileIn( __METHOD__ );
|
67 | | - $this->dataLoaded = false;
|
68 | | - $key = $this->getCacheKey();
|
69 | | - if ( !$key ) {
|
70 | | - return false;
|
71 | | - }
|
72 | | - $oldImages = $wgMemc->get( $key );
|
73 | | -
|
74 | | - if ( isset( $oldImages['version'] ) && $oldImages['version'] == MW_OLDFILE_VERSION ) {
|
75 | | - unset( $oldImages['version'] );
|
76 | | - $more = isset( $oldImages['more'] );
|
77 | | - unset( $oldImages['more'] );
|
78 | | - $found = false;
|
79 | | - if ( is_null( $this->requestedTime ) ) {
|
80 | | - foreach ( $oldImages as $timestamp => $info ) {
|
81 | | - if ( $info['archive_name'] == $this->archive_name ) {
|
82 | | - $found = true;
|
83 | | - break;
|
84 | | - }
|
85 | | - }
|
86 | | - } else {
|
87 | | - krsort( $oldImages );
|
88 | | - foreach ( $oldImages as $timestamp => $info ) {
|
89 | | - if ( $timestamp <= $this->requestedTime ) {
|
90 | | - $found = true;
|
91 | | - break;
|
92 | | - }
|
93 | | - }
|
94 | | - }
|
95 | | - if ( $found ) {
|
96 | | - wfDebug( "Pulling file metadata from cache key {$key}[{$timestamp}]\n" );
|
97 | | - $this->dataLoaded = true;
|
98 | | - foreach ( $cachedValues as $name => $value ) {
|
99 | | - $this->$name = $value;
|
100 | | - }
|
101 | | - } elseif ( $more ) {
|
102 | | - wfDebug( "Cache key was truncated, oldimage row might be found in the database\n" );
|
103 | | - } else {
|
104 | | - wfDebug( "Image did not exist at the specified time.\n" );
|
105 | | - $this->fileExists = false;
|
106 | | - $this->dataLoaded = true;
|
107 | | - }
|
108 | | - }
|
109 | | -
|
110 | | - if ( $this->dataLoaded ) {
|
111 | | - wfIncrStats( 'image_cache_hit' );
|
112 | | - } else {
|
113 | | - wfIncrStats( 'image_cache_miss' );
|
114 | | - }
|
115 | | -
|
116 | | - wfProfileOut( __METHOD__ );
|
117 | | - return $this->dataLoaded;
|
118 | | - }
|
119 | | -
|
120 | | - function saveToCache() {
|
121 | | - // Cache the entire history of the image (up to MAX_CACHE_ROWS).
|
122 | | - // This is expensive, so we only do it if $wgMemc is real
|
123 | | - global $wgMemc;
|
124 | | - if ( $wgMemc instanceof FakeMemcachedClient ) {
|
125 | | - return;
|
126 | | - }
|
127 | | - $key = $this->getCacheKey();
|
128 | | - if ( !$key ) {
|
129 | | - return;
|
130 | | - }
|
131 | | - wfProfileIn( __METHOD__ );
|
132 | | -
|
133 | | - $dbr = $this->repo->getSlaveDB();
|
134 | | - $res = $dbr->select( 'oldimage', $this->getCacheFields(),
|
135 | | - array( 'oi_name' => $this->getName() ), __METHOD__,
|
136 | | - array(
|
137 | | - 'LIMIT' => self::MAX_CACHE_ROWS + 1,
|
138 | | - 'ORDER BY' => 'oi_timestamp DESC',
|
139 | | - ));
|
140 | | - $cache = array( 'version' => self::CACHE_VERSION );
|
141 | | - $numRows = $dbr->numRows( $res );
|
142 | | - if ( $numRows > self::MAX_CACHE_ROWS ) {
|
143 | | - $cache['more'] = true;
|
144 | | - $numRows--;
|
145 | | - }
|
146 | | - for ( $i = 0; $i < $numRows; $i++ ) {
|
147 | | - $row = $dbr->fetchObject( $res );
|
148 | | - $this->decodeRow( $row, 'oi_' );
|
149 | | - $cache[$row->oi_timestamp] = $row;
|
150 | | - }
|
151 | | - $dbr->freeResult( $res );
|
152 | | - $wgMemc->set( $key, $cache, 7*86400 /* 1 week */ );
|
153 | | - wfProfileOut( __METHOD__ );
|
154 | | - }
|
155 | | -
|
156 | | - function loadFromDB() {
|
157 | | - wfProfileIn( __METHOD__ );
|
158 | | - $dbr = $this->repo->getSlaveDB();
|
159 | | - $conds = array( 'oi_name' => $this->getName() );
|
160 | | - if ( is_null( $this->requestedTime ) ) {
|
161 | | - $conds['oi_archive_name'] = $this->archive_name;
|
162 | | - } else {
|
163 | | - $conds[] = 'oi_timestamp <= ' . $dbr->addQuotes( $this->requestedTime );
|
164 | | - }
|
165 | | - $row = $dbr->selectRow( 'oldimage', $this->getCacheFields( 'oi_' ),
|
166 | | - $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
|
167 | | - if ( $row ) {
|
168 | | - $this->loadFromRow( $row, 'oi_' );
|
169 | | - } else {
|
170 | | - $this->fileExists = false;
|
171 | | - }
|
172 | | - $this->dataLoaded = true;
|
173 | | - }
|
174 | | -
|
175 | | - function getCacheFields( $prefix = 'img_' ) {
|
176 | | - $fields = parent::getCacheFields( $prefix );
|
177 | | - $fields[] = $prefix . 'archive_name';
|
178 | | -
|
179 | | - // XXX: Temporary hack before schema update
|
180 | | - $fields = array_diff( $fields, array(
|
181 | | - 'oi_media_type', 'oi_major_mime', 'oi_minor_mime', 'oi_metadata' ) );
|
182 | | - return $fields;
|
183 | | - }
|
184 | | -
|
185 | | - function getRel() {
|
186 | | - return 'archive/' . $this->getHashPath() . $this->getArchiveName();
|
187 | | - }
|
188 | | -
|
189 | | - function getUrlRel() {
|
190 | | - return 'archive/' . $this->getHashPath() . urlencode( $this->getArchiveName() );
|
191 | | - }
|
192 | | -
|
193 | | - function upgradeRow() {
|
194 | | - wfProfileIn( __METHOD__ );
|
195 | | -
|
196 | | - $this->loadFromFile();
|
197 | | -
|
198 | | - $dbw = $this->repo->getMasterDB();
|
199 | | - list( $major, $minor ) = self::splitMime( $this->mime );
|
200 | | -
|
201 | | - wfDebug(__METHOD__.': upgrading '.$this->archive_name." to the current schema\n");
|
202 | | - $dbw->update( 'oldimage',
|
203 | | - array(
|
204 | | - 'oi_width' => $this->width,
|
205 | | - 'oi_height' => $this->height,
|
206 | | - 'oi_bits' => $this->bits,
|
207 | | - #'oi_media_type' => $this->media_type,
|
208 | | - #'oi_major_mime' => $major,
|
209 | | - #'oi_minor_mime' => $minor,
|
210 | | - #'oi_metadata' => $this->metadata,
|
211 | | - ), array( 'oi_name' => $this->getName(), 'oi_timestamp' => $this->requestedTime ),
|
212 | | - __METHOD__
|
213 | | - );
|
214 | | - wfProfileOut( __METHOD__ );
|
215 | | - }
|
216 | | -
|
217 | | - // XXX: Temporary hack before schema update
|
218 | | - function maybeUpgradeRow() {}
|
219 | | -
|
220 | | -}
|
221 | | -
|
222 | | -
|
223 | | -?>
|
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Class to represent a file in the oldimage table |
| 6 | + * |
| 7 | + * @addtogroup FileRepo |
| 8 | + */ |
| 9 | +class OldLocalFile extends LocalFile { |
| 10 | + var $requestedTime, $archive_name; |
| 11 | + |
| 12 | + const CACHE_VERSION = 1; |
| 13 | + const MAX_CACHE_ROWS = 20; |
| 14 | + |
| 15 | + function newFromTitle( $title, $repo, $time ) { |
| 16 | + return new self( $title, $repo, $time, null ); |
| 17 | + } |
| 18 | + |
| 19 | + function newFromArchiveName( $title, $repo, $archiveName ) { |
| 20 | + return new self( $title, $repo, null, $archiveName ); |
| 21 | + } |
| 22 | + |
| 23 | + function newFromRow( $row, $repo ) { |
| 24 | + $title = Title::makeTitle( NS_IMAGE, $row->oi_name ); |
| 25 | + $file = new self( $title, $repo, null, $row->oi_archive_name ); |
| 26 | + $file->loadFromRow( $row, 'oi_' ); |
| 27 | + return $file; |
| 28 | + } |
| 29 | + |
| 30 | + /** |
| 31 | + * @param Title $title |
| 32 | + * @param FileRepo $repo |
| 33 | + * @param string $time Timestamp or null to load by archive name |
| 34 | + * @param string $archiveName Archive name or null to load by timestamp |
| 35 | + */ |
| 36 | + function __construct( $title, $repo, $time, $archiveName ) { |
| 37 | + parent::__construct( $title, $repo ); |
| 38 | + $this->requestedTime = $time; |
| 39 | + $this->archive_name = $archiveName; |
| 40 | + if ( is_null( $time ) && is_null( $archiveName ) ) { |
| 41 | + throw new MWException( __METHOD__.': must specify at least one of $time or $archiveName' ); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + function getCacheKey() { |
| 46 | + $hashedName = md5($this->getName()); |
| 47 | + return wfMemcKey( 'oldfile', $hashedName ); |
| 48 | + } |
| 49 | + |
| 50 | + function getArchiveName() { |
| 51 | + if ( !isset( $this->archive_name ) ) { |
| 52 | + $this->load(); |
| 53 | + } |
| 54 | + return $this->archive_name; |
| 55 | + } |
| 56 | + |
| 57 | + function isOld() { |
| 58 | + return true; |
| 59 | + } |
| 60 | + |
| 61 | + /** |
| 62 | + * Try to load file metadata from memcached. Returns true on success. |
| 63 | + */ |
| 64 | + function loadFromCache() { |
| 65 | + global $wgMemc; |
| 66 | + wfProfileIn( __METHOD__ ); |
| 67 | + $this->dataLoaded = false; |
| 68 | + $key = $this->getCacheKey(); |
| 69 | + if ( !$key ) { |
| 70 | + return false; |
| 71 | + } |
| 72 | + $oldImages = $wgMemc->get( $key ); |
| 73 | + |
| 74 | + if ( isset( $oldImages['version'] ) && $oldImages['version'] == MW_OLDFILE_VERSION ) { |
| 75 | + unset( $oldImages['version'] ); |
| 76 | + $more = isset( $oldImages['more'] ); |
| 77 | + unset( $oldImages['more'] ); |
| 78 | + $found = false; |
| 79 | + if ( is_null( $this->requestedTime ) ) { |
| 80 | + foreach ( $oldImages as $timestamp => $info ) { |
| 81 | + if ( $info['archive_name'] == $this->archive_name ) { |
| 82 | + $found = true; |
| 83 | + break; |
| 84 | + } |
| 85 | + } |
| 86 | + } else { |
| 87 | + krsort( $oldImages ); |
| 88 | + foreach ( $oldImages as $timestamp => $info ) { |
| 89 | + if ( $timestamp <= $this->requestedTime ) { |
| 90 | + $found = true; |
| 91 | + break; |
| 92 | + } |
| 93 | + } |
| 94 | + } |
| 95 | + if ( $found ) { |
| 96 | + wfDebug( "Pulling file metadata from cache key {$key}[{$timestamp}]\n" ); |
| 97 | + $this->dataLoaded = true; |
| 98 | + foreach ( $cachedValues as $name => $value ) { |
| 99 | + $this->$name = $value; |
| 100 | + } |
| 101 | + } elseif ( $more ) { |
| 102 | + wfDebug( "Cache key was truncated, oldimage row might be found in the database\n" ); |
| 103 | + } else { |
| 104 | + wfDebug( "Image did not exist at the specified time.\n" ); |
| 105 | + $this->fileExists = false; |
| 106 | + $this->dataLoaded = true; |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + if ( $this->dataLoaded ) { |
| 111 | + wfIncrStats( 'image_cache_hit' ); |
| 112 | + } else { |
| 113 | + wfIncrStats( 'image_cache_miss' ); |
| 114 | + } |
| 115 | + |
| 116 | + wfProfileOut( __METHOD__ ); |
| 117 | + return $this->dataLoaded; |
| 118 | + } |
| 119 | + |
| 120 | + function saveToCache() { |
| 121 | + // Cache the entire history of the image (up to MAX_CACHE_ROWS). |
| 122 | + // This is expensive, so we only do it if $wgMemc is real |
| 123 | + global $wgMemc; |
| 124 | + if ( $wgMemc instanceof FakeMemcachedClient ) { |
| 125 | + return; |
| 126 | + } |
| 127 | + $key = $this->getCacheKey(); |
| 128 | + if ( !$key ) { |
| 129 | + return; |
| 130 | + } |
| 131 | + wfProfileIn( __METHOD__ ); |
| 132 | + |
| 133 | + $dbr = $this->repo->getSlaveDB(); |
| 134 | + $res = $dbr->select( 'oldimage', $this->getCacheFields(), |
| 135 | + array( 'oi_name' => $this->getName() ), __METHOD__, |
| 136 | + array( |
| 137 | + 'LIMIT' => self::MAX_CACHE_ROWS + 1, |
| 138 | + 'ORDER BY' => 'oi_timestamp DESC', |
| 139 | + )); |
| 140 | + $cache = array( 'version' => self::CACHE_VERSION ); |
| 141 | + $numRows = $dbr->numRows( $res ); |
| 142 | + if ( $numRows > self::MAX_CACHE_ROWS ) { |
| 143 | + $cache['more'] = true; |
| 144 | + $numRows--; |
| 145 | + } |
| 146 | + for ( $i = 0; $i < $numRows; $i++ ) { |
| 147 | + $row = $dbr->fetchObject( $res ); |
| 148 | + $this->decodeRow( $row, 'oi_' ); |
| 149 | + $cache[$row->oi_timestamp] = $row; |
| 150 | + } |
| 151 | + $dbr->freeResult( $res ); |
| 152 | + $wgMemc->set( $key, $cache, 7*86400 /* 1 week */ ); |
| 153 | + wfProfileOut( __METHOD__ ); |
| 154 | + } |
| 155 | + |
| 156 | + function loadFromDB() { |
| 157 | + wfProfileIn( __METHOD__ ); |
| 158 | + $dbr = $this->repo->getSlaveDB(); |
| 159 | + $conds = array( 'oi_name' => $this->getName() ); |
| 160 | + if ( is_null( $this->requestedTime ) ) { |
| 161 | + $conds['oi_archive_name'] = $this->archive_name; |
| 162 | + } else { |
| 163 | + $conds[] = 'oi_timestamp <= ' . $dbr->addQuotes( $this->requestedTime ); |
| 164 | + } |
| 165 | + $row = $dbr->selectRow( 'oldimage', $this->getCacheFields( 'oi_' ), |
| 166 | + $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) ); |
| 167 | + if ( $row ) { |
| 168 | + $this->loadFromRow( $row, 'oi_' ); |
| 169 | + } else { |
| 170 | + $this->fileExists = false; |
| 171 | + } |
| 172 | + $this->dataLoaded = true; |
| 173 | + } |
| 174 | + |
| 175 | + function getCacheFields( $prefix = 'img_' ) { |
| 176 | + $fields = parent::getCacheFields( $prefix ); |
| 177 | + $fields[] = $prefix . 'archive_name'; |
| 178 | + |
| 179 | + // XXX: Temporary hack before schema update |
| 180 | + $fields = array_diff( $fields, array( |
| 181 | + 'oi_media_type', 'oi_major_mime', 'oi_minor_mime', 'oi_metadata' ) ); |
| 182 | + return $fields; |
| 183 | + } |
| 184 | + |
| 185 | + function getRel() { |
| 186 | + return 'archive/' . $this->getHashPath() . $this->getArchiveName(); |
| 187 | + } |
| 188 | + |
| 189 | + function getUrlRel() { |
| 190 | + return 'archive/' . $this->getHashPath() . urlencode( $this->getArchiveName() ); |
| 191 | + } |
| 192 | + |
| 193 | + function upgradeRow() { |
| 194 | + wfProfileIn( __METHOD__ ); |
| 195 | + |
| 196 | + $this->loadFromFile(); |
| 197 | + |
| 198 | + $dbw = $this->repo->getMasterDB(); |
| 199 | + list( $major, $minor ) = self::splitMime( $this->mime ); |
| 200 | + |
| 201 | + wfDebug(__METHOD__.': upgrading '.$this->archive_name." to the current schema\n"); |
| 202 | + $dbw->update( 'oldimage', |
| 203 | + array( |
| 204 | + 'oi_width' => $this->width, |
| 205 | + 'oi_height' => $this->height, |
| 206 | + 'oi_bits' => $this->bits, |
| 207 | + #'oi_media_type' => $this->media_type, |
| 208 | + #'oi_major_mime' => $major, |
| 209 | + #'oi_minor_mime' => $minor, |
| 210 | + #'oi_metadata' => $this->metadata, |
| 211 | + ), array( 'oi_name' => $this->getName(), 'oi_timestamp' => $this->requestedTime ), |
| 212 | + __METHOD__ |
| 213 | + ); |
| 214 | + wfProfileOut( __METHOD__ ); |
| 215 | + } |
| 216 | + |
| 217 | + // XXX: Temporary hack before schema update |
| 218 | + function maybeUpgradeRow() {} |
| 219 | + |
| 220 | +} |
| 221 | + |
| 222 | + |
| 223 | +?> |
Property changes on: trunk/phase3/includes/filerepo/OldLocalFile.php |
___________________________________________________________________ |
Added: svn:eol-style |
224 | 224 | + native |