22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5+ import 'package:clock/clock.dart' ;
56import 'package:logging/logging.dart' ;
7+ import 'package:pub_dev/account/models.dart' ;
8+ import 'package:pub_dev/package/api_export/api_exporter.dart' ;
9+ import 'package:pub_dev/package/backend.dart' ;
10+ import 'package:pub_dev/package/models.dart' ;
11+ import 'package:pub_dev/publisher/models.dart' ;
12+ import 'package:pub_dev/shared/datastore.dart' ;
613
714final _logger = Logger ('backfill_new_fields' );
815
@@ -12,5 +19,72 @@ final _logger = Logger('backfill_new_fields');
1219/// CHANGELOG.md must be updated with the new fields, and the next
1320/// release could remove the backfill from here.
1421Future <void > backfillNewFields () async {
15- _logger.info ('Nothing to backfill' );
22+ await migrateIsBlocked ();
23+ }
24+
25+ /// Migrates entities from the `isBlocked` fields to the new `isModerated` instead.
26+ Future <void > migrateIsBlocked () async {
27+ _logger.info ('Migrating isBlocked...' );
28+ final pkgQuery = dbService.query <Package >()..filter ('isBlocked =' , true );
29+ await for (final entity in pkgQuery.run ()) {
30+ await withRetryTransaction (dbService, (tx) async {
31+ final pkg = await tx.lookupValue <Package >(entity.key);
32+ // sanity check
33+ if (! pkg.isBlocked) {
34+ return ;
35+ }
36+ pkg
37+ ..isModerated = true
38+ ..moderatedAt = pkg.moderatedAt ?? pkg.blocked ?? clock.now ()
39+ ..isBlocked = false
40+ ..blocked = null
41+ ..blockedReason = null ;
42+ tx.insert (pkg);
43+ });
44+
45+ // sync exported API(s)
46+ await apiExporter? .synchronizePackage (entity.name! , forceDelete: true );
47+
48+ // retract or re-populate public archive files
49+ await packageBackend.tarballStorage.updatePublicArchiveBucket (
50+ package: entity.name! ,
51+ ageCheckThreshold: Duration .zero,
52+ deleteIfOlder: Duration .zero,
53+ );
54+ }
55+
56+ final publisherQuery = dbService.query <Publisher >()
57+ ..filter ('isBlocked =' , true );
58+ await for (final entity in publisherQuery.run ()) {
59+ await withRetryTransaction (dbService, (tx) async {
60+ final publisher = await tx.lookupValue <Publisher >(entity.key);
61+ // sanity check
62+ if (! publisher.isBlocked) {
63+ return ;
64+ }
65+ publisher
66+ ..isModerated = true
67+ ..moderatedAt = publisher.moderatedAt ?? clock.now ()
68+ ..isBlocked = false ;
69+ tx.insert (publisher);
70+ });
71+ }
72+
73+ final userQuery = dbService.query <User >()..filter ('isBlocked =' , true );
74+ await for (final entity in userQuery.run ()) {
75+ await withRetryTransaction (dbService, (tx) async {
76+ final user = await tx.lookupValue <User >(entity.key);
77+ // sanity check
78+ if (! user.isBlocked) {
79+ return ;
80+ }
81+ user
82+ ..isModerated = true
83+ ..moderatedAt = user.moderatedAt ?? clock.now ()
84+ ..isBlocked = false ;
85+ tx.insert (user);
86+ });
87+ }
88+
89+ _logger.info ('isBlocked migration completed.' );
1690}
0 commit comments