Subversion Repositories DevTools

Rev

Rev 392 | Rev 5710 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
392 dpurdie 1
########################################################################
2
# Copyright ( C ) 2004 ERG Limited, All rights reserved
3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats
8
#
9
# Description   : Get package information for a package name specified on the
10
#                 command line.
11
#
12
#                 Determine the package id
13
#                 Locate all packages that have the same package name
14
#
15
#                 Pump it into SVN
16
#
17
#                 Project Based Pumping
18
#
19
#......................................................................#
20
 
21
require 5.006_001;
22
use strict;
23
use warnings;
24
use JatsError;
25
use JatsRmApi;
26
use FileUtils;
27
use JatsSystem;
28
 
29
 
30
#use Data::Dumper;
31
use Cwd;
32
use DBI;
33
use Getopt::Long;
34
use Pod::Usage;                             # required for help support
35
my $RM_DB;
36
 
37
my $opt_repo_base = 'https://auperasvn01.aupera.erggroup.com/svn/';
38
my $opt_repo;
39
my $opt_package;
40
my $opt_resume;
41
my $opt_flat;
42
my $opt_test;
43
my $opt_reuse;
44
 
45
################################################################################
46
#   List of Projects Suffixes and Branch Names to be used within SVN
47
#
48
my %ProjectsBaseCreated;
49
my %Projects = (
50
    '.sea' => 'Seattle',
51
    '.coct' => 'CapeTown',
52
    '.sls'  => 'Stockholm',
53
    '.syd'  => 'Sydney',
54
    '.vtk'  => 'Vasttrafik',
55
    '.bei'  => 'Beijing',
56
    '.bkk'  => 'Bangkok',
57
    '.mas'  => 'Mass',
58
    '.ndl'  => 'NewDeli',
59
    '.nzs'  => 'NewZealandStageCoach',
60
    '.was'  => 'Washington',
61
    '.wdc'  => 'Washington',
62
);
63
 
64
################################################################################
65
#   Global data
66
#
67
my $VERSION = "1.0.0";
68
my $currentBranchName;
69
my $last_pv_id;
70
my $pkg_id;
71
my %versions;
72
my %suffixes;
73
my @processOrder;
74
 
75
#
76
#   Options
77
#
78
my $opt_help = 0;
79
my $opt_manual = 0;
80
my $opt_verbose = 0;
81
 
82
my $result = GetOptions (
83
                "help+"         => \$opt_help,          # Help
84
                "manual"        => \$opt_manual,        # Help
85
                "verbose+"      => \$opt_verbose,       # Versose
86
                "repository:s"  => \$opt_repo,          # Name of repository
87
                "resume:s"      => \$opt_resume,        # Resume at given version
88
                "flat!"         => \$opt_flat,          # Flat structure
89
                "test!"         => \$opt_test,          # Test operations
90
                "reuse!"        => \$opt_reuse,         # Reuse ClearCase views
91
                );
92
 
93
#
94
#   Process help and manual options
95
#
96
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
97
pod2usage(-verbose => 1)  if ($opt_help == 2 );
98
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));
99
 
100
#
101
#   Configure the error reporting process now that we have the user options
102
#
103
ErrorConfig( 'name'    =>'PLAY9d',
104
             'verbose' => $opt_verbose );
105
 
106
Error("No repository specified. ie -repo=DevTools, COTS") unless ( defined $opt_repo );
107
Error("Specify a package as 'name'" ) unless ( defined $ARGV[0] );
108
 
109
$opt_package = $ARGV[0];
110
$opt_repo = $opt_repo_base . $opt_repo;
111
 
112
Verbose( "Base Package: $opt_package");
113
Verbose( "Repo URL: $opt_repo");
114
 
115
#
116
#   Body of the process
117
#
118
GetPkgIdByName ( $opt_package );
119
GetData_by_pkg_id ( $pkg_id );
120
 
121
#
122
# Process the 'versions' hash and add back references
123
#
124
foreach my $entry ( keys(%versions) )
125
{
126
    foreach ( @{ $versions{$entry}{next}} )
127
    {
128
        $versions{$_}{last} = $entry;
129
    }
130
}
131
 
132
#
133
#   Find starts and ends
134
#       Entry with no previous
135
#       Entry with no next
136
#
137
my @startPoints;
138
my @endPoints;
139
foreach my $entry ( keys(%versions) )
140
{
141
    unless ( exists $versions{$entry}{last} )
142
    {
143
        push @startPoints, $entry;
144
    }
145
 
146
    unless ( @{$versions{$entry}{next}} > 0  )
147
    {
148
        push @endPoints, $entry;
149
    }
150
}
151
 
152
#
153
#   Create lists of entries starting at each start point
154
#
155
my $last_entry;
156
my @list;
157
my %startLists;
158
foreach my $entry ( @startPoints )
159
{
160
    $last_entry = 0;
161
    @list = ();
162
    processBranchLists($entry);
163
    @{$startLists{$entry}} = @list;
164
 
165
    sub processBranchLists
166
    {
167
        foreach my $entry ( @_ )
168
        {
169
            if ( $entry > $last_entry )
170
            {
171
                $last_entry = $entry;
172
            }
173
            push @list, $entry;
174
            processBranchLists (@{$versions{$entry}{next}});
175
        }
176
    }
177
 
178
}
179
 
180
#
181
#   Walk each starting point list and determine new Projects
182
#
183
#DebugDumpData("Lists", \%startLists );
184
my %seenSuffixes;
185
foreach ( @startPoints )
186
{
187
    foreach my $entry ( @{$startLists{$_}} )
188
    {
189
        my $s = $versions{$entry}{suffix};
190
        unless ( exists $seenSuffixes{$s} )
191
        {
192
            $seenSuffixes{$s} = 1;
193
            $versions{$entry}{branchPoint} = 1;
194
            $versions{$entry}{newSuffix} = 1;
195
        }
196
    }
197
}
198
 
199
#
200
#   For each leaf ( end point ), walk backwards and mark each node with the
201
#   distance frm the end. If we get to a node which already has been marked then
202
#   stop if our length is less.
203
#
204
my $distanceCount;
205
foreach my $entry ( @endPoints )
206
{
207
    $distanceCount = 0;
208
    calcDistance($entry);
209
}
210
 
211
#
212
#   Locate all instances where a package-version branches
213
#   Determine the version that should be on the non-branching path
214
#
215
#   Reorder the 'next' list so that the first item is the non-branching
216
#   path. This will be used in the data-insertion phase to simplify the
217
#   processing.
218
#
219
foreach my $entry ( sort keys(%versions) )
220
{
221
    my @next = @{$versions{$entry}{next}};
222
    my $count = @next;
223
    my @ordered;
224
    my $main;
225
 
226
    if ( $count > 0 )
227
    {
228
        my %nexts = map { $_ => 1 } @next;
229
        foreach my $e ( @next )
230
        {
231
            #
232
            #   Remove those that already have a branch
233
            #
234
            if ( $versions{$e}{branchPoint} || $versions{$e}{newSuffix}  )
235
            {
236
                push @ordered, $e;
237
                delete $nexts{$e};
238
            }
239
        }
240
 
241
        #
242
        #   Select longest arm as the non-branching path
243
        #
244
        my $count = -1;
245
        my $countEntry;
246
        foreach my $e ( sort keys %nexts )
247
        {
248
            if ( $versions{$e}{distance} > $count )
249
            {
250
                $count = $versions{$e}{distance};
251
                $countEntry = $e;
252
            }
253
        }
254
        if ($countEntry)
255
        {
256
            $main = $countEntry;
257
            delete $nexts{$countEntry};
258
        }
259
 
260
        #
261
        #   Mark remaining as non-main
262
        #
263
        foreach my $e ( keys %nexts )
264
        {
265
            push @ordered, $e;
266
            $versions{$e}{branchPoint} = 1;
267
        }
268
 
269
        #
270
        #   Re-order 'next' so that the main path is first
271
        #
272
        @ordered = sort @ordered;
273
        unshift @ordered, $main if ( $main );
274
        @{$versions{$entry}{next}} = @ordered;
275
    }
276
}
277
 
278
sub calcDistance
279
{
280
    my ($entry) = @_;
281
    while ( $entry )
282
    {
283
        if ( defined $versions{$entry}{distance} )
284
        {
285
            if ( $versions{$entry}{distance} > $distanceCount )
286
            {
287
                last;
288
            }
289
        }
290
        $versions{$entry}{distance} = $distanceCount++;
291
        $entry = $versions{$entry}{last};
292
    }
293
}
294
 
295
 
296
DebugDumpData ("Versions", \%versions );
297
DebugDumpData ("Starts", \@startPoints );
298
DebugDumpData ("Ends", \@endPoints );
299
DebugDumpData ("Suffixes", \%suffixes );
300
 
301
#
302
#   Process all packages
303
#       Going to create versions based on RM structure
304
#       May have several starting points: Process each
305
#
306
newPackage();
307
processBranch(@startPoints);
308
endPackage();
309
exit 0;
310
 
311
#-------------------------------------------------------------------------------
312
# Function        : processBranch
313
#
314
# Description     : Process one complete branch within the tree of versions
315
#                   May be called recursivly to walk the tree
316
#
317
# Inputs          : Array of package-version ID to process
318
#
319
# Returns         : Nothing
320
#
321
 
322
sub processBranch
323
{
324
    foreach my $entry ( @_ )
325
    {
326
        #
327
        #   Do we need to create a branch before we can process this package
328
        #
329
        if ( $versions{$entry}{newSuffix} || $versions{$entry}{branchPoint} )
330
        {
331
            newProject();
332
            createBranchPoint ($entry);
333
        }
334
 
335
        processPackage( $entry, $versions{$entry}{suffix} );
336
        processBranch (@{$versions{$entry}{next}});
337
    }
338
}
339
 
340
#-------------------------------------------------------------------------------
341
# Function        : processPackage
342
#
343
# Description     : Process a package version
344
#
345
# Inputs          : $entry              - Ref to entry being proccessed
346
#                   $suffix             - Project Suffix
347
#
348
# Returns         :
349
#
350
my $ProjectName;
351
sub processPackage
352
{
353
    my ($entry, $suffix) = @_;
354
    my $rv;
355
 
356
    print "--- Entry:",GetVname($entry)," Tag: ",$versions{$entry}{vcsTag},"\n";
357
    push @processOrder, $entry;
358
    return if ( $opt_test );
359
 
360
    #
361
    #   Allow resumption
362
    #   Assumes a great deal ...
363
    #   Designed to allow manual recovery
364
    #
365
    if ( $opt_resume )
366
    {
367
        return if ( $opt_resume ne GetVname($entry) );
368
        $opt_resume = undef;
369
    }
370
 
371
    #
372
    #   Determine version information
373
    #
374
    my $opt_label = $opt_package . '_' . GetVname($entry);
375
 
376
    my $tag = $versions{$entry}{vcsTag} || '';
377
    $tag =~ s~\\~/~g;
378
    $tag =~ m~^(.+?)::(.*?)(::(.+))?$~;
379
 
380
    my $opt_path = $2 || '';
381
    $opt_path =~ s~\\~/~g;
382
    $opt_path =~ s~//~/~g;
383
 
384
    my $cc_label = $4;
385
    if ( !defined $opt_path || ! defined $cc_label )
386
    {
387
        print "--- (E) Error: Bad Config Spec for:",GetVname($entry),"\n";
388
        return;
389
    }
390
print "--- Path: $opt_path, Label: $cc_label\n";
391
 
392
    my @author;
393
    my $author = $versions{$entry}{created_id};
394
    if ( $author )
395
    {
396
        push @author, '-author', $author;
397
    }
398
    my $created = $versions{$entry}{created};
399
    if ( $created )
400
    {
401
        $created =~ s~ ~T~;
402
        $created .= '00000Z';
403
        push @author, '-date', $created;
404
    }
405
 
406
    my $log = $versions{$entry}{comment};
407
    if ( $log )
408
    {
409
        push @author, '-log', $log;
410
    }
411
 
412
    #
413
    #   Projects are stored on a branch
414
    #
415
    if ( $suffix )
416
    {
417
        Error ("Unknown Project: $suffix") unless ( defined $Projects{$suffix} );
418
        $ProjectName = $Projects{$suffix};
419
    }
420
 
421
    $ProjectName = $currentBranchName;
422
 
423
    #
424
    #   Create CC view
425
    #   Import into Subversion View
426
    #
427
    SystemConfig ('ExitOnError' => 0);
428
    if ( $opt_reuse && -d ($cc_label) )
429
    {
430
        Message ("Reusing view: $cc_label");
431
        $rv = 0;
432
    }
433
    else
434
    {
435
        $rv = JatsToolPrint ( 'jats_ccrelease', '-extractfiles', '-root=.' , '-noprefix',
436
                    "-label=$cc_label" ,
437
                    "-path=$opt_path");
438
    }
439
 
440
    unless ( $rv )
441
    {
442
        SystemConfig ('ExitOnError' => 1);
443
        my $import_label = $opt_label;
444
        $import_label = $cc_label if ( $cc_label =~ m~WIP$~ );
445
 
446
        JatsToolPrint ( 'jats_svn', 'import', '-reuse' ,
447
                        "-package=$opt_repo/$opt_package",
448
                        "-dir=$cc_label/$opt_path",
449
                        "-label=$import_label",
450
                        "-branch=$ProjectName",
451
                        @author
452
                         );
453
        $versions{$entry}{TagCreated} = 1;
454
    }
455
 
456
    #
457
    #   Delete the created view
458
    #   Its just a directory, so delete it
459
    #
460
    RmDirTree ($cc_label) if -d ($cc_label && ! $opt_reuse);
461
}
462
 
463
#-------------------------------------------------------------------------------
464
# Function        : newProject
465
#
466
# Description     : Start a new project within a package
467
#
468
# Inputs          : 
469
#
470
# Returns         : 
471
#
472
sub newProject
473
{
474
    print "---- New Project\n";
475
    return if ( $opt_resume  );
476
 
477
    #
478
    #   New project
479
    #   Kill the running import directory
480
    #
481
    RmDirTree ('SvnImportDir');
482
}
483
 
484
#-------------------------------------------------------------------------------
485
# Function        : newPackage
486
#
487
# Description     : Start processing a new package
488
#
489
# Inputs          : 
490
#
491
# Returns         : 
492
#
493
sub newPackage
494
{
495
    print "---- New Package\n";
496
    return if ( $opt_resume  );
497
 
498
    #
499
    #   First entry being created
500
    #   Prime the work area
501
    #
502
    SystemConfig ('ExitOnError' => 1);
503
    JatsToolPrint ( 'jats_svn', 'delete-package', '-noerror',  "$opt_repo/$opt_package" );
504
    JatsToolPrint ( 'jats_svn', 'create', "$opt_repo/$opt_package" );
505
    RmDirTree ('SvnImportDir');
506
}
507
 
508
#-------------------------------------------------------------------------------
509
# Function        : createBranchPoint
510
#
511
# Description     : Create a branch point for the current work
512
#
513
# Inputs          : $entry                  Entry being processed
514
#
515
# Returns         : 
516
#
517
sub createBranchPoint
518
{
519
    my ($entry) = @_;
520
    my $forceNewProject;
521
    print "---- Create Branch Point\n";
522
 
523
    #
524
    #   Find previous good tag
525
    #   We are walking a tree so something should have been created, but
526
    #   the one we want may have had an error
527
    #
528
    #   Walk backwards looking for one that has been created
529
    #
530
    my $last = $versions{$entry}{last};
531
    while ( $last )
532
    {
533
        unless ( $versions{$last}{TagCreated} )
534
        {
535
            $last = $versions{$last}{last};
536
        }
537
        else
538
        {
539
            last;
540
        }
541
    }
542
 
543
    #
544
    #   If we have walked back to the base of the tree then we will create
545
    #   an empty view
546
    #
547
    unless ( $last )
548
    {
549
    print "---- Create Branch Point: New Root Branch\n";
550
        $forceNewProject = 1;
551
    }
552
 
553
    #
554
    #   Determine source name
555
    #   This MUST have been created before we can branch
556
    #
557
    my $src_label;
558
    $src_label = ($opt_package . '_' . GetVname($last)) if $last;
559
 
560
    #
561
    #   Create target name
562
    #
563
    my $tgt_label;
564
    if ( $forceNewProject || $versions{$entry}{newSuffix} || !defined $src_label )
565
    {
566
        #
567
        #   Create target name based on project
568
        #
569
        my $suffix = $versions{$entry}{suffix};
570
        if ( $suffix )
571
        {
572
            Error ("Unknown Project: $suffix") unless ( defined $Projects{$suffix} );
573
            if ( ! exists $ProjectsBaseCreated{$suffix} )
574
            {
575
                $tgt_label = $Projects{$suffix};
576
                $ProjectsBaseCreated{$suffix} = 1;
577
            }
578
            else
579
            {
580
                #
581
                #   Project Base Already taken
582
                #   Have disjoint starting points
583
                #
584
                $tgt_label = $Projects{$suffix} . '.' . $ProjectsBaseCreated{$suffix};
585
                $ProjectsBaseCreated{$suffix}++;
586
            }
587
        }
588
        else
589
        {
590
            #
591
            #   No suffix in use
592
            #
593
            #   Currently not handled
594
            #   May have to force the use of the trunk
595
            #
596
            Error ("INTERNAL ERROR: No suffix present");
597
        }
598
    }
599
    else
600
    {
601
        $tgt_label = $src_label . '_for_' . $opt_package . '_' . GetVname($entry);
602
    }
603
 
604
    #
605
    #   Save branch name for use when populating sandbox
606
    #
607
    $currentBranchName = $tgt_label;
608
print "----- src: $src_label\n";
609
print "------tgt: $tgt_label\n";
610
 
611
    #
612
    #   Perform the branch
613
    #
614
    if ( $src_label )
615
    {
616
        SystemConfig ('ExitOnError' => 1);
617
        JatsToolPrint ( 'jats_svnlabel',
618
                        '-packagebase', "$opt_repo/$opt_package",
619
                        'tags/' . $src_label,
620
                        '-branch',
621
                        '-clone', $tgt_label,
622
                      );
623
    }
624
}
625
 
626
 
627
#-------------------------------------------------------------------------------
628
# Function        : endPackage
629
#
630
# Description     : End of package processing
631
#                   Clean up and display problems
632
#
633
# Inputs          : 
634
#
635
# Returns         : 
636
#
637
sub endPackage
638
{
639
    RmDirTree ('SvnImportDir');
640
 
641
    #
642
    #   Display versions that did not get created
643
    #
644
    foreach my $entry ( @processOrder )
645
    {
646
        $versions{$entry}{Scanned} = 1;
647
        next if ( $versions{$entry}{TagCreated} );
648
        print "(E) Not Processed: ",GetVname($entry),"\n";
649
    }
650
 
651
    foreach my $entry ( keys(%versions) )
652
    {
653
        next if ( $versions{$entry}{Scanned} );
654
        print "(E) INTERNAL ERROR. Package Not Processed: ",GetVname($entry),"\n";
655
    }
656
 
657
    Message ("All Done");
658
}
659
 
660
sub JatsToolPrint
661
{
662
    Information ("Command: @_");
663
    JatsTool @_;
664
}
665
 
666
sub GetVname
667
{
668
    my ($entry) = @_;
669
    my $me = 'NONE';
670
    if ( $entry )
671
        {
672
        $me = $versions{$entry}{vname};
673
        unless ( $me )
674
        {
675
            $me = 'Unknown-' . $entry;
676
        }
677
    }
678
    return $me;
679
}
680
 
681
exit 0;
682
 
683
 
684
#-------------------------------------------------------------------------------
685
# Function        : GetPkgIdByName
686
#
687
# Description     :
688
#
689
# Inputs          : pkg_name
690
#
691
# Returns         :
692
#
693
sub GetPkgIdByName
694
{
695
    my ( $pkg_name ) = @_;
696
    my (@row);
697
    my $pv_id;
698
 
699
    #
700
    #   Establish a connection to Release Manager
701
    #
702
    connectRM(\$RM_DB) unless ( $RM_DB );
703
 
704
    #
705
    #   Extract data from Release Manager
706
    #
707
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pkg.PKG_ID" .
708
                   " FROM RELEASE_MANAGER.PACKAGES pkg" .
709
                   " WHERE pkg.PKG_NAME = \'$pkg_name\'";
710
 
711
    my $sth = $RM_DB->prepare($m_sqlstr);
712
    if ( defined($sth) )
713
    {
714
        if ( $sth->execute( ) )
715
        {
716
            if ( $sth->rows )
717
            {
718
                while ( @row = $sth->fetchrow_array )
719
                {
720
                    Verbose( "DATA: " . join(',', @row) );
721
                    $pkg_id = $row[1] || 0;
722
                    last;
723
                }
724
            }
725
            else
726
            {
727
                Error ("GetPkgIdByName:No Data for package: $pkg_name");
728
            }
729
            $sth->finish();
730
        }
731
    }
732
    else
733
    {
734
        Error("GetPkgIdByName:Prepare failure" );
735
    }
736
}
737
 
738
#-------------------------------------------------------------------------------
739
# Function        : GetData_by_pkg_id
740
#
741
# Description     :
742
#
743
# Inputs          : pv_id
744
#
745
# Returns         :
746
#
747
sub GetData_by_pkg_id
748
{
749
    my ( $pkg_id ) = @_;
750
    my (@row);
751
 
752
    #
753
    #   Establish a connection to Release Manager
754
    #
755
    connectRM(\$RM_DB) unless ( $RM_DB );
756
 
757
    #
758
    #   Extract data from Release Manager
759
    #
760
    my $m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION, pkg.PKG_ID, pv.PV_ID, pv.LAST_PV_ID, pv.MODIFIED_STAMP, release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID), amu.USER_NAME, pv.COMMENTS, pv.DLOCKED ".
761
                   " FROM RELEASE_MANAGER.PACKAGES pkg, RELEASE_MANAGER.PACKAGE_VERSIONS pv, ACCESS_MANAGER.USERS amu" .
762
                   " WHERE pv.PKG_ID = \'$pkg_id\' AND pkg.PKG_ID = pv.PKG_ID AND pv.CREATOR_ID = amu.USER_ID";
763
 
764
 
765
    my $sth = $RM_DB->prepare($m_sqlstr);
766
    if ( defined($sth) )
767
    {
768
        if ( $sth->execute( ) )
769
        {
770
            if ( $sth->rows )
771
            {
772
                while ( @row = $sth->fetchrow_array )
773
                {
774
                    Verbose( "DATA: " . join(',', @row) );
775
                    my $pkg_name = $row[0] || 'Unknown';
776
                    my $pkg_ver = $row[1] || 'Unknown';
777
                    my $pv_id = $row[3] || 'Unknown';
778
                    my $last_pv_id = $row[4] || 'Unknown';
779
                    my $created =  $row[5] || 'Unknown';
780
                    my $vcstag =  $row[6] || 'Unknown';
781
                    my $created_id =  $row[7] || 0;
782
                    my $comment =  $row[8] || '';
783
                    my $locked =  $row[9] || 'N';
784
 
785
                    #
786
                    #   Add data to the hash
787
                    #       Remove entries that address themselves
788
                    #
789
                    push (@{$versions{$last_pv_id}{next}}, $pv_id) unless ($pv_id == $last_pv_id) ;
790
                    $versions{$pv_id}{vname} = $pkg_ver;
791
                    $versions{$pv_id}{vcsTag} = $vcstag;
792
                    $versions{$pv_id}{created} = $created;
793
                    $versions{$pv_id}{created_id} = $created_id;
794
                    $versions{$pv_id}{comment} = $comment;
795
                    $versions{$pv_id}{locked} = $locked;
796
 
797
                    #
798
                    #   Convert version into full form for comparisions
799
                    #
800
                    my $version = $pkg_ver;
801
                    my $suffix;
802
                    if ( $version =~ m~(.*)\.cots$~ ) {
803
                        my $cots_base = $1;
804
                        $suffix = '.cots';
805
                        unless ( $version =~ m~(.*)(\.[0-9]4)\.cots~ )
806
                        {
807
                            $version = $cots_base . '.0000.cots';
808
                        }
809
                    }
810
                    elsif ( $version =~ m~(\d+)\.(\d+)\.(\d+)(\.(.*))?~ )
811
                    {
812
                        my $patch = $3;
813
                        my $build = '000';
814
                        if ( length( $patch) >= 4 )
815
                        {
816
                            $build = substr( $patch, -3 ,3);
817
                            $patch = substr( $patch,  0 ,length($patch)-3);
818
                        }
819
 
820
                        $version = sprintf("%3.3d.%3.3d.%3.3d.%3.3d%s", $1,$2,$patch,$build,$4 || '.0000');
821
                        $suffix = $4 || '';
822
                    }
823
                    else
824
                    {
825
                        $pkg_ver =~ m~(\.\w+)$~;
826
                        $suffix = $1 || '';
827
                    }
828
                    $versions{$pv_id}{version} = $version;
829
 
830
                    #
831
                    #   Process suffix
832
                    #
833
                    $suffix = 'Unknown' unless ( $suffix );
834
                    $suffix = lc ($suffix);
835
                    $versions{$pv_id}{suffix} = $suffix;
836
                    push @{$suffixes{$suffix}}, $pv_id;
837
 
838
 
839
                    print "$pkg_name, $pkg_ver, $pv_id, $last_pv_id, $created, $created_id, $suffix\n";
840
                }
841
            }
842
            else
843
            {
844
                Error ("GetData_by_pkg_id: No Data: $m_sqlstr");
845
            }
846
            $sth->finish();
847
        }
848
        else
849
        {
850
                Error ("GetData_by_pkg_id: Execute: $m_sqlstr");
851
        }
852
    }
853
    else
854
    {
855
        Error("GetData_by_pkg_id:Prepare failure" );
856
    }
857
}
858