forked from plainblack/webgui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rebuildLineage.pl
executable file
·179 lines (141 loc) · 5.54 KB
/
rebuildLineage.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env perl
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
our ($webguiRoot);
BEGIN {
$webguiRoot = "..";
unshift (@INC, $webguiRoot."/lib");
}
$| = 1;
use Getopt::Long;
use Pod::Usage;
use strict;
use WebGUI::Session;
use WebGUI::Utility;
my $configFile;
my $help;
my $quiet;
GetOptions(
'configFile=s'=>\$configFile,
'help'=>\$help,
'quiet'=>\$quiet,
);
pod2usage( verbose => 2 ) if $help;
pod2usage() unless (defined($configFile) && $configFile ne '');
print "Starting..." unless ($quiet);
my $session = WebGUI::Session->open($webguiRoot,$configFile);
print "OK\n" unless ($quiet);
print "Looking for descendant replationships...\n" unless ($quiet);
my @found = (); #descendants found
getDescendants("PBasset000000000000001");
print "Got the relationships.\n" unless ($quiet);
print "\nLooking for orphans...\n" unless ($quiet);
my $orphansFound = 0;
my $rs = $session->db->read("select assetId from asset order by lineage");
while (my ($id) = $rs->array) {
unless (isIn($id, @found)) {
print "\tFound an orphan with an assetId of $id. Moving it to the import node.\n";
$session->db->write("update asset set parentId='PBasset000000000000002' where assetId=?",[$id]);
getDescendants($id);
$orphansFound++;
}
}
if ($orphansFound) {
print "Found and fixed $orphansFound orphan(s).\n" unless ($quiet);
} else {
print "No orphans found.\n" unless ($quiet);
}
print "\nDisabling constraints on lineage...\n" unless ($quiet);
$session->db->write("drop index `lineage` on `asset`");
print "Rebuilding lineage...\n" unless ($quiet);
my ($oldRootLineage) = $session->db->quickArray("select lineage from asset where assetId='PBasset000000000000001'");
printChange("Asset ID","Old Lineage","New Lineage");
printChange('PBasset000000000000001',$oldRootLineage,'000001');
$session->db->write("update asset set lineage='000001' where assetId='PBasset000000000000001'");
recurseAndFixTree("PBasset000000000000001","000001");
print "\nRe-enabling constraints on lineage...\n" unless ($quiet);
$session->db->write("create unique index `lineage` on `asset` (`lineage`)");
print "\nRepairing search index...\n" unless ($quiet);
$session->db->write("update assetIndex inner join asset on asset.assetId=assetIndex.assetId set assetIndex.lineage=asset.lineage");
print "Cleaning up..." unless ($quiet);
$session->var->end;
$session->close;
print "OK\n" unless ($quiet);
print "\nDon't forget to clear your cache.\n" unless ($quiet);
sub getDescendants {
my $parentId = shift;
my $depth = shift || 0;
if (isIn($parentId, @found)) {
print "\nFound circular relationships involving $parentId. This requires manual intervention.\n" unless ($quiet);
exit;
}
if (++$depth > 42) {
print "\nFound asset greater than 42 levels deep: $parentId. This requires manual intervention.\n" unless ($quiet);
exit;
}
push(@found, $parentId);
my $getChildren = $session->db->prepare("select assetId, lineage from asset where parentId=? order by lineage");
$getChildren->execute([$parentId]);
while (my ($assetId) = $getChildren->array) {
getDescendants($assetId, $depth);
}
}
sub recurseAndFixTree {
my $parentId = shift;
my $parentLineage = shift;
my $rank = 0;
my $getChildren = $session->db->prepare("select assetId, lineage from asset where parentId=? order by lineage");
$getChildren->execute([$parentId]);
while (my ($assetId, $oldLineage) = $getChildren->array) {
$rank++;
my $newLineage = $parentLineage.sprintf("%06d",$rank);
printChange($assetId,$oldLineage,$newLineage);
my $setLineage = $session->db->prepare("update asset set lineage=? where assetId=?");
$setLineage->execute([$newLineage,$assetId]);
recurseAndFixTree($assetId,$newLineage);
}
}
sub printChange {
my $assetId = shift;
my $oldLineage = shift;
my $newLineage = shift;
print sprintf("%-25s",$assetId).sprintf("%-51s",$oldLineage).$newLineage."\n" unless ($quiet);
}
__END__
=head1 NAME
rebuildLineage - Rebuild WebGUI Lineage Tree.
=head1 SYNOPSIS
rebuildLineage --configFile config.conf
rebuildLineage --help
=head1 DESCRIPTION
WebGUI's Lineage Tree is an index that helps WebGUI run faster, if
built propely. This utility will rebuild your WebGUI Lineage Tree,
detect and fix orphaned data, and circular relationships (loops)
in the tree.
B<WARNING>: Use this tool only if you know what you're doing. It should
only be used if somehow your lineage tree has become corrupt (very rare)
or if you have done some massive reorganization of your asset tree and
you want to fill in the gaps between the ranks of your assets. A side
effect of using this utility can be that your assets may no longer be
in the same rank as they once were, which means that they may appear
out of order in your navigation.
=over
=item B<--configFile config.conf>
The WebGUI config file to use. Only the file name needs to be specified,
since it will be looked up inside WebGUI's configuration directory.
This parameter is required.
=item B<--quiet>
Disable all output unless there's an error.
=item B<--help>
Shows this documentation, then exits.
=back
=head1 AUTHOR
Copyright 2001-2009 Plain Black Corporation.
=cut