Skip to content

Commit 8c45c93

Browse files
committed
Issue #752: Migrate all the location status to bits
1 parent a0600a4 commit 8c45c93

16 files changed

Lines changed: 125 additions & 66 deletions

classes/local/object_manipulator/candidates/recoverer_candidates.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,6 @@ public function get_candidates_sql() {
5050
* @return array
5151
*/
5252
public function get_candidates_sql_params() {
53-
return ['location' => OBJECT_LOCATION_ERROR];
53+
return ['location' => OBJECT_LOCATION_MISSING];
5454
}
5555
}

classes/local/report/location_report_builder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function build_report($reportid) {
4646
OBJECT_LOCATION_DUPLICATED,
4747
OBJECT_LOCATION_EXTERNAL,
4848
OBJECT_LOCATION_ORPHANED,
49-
OBJECT_LOCATION_ERROR,
49+
OBJECT_LOCATION_MISSING,
5050
];
5151

5252
$totalcount = 0;

classes/local/report/object_location_history_table.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public function query_db($pagesize, $useinitialsbar = true) {
136136
$duplicatedrecord = $rawrecords[$id . OBJECT_LOCATION_DUPLICATED] ?? $emptyrecord;
137137
$orphanedrecord = $rawrecords[$id . OBJECT_LOCATION_ORPHANED] ?? $emptyrecord;
138138
$externalrecord = $rawrecords[$id . OBJECT_LOCATION_EXTERNAL] ?? $emptyrecord;
139-
$errorrecord = $rawrecords[$id . OBJECT_LOCATION_ERROR] ?? $emptyrecord;
139+
$missingrecord = $rawrecords[$id . OBJECT_LOCATION_MISSING] ?? $emptyrecord;
140140
$filedir = $rawrecords[$id . 'filedir'] ?? $emptyrecord;
141141
$total = $rawrecords[$id . 'total'] ?? $emptyrecord;
142142

@@ -154,8 +154,8 @@ public function query_db($pagesize, $useinitialsbar = true) {
154154
$row['orphaned_size'] = get_string('object_status:location:orphanedsizeunknown', 'tool_objectfs');
155155
$row['external_count'] = $externalrecord->count;
156156
$row['external_size'] = $externalrecord->size;
157-
$row['missing_count'] = $errorrecord->count;
158-
$row['missing_size'] = $errorrecord->size;
157+
$row['missing_count'] = $missingrecord->count;
158+
$row['missing_size'] = $missingrecord->size;
159159
$row['total_count'] = $total->count;
160160
$row['total_size'] = $total->size;
161161
$row['filedir_count'] = $filedir->count;
@@ -167,7 +167,7 @@ public function query_db($pagesize, $useinitialsbar = true) {
167167
$row['duplicated_count'] = number_format($duplicatedrecord->count);
168168
$row['orphaned_count'] = number_format($orphanedrecord->count);
169169
$row['external_count'] = number_format($externalrecord->count);
170-
$row['missing_count'] = number_format($errorrecord->count);
170+
$row['missing_count'] = number_format($missingrecord->count);
171171
$row['total_count'] = number_format($total->count);
172172
$row['filedir_count'] = number_format($filedir->count);
173173
$row['delta_count'] = number_format($deltacount);
@@ -176,7 +176,7 @@ public function query_db($pagesize, $useinitialsbar = true) {
176176
$this->duplicatedsizes[] = $this->size_to_mb($duplicatedrecord->size);
177177
$this->orphanedsizes[] = $this->size_to_mb($orphanedrecord->size);
178178
$this->externalsizes[] = $this->size_to_mb($externalrecord->size);
179-
$this->missingsizes[] = $this->size_to_mb($errorrecord->size);
179+
$this->missingsizes[] = $this->size_to_mb($missingrecord->size);
180180
$this->totalsizes[] = $this->size_to_mb($total->size);
181181
$this->filedirsizes[] = $this->size_to_mb($filedir->size);
182182
$this->deltasizes[] = $this->size_to_mb($deltasize);

classes/local/report/object_status_history_table.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,11 @@ public function get_file_location_string($filelocation) {
240240
'filedir' => 'object_status:filedir',
241241
'deltaa' => 'object_status:delta:a',
242242
'deltab' => 'object_status:delta:b',
243-
OBJECT_LOCATION_ERROR => 'object_status:location:error',
243+
OBJECT_LOCATION_MISSING => 'object_status:location:missing',
244+
OBJECT_LOCATION_ORPHANED => 'object_status:location:orphaned',
244245
OBJECT_LOCATION_LOCAL => 'object_status:location:local',
245246
OBJECT_LOCATION_DUPLICATED => 'object_status:location:duplicated',
246247
OBJECT_LOCATION_EXTERNAL => 'object_status:location:external',
247-
OBJECT_LOCATION_ORPHANED => 'object_status:location:orphaned',
248248
];
249249
if (isset($locationstringmap[$filelocation])) {
250250
return get_string($locationstringmap[$filelocation], 'tool_objectfs');
@@ -263,6 +263,7 @@ public function get_file_location_class($filelocation): string {
263263
case 'deltaa':
264264
case 'deltab':
265265
case OBJECT_LOCATION_ERROR:
266+
case OBJECT_LOCATION_MISSING:
266267
case OBJECT_LOCATION_ORPHANED:
267268
$class = 'table-danger';
268269
break;

classes/local/store/object_file_system.php

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -288,20 +288,21 @@ public function is_file_readable_externally_by_hash($contenthash) {
288288
* @return int
289289
*/
290290
public function get_object_location_from_hash($contenthash) {
291-
$localreadable = $this->is_file_readable_locally_by_hash($contenthash);
292-
$externalreadable = $this->is_file_readable_externally_by_hash($contenthash);
293-
294-
if ($localreadable && $externalreadable) {
295-
return OBJECT_LOCATION_DUPLICATED;
296-
} else if ($localreadable && !$externalreadable) {
297-
return OBJECT_LOCATION_LOCAL;
298-
} else if (!$localreadable && $externalreadable) {
299-
return OBJECT_LOCATION_EXTERNAL;
300-
} else {
301-
// Object is not anywhere - we toggle an error state in the DB.
302-
manager::update_object_by_hash($contenthash, OBJECT_LOCATION_ERROR);
303-
return OBJECT_LOCATION_ERROR;
291+
// The mdl_files bit is always set because this function is only called
292+
// for objects known to be referenced in the files table.
293+
$location = OBJECT_LOCATION_IN_MDL_FILES;
294+
if ($this->is_file_readable_locally_by_hash($contenthash)) {
295+
$location |= OBJECT_LOCATION_IN_FILEDIR;
296+
}
297+
if ($this->is_file_readable_externally_by_hash($contenthash)) {
298+
$location |= OBJECT_LOCATION_IN_REMOTE;
299+
}
300+
301+
if ($location === OBJECT_LOCATION_MISSING) {
302+
// Object exists in mdl_files but is not anywhere physically — record missing state.
303+
manager::update_object_by_hash($contenthash, OBJECT_LOCATION_MISSING);
304304
}
305+
return $location;
305306
}
306307

307308
/**
@@ -465,7 +466,7 @@ public function readfile(\stored_file $file) {
465466
$this->logger->log_object_read('readfile', $path, $file->get_filesize());
466467

467468
if ($success === false) {
468-
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_ERROR);
469+
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_MISSING);
469470
}
470471
}
471472
}
@@ -495,7 +496,7 @@ public function get_content(\stored_file $file) {
495496
$this->logger->log_object_read('file_get_contents', $path, $file->get_filesize());
496497

497498
if (!$contents) {
498-
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_ERROR);
499+
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_MISSING);
499500
}
500501

501502
return $contents;
@@ -589,7 +590,7 @@ public function get_content_file_handle(\stored_file $file, $type = \stored_file
589590
$this->logger->log_object_read('get_file_handle_for_path', $path, $file->get_filesize());
590591

591592
if (!$filehandle) {
592-
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_ERROR);
593+
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_MISSING);
593594
}
594595

595596
return $filehandle;
@@ -720,6 +721,7 @@ public function delete_object_from_hash($contenthash) {
720721
$this->delete_external_file_from_hash($contenthash);
721722
break;
722723

724+
case OBJECT_LOCATION_MISSING:
723725
case OBJECT_LOCATION_ERROR:
724726
default:
725727
return;

classes/local/store/s3/file_system.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function readfile(\stored_file $file) {
7171
$this->get_logger()->log_object_read('readfile', $path, $file->get_filesize());
7272

7373
if ($success === false) {
74-
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_ERROR);
74+
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_MISSING);
7575
throw new \file_exception('storedfilecannotreadfile', $file->get_filename());
7676
}
7777
}

classes/log/aggregate_logger.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class aggregate_logger extends objectfs_logger {
6464
public function __construct() {
6565
parent::__construct();
6666
$this->movestatistics = [
67-
OBJECT_LOCATION_ERROR => [],
67+
OBJECT_LOCATION_MISSING => [],
68+
OBJECT_LOCATION_ORPHANED => [],
6869
OBJECT_LOCATION_LOCAL => [],
6970
OBJECT_LOCATION_DUPLICATED => [],
7071
OBJECT_LOCATION_EXTERNAL => [],
@@ -157,16 +158,16 @@ protected function output_move_statistic($movestatistic, $initiallocation, $fina
157158
*/
158159
public function location_to_string($location) {
159160
switch ($location) {
160-
case OBJECT_LOCATION_ERROR:
161-
return 'error';
161+
case OBJECT_LOCATION_MISSING:
162+
return 'missing';
163+
case OBJECT_LOCATION_ORPHANED:
164+
return 'orphaned';
162165
case OBJECT_LOCATION_LOCAL:
163166
return 'local';
164167
case OBJECT_LOCATION_DUPLICATED:
165168
return 'duplicated';
166169
case OBJECT_LOCATION_EXTERNAL:
167170
return 'remote';
168-
case OBJECT_LOCATION_ORPHANED:
169-
return 'orphaned';
170171
default:
171172
return $location;
172173
}

classes/tests/testcase.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ protected function create_error_file() {
180180
$file = $this->create_local_file();
181181
$path = $this->get_local_path_from_storedfile($file);
182182
unlink($path);
183-
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_ERROR);
183+
manager::update_object_by_hash($file->get_contenthash(), OBJECT_LOCATION_MISSING);
184184
return $file;
185185
}
186186

@@ -311,7 +311,7 @@ protected function create_remote_object($content = 'remote object content') {
311311
*/
312312
protected function create_error_object($content = 'error object content') {
313313
$file = $this->create_error_file($content);
314-
return $this->create_object_record($file, OBJECT_LOCATION_ERROR);
314+
return $this->create_object_record($file, OBJECT_LOCATION_MISSING);
315315
}
316316

317317
/**

db/install.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
1010
<FIELD NAME="contenthash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false"/>
1111
<FIELD NAME="timeduplicated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
12-
<FIELD NAME="location" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
12+
<FIELD NAME="location" TYPE="int" LENGTH="3" NOTNULL="true" SEQUENCE="false"/>
1313
<FIELD NAME="filesize" TYPE="int" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
1414
<FIELD NAME="tagsyncstatus" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
1515
<FIELD NAME="tagslastpushed" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>

db/upgrade.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,5 +220,34 @@ function xmldb_tool_objectfs_upgrade($oldversion) {
220220
upgrade_plugin_savepoint(true, 2024120600, 'tool', 'objectfs');
221221
}
222222

223+
if ($oldversion < 2026041006) {
224+
// Migrate OBJECT_LOCATION_* constants from sequential integers to bit flags.
225+
// Old values: ORPHANED=-2, ERROR(missing)=-1, LOCAL=0, DUPLICATED=1, EXTERNAL=2
226+
// New values: ERROR=0, ORPHANED=1, MISSING=2, LOCAL=3, EXTERNAL=6, DUPLICATED=7
227+
//
228+
// Processing in an order that avoids value collisions (highest old value first).
229+
230+
// Widen the location column to match install.xml (LENGTH 1 -> 3) before migrating values.
231+
$table = new xmldb_table('tool_objectfs_objects');
232+
$field = new xmldb_field('location', XMLDB_TYPE_INTEGER, '3', null, XMLDB_NOTNULL, null, null, 'timeduplicated');
233+
$dbman->change_field_precision($table, $field);
234+
235+
// tool_objectfs_objects.location column.
236+
$DB->execute('UPDATE {tool_objectfs_objects} SET location = 6 WHERE location = 2');
237+
$DB->execute('UPDATE {tool_objectfs_objects} SET location = 7 WHERE location = 1');
238+
$DB->execute('UPDATE {tool_objectfs_objects} SET location = 3 WHERE location = 0');
239+
$DB->execute('UPDATE {tool_objectfs_objects} SET location = 2 WHERE location = -1');
240+
$DB->execute('UPDATE {tool_objectfs_objects} SET location = 1 WHERE location = -2');
241+
242+
// tool_objectfs_report_data.datakey stores location values as strings for the 'location' report type.
243+
$DB->execute("UPDATE {tool_objectfs_report_data} SET datakey = '6' WHERE reporttype = 'location' AND datakey = '2'");
244+
$DB->execute("UPDATE {tool_objectfs_report_data} SET datakey = '7' WHERE reporttype = 'location' AND datakey = '1'");
245+
$DB->execute("UPDATE {tool_objectfs_report_data} SET datakey = '3' WHERE reporttype = 'location' AND datakey = '0'");
246+
$DB->execute("UPDATE {tool_objectfs_report_data} SET datakey = '2' WHERE reporttype = 'location' AND datakey = '-1'");
247+
$DB->execute("UPDATE {tool_objectfs_report_data} SET datakey = '1' WHERE reporttype = 'location' AND datakey = '-2'");
248+
249+
upgrade_plugin_savepoint(true, 2026041006, 'tool', 'objectfs');
250+
}
251+
223252
return true;
224253
}

0 commit comments

Comments
 (0)