2 ################################################################################
5 # Description: Perl module PQA conversion routines
6 # Author: Andrew@DeFaria.com
7 # Created: Thu Oct 6 09:51:38 PDT 2005
11 # (c) Copyright 2005, Andrew@DeFaria.com, all rights reserved
13 ################################################################################
25 @old_Prod_defect_fields
27 @new_Cont_defect_fields
48 sub AddToFieldChoiceList;
52 sub DeleteDynamicLists;
55 sub GetAllDefectRecords;
59 sub TransferAttachemnts;
63 our ($me, $verbose, $debug);
67 # Check environment variables
68 $verbose = $ENV {VERBOSE} ? "yes" : "no";
69 $debug = $ENV {DEBUG} ? "yes" : "no";
75 ## Exported variables ##
78 our @old_Prod_defect_fields = (
79 "ActionNotes", # SHORT_STRING
80 "AdvancedFeature", # SHORT_STRING, CONSTANT_LIST
81 "Assigned_Date", # DATE_TIME
82 "AttachmentBRCM", # ATTACHMENT_LIST
83 "Audit_Log", # MULTILINE_STRING
84 "Category", # SHORT_STRING, CONSTANT_LIST
85 "Close_Date", # DATE_TIME
86 "CommitmentLevel", # SHORT_STRING, CONSTANT_LIST
87 "CommittedDate", # DATE_TIME
88 "CommittedToProject", # SHORT_STRING, CONSTANT_LIST
89 "CustomerID", # SHORT_STRING
90 "DataPendingNote", # MULTILINE_STRING
91 "DeferredToChip", # SHORT_STRING
92 "DeferredToProject", # SHORT_STRING, CONSTANT_LIST
93 "Description", # MULTILINE_STRING
94 "DoesNotVerifyNote", # MULTILINE_STRING
95 "Entry_Type", # SHORT_STRING, CONSTANT_LIST
96 "Est_Time_To_Fix", # SHORT_STRING
97 "Fixed_In_HW_Version", # SHORT_STRING
98 "Fixed_In_Project", # SHORT_STRING, CONSTANT_LIST
99 "Fixed_In_SW_Version", # SHORT_STRING
100 "GatingItem", # SHORT_STRING, CONSTANT_LIST
101 "HUT", # SHORT_STRING, DYNAMIC_LIST
102 "HUT_Revision", # SHORT_STRING, CONSTANT_LIST
103 "HUT_Version", # SHORT_STRING, CONSTANT_LIST
105 "Issue_Classification", # SHORT_STRING, CONSTANT_LIST
106 "Keywords", # MULTILINE_STRING, CONSTANT_LIST
107 "NoteBRCMOnly", # MULTILINE_STRING
108 "NoteBugReview", # MULTILINE_STRING
109 "Note_Entry", # MULTILINE_STRING
110 "Notes_Log", # MULTILINE_STRING
111 "OEMSubmitterName", # SHORT_STRING
112 "OS", # CONSTANT_LIST
113 "Open_Close_Status", # SHORT_STRING, CONSTANT_LIST
115 "PendingHWSWReleases", # INT
116 "Priority", # SHORT_STRING, CONSTANT_LIST
117 "Project", # REFERENCE
118 "Project_Name", # SHORT_STRING, CONSTANT_LIST
119 "RelatedID", # MULTILINE_STRING
120 "ReportedBy", # SHORT_STRING, CONSTANT_LIST
121 "Resolution", # SHORT_STRING
122 "ResolveNote", # MULTILINE_STRING
123 "ResolvedBy", # REFERENCE
124 "Resolved_Date", # DATE_TIME
125 "SQATestCase", # SHORT_STRING, CONSTANT_LIST
126 "Service_Pack", # SHORT_STRING
127 "Severity", # SHORT_STRING, CONSTANT_LIST
128 "Software", # SHORT_STRING, CONSTANT_LIST
129 "Software_Version", # SHORT_STRING
130 "Submit_Date", # DATE_TIME
131 "Submitter", # REFERENCE
132 "Symptoms", # MULTILINE_STRING, CONSTANT_LIST
133 "TCProcedure", # MULTILINE_STRING
134 "TestBlocking", # SHORT_STRING, CONSTANT_LIST
136 "TestcaseComment", # MULTILINE_STRING
137 "TimeFromSubmitToVerify", # SHORT_STRING
138 "TimeSubmitToResolve", # SHORT_STRING
139 "TimeSubmitToResolve", # SHORT_STRING
140 "TimeToVerify", # SHORT_STRING
141 "Title", # SHORT_STRING
142 "VerifiedBy", # REFERENCE
143 "VerifyNote", # MULTILINE_STRING
144 "Verified_Date", # DATE_TIME
145 "Verified_In_HW_Version", # SHORT_STRING
146 "Verified_In_SW_Version", # SHORT_STRING
147 "Visibility", # SHORT_STRING, CONSTANT_LIST
148 "VisibleTo3com", # INT
149 "VisibleToAltima", # INT
150 "VisibleToCompaq", # INT
151 "VisibleToDell", # INT
152 "customer", # REFERENCE
153 "customer_severity", # SHORT_STRING, CONSTANT_LIST
154 "old_id", # SHORT_STRING, CONSTANT_LIST
157 # This decribes the fields in the old TO defect record
158 our @old_TO_defect_fields = (
159 "ActionNotes", # SHORT_STRING
160 "AdvancedFeature", # SHORT_STRING, DYNAMIC_LIST
161 "Assigned_Date", # DATE_TIME
162 "AttachmentsBRCM", # ATTACHMENT_LIST
163 "Audit_Log", # MULTILINE_STRING
164 "Category", # SHORT_STRING, CONSTANT_LIST
165 "Close_Date", # DATE_TIME
166 "CommitmentLevel", # SHORT_STRING, CONSTANT_LIST
167 "CommittedDate", # DATE_TIME
168 "CommittedToProject", # SHORT_STRING, DYNAMIC_LIST
169 "CustomerID", # SHORT_STRING
170 "DataPendingNote", # MULTILINE_STRING
171 "DeferredToChip", # SHORT_STRING
172 "DeferredToProject", # SHORT_STRING, DYNAMIC_LIST
173 "Description", # MULTILINE_STRING
174 "DoesNotVerifyNote", # MULTILINE_STRING
175 "Entry_Type", # SHORT_STRING, CONSTANT_LIST
176 "Est_Time_To_Fix", # SHORT_STRING
177 "Fixed_In_HW_Version", # SHORT_STRING
178 "Fixed_In_Project", # SHORT_STRING, DYNAMIC_LIST
179 "Fixed_In_SW_Version", # SHORT_STRING
180 "Found_In_Project", # SHORT_STRING, DYNAMIC_LIST
181 "GatingItem", # SHORT_STRING, CONSTANT_LIST
182 "HUT", # SHORT_STRING, DYNAMIC_LIST
183 "HUT_Revision", # SHORT_STRING, DYNAMIC_LIST
184 "HUT_Version", # SHORT_STRING, DYNAMIC_LIST
185 "Headline", # SHORT_STRING
187 "Issue_Classification", # SHORT_STRING, CONSTANT_LIST
188 "Keywords", # MULTILINE_STRING, CONSTANT_LIST
189 "NoteBRCMOnly", # MULTILINE_STRING
190 "NoteBugReview", # MULTILINE_STRING
191 "Note_Entry", # MULTILINE_STRING
192 "Notes_Log", # MULTILINE_STRING
193 "OEMSubmitterName", # SHORT_STRING
194 "OS", # SHORT_STRING, DYNAMIC_LIST
195 "Open_Close_Status", # SHORT_STRING, CONSTANT_LIST
197 "PendingHWSWReleases", # INT
198 "Priority", # SHORT_STRING, CONSTANT_LIST
199 "Project", # REFERENCE
200 "ReportedBy", # REFERENCE
201 "Resolution", # SHORT_STRING, CONSTANT_LIST
202 "ResolveNote", # MULTILINE_STRING
203 "ResolvedBy", # REFERENCE
204 "Resolved_Date", # DATE_TIME
205 "SQATestCase", # SHORT_STRING, CONSTANT_LIST
206 "Service_Pack", # SHORT_STRING, DYNAMIC_LIST
207 "Severity", # SHORT_STRING, CONSTANT_LIST
208 "Software", # SHORT_STRING, DYNAMIC_LIST
209 "Software_Version", # SHORT_STRING
210 "Submit_Date", # DATE_TIME
211 "Submitter", # REFERENCE
212 "Symptoms", # MULTILINE_STRING, CONSTANT_LIST
213 "TCProcedure", # MULTILINE_STRING
214 "TestBlocking", # SHORT_STRING, CONSTANT_LIST
216 "TestcaseComment", # MULTILINE_STRING
217 "TimeFromSubmitToVerify", # SHORT_STRING
218 "TimeSubmitToResolve", # SHORT_STRING
219 "TimeToVerify", # SHORT_STRING
220 "Title_2", # SHORT_STRING
221 "VerifiedBy", # REFERENCE
222 "Verified_Date", # DATE_TIME
223 "Verified_In_HW_Version", # SHORT_STRING
224 "Verified_In_SW_Version", # SHORT_STRING
225 "VerifyNote", # MULTILINE_STRING
226 "Visibility", # SHORT_STRING, DYNAMIC_LIST
227 "customer", # REFERENCE_LIST
228 "customer_severity", # SHORT_STRING, CONSTANT_LIST
229 "old_id", # SHORT_STRING
232 # This describes the fields in the new Cont Defect record
233 our @new_Cont_defect_fields = (
234 "ActionNotes", # SHORT_STRING
235 # Prod: <not defined>, TO: <not defined> -> Cont: Active_Deferred_Status
236 "Active_Deferred_Status", # SHORT_STRING, CONSTANT_LIST
237 "Advanced_Feature", # SHORT_STRING, DYNAMIC_LIST
238 "Assigned_Date", # DATE_TIME
239 "AttachmentsBRCM", # ATTACHMENT_LIST
240 "Audit_Log", # MULTILINE_STRING
241 "Board_Revision", # SHORT_STRING, DYNAMIC_LIST
242 # Prod: NoteBRCMOnly, TO: NoteBRCMOnly -> Cont: Broadcom_Only_Note
243 "Broadcom_Only_Note", # MULTILINE_STRING
244 # Prod: NoteBugReview, TO: NoteBugReview -> Cont: Bug_Review_Note
245 "Bug_Review_Note", # MULTILINE_STRING
246 "Category", # SHORT_STRING, CONSTANT_LIST
247 "Close_Date", # DATE_TIME
248 "CommitmentLevel", # SHORT_STRING, CONSTANT_LIST
249 "CommittedDate", # DATE_TIME
250 "CommittedToProject", # SHORT_STRING, DYNAMIC_LIST
251 "CustomerID", # SHORT_STRING
252 "DataPendingNote", # MULTILINE_STRING
253 "DeferredToChip", # SHORT_STRING
254 "DeferredToProject", # SHORT_STRING, DYNAMIC_LIST
255 "Description", # MULTILINE_STRING
256 "DoesNotVerifyNote", # MULTILINE_STRING
257 "Entry_Type", # SHORT_STRING, CONSTANT_LIST
258 "Est_Time_To_Fix", # SHORT_STRING
259 "Fixed_In_HW_Version", # SHORT_STRING
260 "Fixed_In_Project", # SHORT_STRING, DYNAMIC_LIST
261 "Fixed_In_SW_Version", # SHORT_STRING
262 # Prod: Project (REFERENCE), TO: Project (REFERENCE) -> Cont: Found_In_Project (REFERENCE)
263 "Found_In_Project", # REFERENCE
264 # Prod: <not defined>, TO: <not defined> -> Cont: Found_On_Gold
265 "Found_On_Gold", # SHORT_STRING, CONSTANT_LIST
266 "Gating_Item_HW", # SHORT_STRING, CONSTANT_LIST
267 # Prod: GatingItem, TO: GatingItem -> Cont: Gating_Item_SW, Gating_Item_HW
268 "Gating_Item_SW", # SHORT_STRING, CONSTANT_LIST
269 "HUT", # SHORT_STRING, DYNAMIC_LIST
270 "HUT_Revision", # SHORT_STRING, DYNAMIC_LIST
271 # Prod: Title, TO: Headline -> Cont: Headline
272 "Headline", # SHORT_STRING
273 "Issue_Classification", # SHORT_STRING, CONSTANT_LIST
274 "Keywords", # MULTILINE_STRING, CONSTANT_LIST
275 # Prod: <not defined>, TO: <not defined> -> Cont: Newly_Introduce
276 "Newly_Introduce", # SHORT_STRING, CONSTANT_LIST
277 "Note_Entry", # MULTILINE_STRING
278 "Notes_Log", # MULTILINE_STRING
279 "OEMSubmitterName", # SHORT_STRING
280 "OS", # SHORT_STRING, DYNAMIC_LIST
281 # Prod: <not defined>, TO: <not defined> -> Cont: Other_HUT
282 "Other_HUT", # MULTILINE_STRING
284 # Prod: <not defined>, TO: <not defined> -> Cont: PQATestCase
285 "PQATestCase", # SHORT_STRING, CONSTANT_LIST
286 "Priority", # SHORT_STRING, CONSTANT_LIST
287 # Prod: ReportedBy, TO: ReportedBy -> Cont: Reported_By
288 "Reported_By", # REFERENCE
289 "Resolution", # SHORT_STRING, CONSTANT_LIST
290 "ResolveNote", # MULTILINE_STRING
291 "ResolvedBy", # REFERENCE
292 "Resolved_Date", # DATE_TIME
293 # Prod: <not defined>, TO: <not defined> -> Cont: Root_Caused
294 "Root_Caused", # SHORT_STRING, CONSTANT_LIST
295 # Prod: <not defined>, TO: <not defined> -> Cont: Root_Caused_Note
296 "Root_Caused_Note", # MULTILINE_STRING
297 "Service_Pack", # SHORT_STRING, DYNAMIC_LIST
298 "Severity", # SHORT_STRING, CONSTANT_LIST
299 "Software", # SHORT_STRING, DYNAMIC_LIST
300 "Software_Version", # SHORT_STRING
301 "Submit_Date", # DATE_TIME
302 "Submitter", # REFERENCE
303 "Symptoms", # MULTILINE_STRING, CONSTANT_LIST
304 "TCProcedure", # MULTILINE_STRING
306 "TestcaseComment", # MULTILINE_STRING
307 "TimeFromSubmitToVerify", # SHORT_STRING
308 "TimeSubmitToResolve", # SHORT_STRING
309 "TimeToVerify", # SHORT_STRING
310 # Prod: Title_2, TO: Title_2 -> Cont: Title
311 "Title", # SHORT_STRING
312 "VerifiedBy", # REFERENCE
313 "Verified_Date", # DATE_TIME
314 "Verified_In_HW_Version", # SHORT_STRING
315 "Verified_In_SW_Version", # SHORT_STRING
316 "VerifyNote", # MULTILINE_STRING
317 # Prod: <not defined>, TO: <not defined> -> Cont: <added>
318 "Visibility", # SHORT_STRING, DYNAMIC_LIST
319 # Prod: <not defined>, TO: <not defined> -> Cont: WorkAroundNote
320 "WorkAroundNote", # MULTILINE_STRING
321 "customer", # REFERENCE_LIST
322 "customer_severity", # SHORT_STRING, CONSTANT_LIST
323 "old_id", # SHORT_STRING
324 # Prod: <not defined>, TO: Found_In_Project -> Cont: <Deleted>
325 # "Found_In_Project", # SHORT_STRING, DYNAMIC_LIST
327 # "HUT_Version", # SHORT_STRING, DYNAMIC_LIST
328 # "Open_Close_Status", # SHORT_STRING, CONSTANT_LIST
329 # "PendingHWSWReleases", # INT
330 # "SQATestCase", # SHORT_STRING, CONSTANT_LIST
331 # "TestBlocking", # SHORT_STRING, CONSTANT_LIST
334 # Customer and Project records appear in both instances of the old
335 # databases as well as the new Cont database and have not changed.
336 our @customer_fields = (
337 "Name", # SHORT_STRING
338 "Phone", # SHORT_STRING
339 "Fax", # SHORT_STRING
340 "Email", # SHORT_STRING
341 "CallTrackingID", # SHORT_STRING
342 "Description", # MULTILINE_STRING
343 "Company", # SHORT_STRING
344 "Attachment", # ATTACHMENT_LIST
347 our @project_fields = (
348 "Name", # SHORT_STRING
349 "Description", # MULTILINE_STRING
352 # Collect bad characters
355 ## Internal variables ##
356 my $login = "<username>";
357 my $password = "<password>";
363 my $half = $nbr_chars / 2;
365 # Derived from http://hotwired.lycos.com/webmonkey/reference/special_characters/
384 145 => "'", # Signal "smart quote" left
385 146 => "'", # Signal "smart quote" right
386 147 => "\"", # Double "smart quote" left
387 148 => "\"", # Double "smart quote" right
389 150 => "–", # En dash
390 151 => "—", # Em dash
399 160 => " ", # Nonbreaking space
400 161 => "¡", # Inverted exclamation (¡)
401 162 => "¢", # Cent sign (¢)
402 163 => "£", # Pound sterling (£)
403 164 => "¤", # General currency sign (¤)
404 165 => "¥", # Yen sign (¥)
405 166 => "&brkbar;", # Broken vertical bar (¦)
406 167 => "§", # Section sign (§)
407 168 => "¨", # Umlaut (¨)
408 169 => "©", # Copyright (©)
409 170 => "ª", # Feminine ordinal (ª)
410 171 => "«", # Left angle quote («)
411 172 => "¬", # Not sign (¬)
412 173 => "­", # Soft hyphen
413 174 => "®", # Registered trademark (®)
414 175 => "¯", # Macron accent (¯)
415 176 => "°", # Degree sign (°)
416 177 => "±", # Plus or minus (±)
417 178 => "²", # Superscript two (²)
418 179 => "³", # Superscript three (³)
419 180 => "´", # Acute accent (´)
420 181 => "µ", # Micro sign (µ)
421 182 => "¶", # Paragraph sign (¶)
422 183 => "·", # Middle dot (·)
423 184 => "¸", # Cedilla (¸)
424 185 => "¹", # Superscript one (¹)
425 186 => "º", # Masculine ordinal (º)
426 187 => "»", # Right angle quote (»)
427 188 => "¼", # One-forth (¼)
428 189 => "½", # One-half (½)
429 190 => "&frac24;", # Three-fourths (¾)
430 191 => "¿", # Inverted question mark (¿)
431 192 => "À", # Uppercase A, grave accent (À)
432 193 => "Á", # Uppercase A, acute accent (Á)
433 194 => "Â", # Uppercase A, circumflex accent (Â)
434 195 => "Ã", # Uppercase A, tilde (Ã)
435 196 => "Ä", # Uppercase A, umlaut (Ä)
436 197 => "Å", # Uppercase A, ring (Å)
437 198 => "Æ", # Uppercase AE (Æ)
438 199 => "Ç", # Uppercase C, cedilla (Ç)
439 200 => "È", # Uppercase E, grave accent (È)
440 201 => "É", # Uppercase E, acute accent (É)
441 202 => "Ê", # Uppercase E, circumflex accent (Ê)
442 203 => "Ë", # Uppercase E, umlaut (Ë)
443 204 => "Ì", # Uppercase I, grave accent (Ì)
444 205 => "Í", # Uppercase I, acute accent (Í)
445 206 => "Î", # Uppercase I, circumflex accent (Î)
446 207 => "Ï", # Uppercase I, umlaut (Ï)
447 208 => "Ð", # Uppercase Eth, Icelandic (Ð)
448 209 => "Ñ", # Uppercase N, tilde (Ñ)
449 210 => "Ò", # Uppercase O, grave accent (Ò)
450 211 => "Ó", # Uppercase O, acute accent (Ó)
451 212 => "Ô", # Uppercase O, circumflex accent (Ô)
452 213 => "Õ", # Uppercase O, tilde (Õ)
453 214 => "Ö", # Uppercase O, umlaut (Ö)
454 215 => "×", # Muliplication sign (×)
455 216 => "Ø", # Uppercase O, slash (Ø)
456 217 => "Ù", # Uppercase U, grave accent (Ù)
457 218 => "Ú", # Uppercase U, acute accent (Ú)
458 219 => "Û", # Uppercase U, circumflex accent (Û)
459 220 => "Ü", # Uppercase U, umlaut (Ü)
460 221 => "Ý", # Uppercase Y, acute accent (Ý)
461 222 => "Þ", # Uppercase THORN, Icelandic (Þ)
462 223 => "ß", # Lowercase sharps, German (ß)
463 224 => "à", # Lowercase a, grave accent (à)
464 225 => "á", # Lowercase a, acute accent (á)
465 226 => "â", # Lowercase a, circumflex acirc (â)
466 227 => "ã", # Lowercase a, tilde (ã)
467 228 => "ä", # Lowercase a, umlaut (ä)
468 229 => "å", # Lowercase a, ring (å)
469 230 => "æ", # Lowercase ae (æ)
470 231 => "ç", # Lowercase c, cedilla (ç)
471 232 => "è", # Lowercase e, grave accent (è)
472 233 => "é", # Lowercase e, acute accent (é)
473 234 => "ê", # Lowercase e, circumflex accent (ê)
474 235 => "ë", # Lowercase e, umlaut (ë)
475 236 => "ì", # Lowercase i, grave accent (ì)
476 237 => "í", # Lowercase i, acute accent (í)
477 238 => "î", # Lowercase i, circumflex accent (î)
478 239 => "ï", # Lowercase i, umlaut (ï)
479 240 => "ð", # Lowercase eth, Icelandic (ð)
480 241 => "ñ", # Lowercase n, tilde (ñ)
481 242 => "ò", # Lowercase o, grave accent (ò)
482 243 => "ó", # Lowercase o, acute accent (ó)
483 244 => "ô", # Lowercase o, circumflex accent (ô)
484 245 => "õ", # Lowercase o, tilde (õ)
485 246 => "ö", # Lowercase o, umlaut (ö)
486 247 => "÷", # Division sign (÷)
487 248 => "ø", # Lowercase o, slash (ø)
488 249 => "ù", # Lowercase u, grave accent (ù)
489 250 => "ú", # Lowercase u, acute accent (ú)
490 251 => "û", # Lowercase u, circumflex accent (û)
491 252 => "ü", # Lowercase u, umlaut (ü)
492 253 => "ý", # Lowercase y, acute accent (ý)
493 254 => "þ", # Lowercase thorn, Icelandic (þ)
494 255 => "ÿ", # Lowercase y, umlaut (ÿ)
497 ## Exported functions ##
498 # Add a value to a field's dynamic list
499 sub AddToFieldChoiceList {
502 my $dynamic_list = shift;
506 return if $value eq "";
508 # It seems that adding the entry to the dynamic list is not enough.
509 # I believe that Clearquest caches entries on a dynamic list so we
510 # need to tell Clearquest about this new entry.
512 my @values = @{$entity->GetFieldChoiceList ($name)};
514 # Ack! Seems now we have values like Service_Pack = "1.A" and
515 # Service_Pack = "1.a", which translate to the same value as far
516 # as a dynamic list is concerned, so we'll do the comparison
517 # ignoring case... Additionally there can be regex meta characters
518 # in the value so we'll need to protect from that.
520 if ("\L$value\E" eq "\L$_\E") {
527 push @values, $value;
529 $entity->SetFieldChoiceList ($name, \@values);
532 # Get the current values, if any
533 @values = @{$session->GetListMembers ($dynamic_list)};
535 # Search to see if the item is already on the list
537 return if ("\L$value\E" eq "\L$_\E");
540 $session->AddListMember ($dynamic_list, $value);
542 push @values, $value;
544 $session->SetListMembers ($dynamic_list, \@values);
547 # TO: defect: Found_In_Project is currently a dynamic list but is
548 # going to Cont: defect: Found_In_Project which is a reference to
549 # Cont: Project. So we need to dynamically add those.
555 if (ProjectExists $to, $project) {
559 my $entity = $to->BuildEntity ("Project");
561 $entity->SetFieldValue ("name", $project);
563 # Call the Validate method
564 my $errmsg = $entity->Validate;
566 $log->err ("Unable to validate Project record: $project:\n$errmsg", 1) if $errmsg ne "";
568 # Post record to database
569 $entity->Commit if $errmsg eq "";
575 my $record_name = shift;
577 my $field_name = shift;
580 return $str if length $str eq 0; # Ignore empty strings
582 if ($str =~ /[^\t\n\r -\177]/) {
583 for (my $x = 0; $x < length $str; $x++) {
584 my $y = substr $str, $x, 1;
585 if ($y =~ /[^\t\n\r -\177]/) {
587 display "At char #$x found \"$y\" ($o)";
588 my $s = substr $str, $x - 20, 40;
592 error "$field_name match", 1;
595 for (my $i = 0; $i < length $str; $i++) {
596 my $ord = ord (substr $str, $i, 1);
598 if ($ord < 0 or $ord > 127) {
599 # $id is undefined at this point...
600 $log->msg ("$db_name:$record_name:$id:$field_name:$i");
601 $log->msg ("Old Contents:\n$str");
602 $str = FixChar ($str, $i);
603 $log->msg ("New Contents:\n$str");
614 my $record_name = shift;
621 $result = GetDefectRecord $log, $session, $record_name, $id;
623 $result = GetAllDefectRecords $log, $session, $record_name;
626 while ($result->MoveNext == $CQPerlExt::CQ_SUCCESS) {
627 # GetEntity by using $id
628 $id = $result->GetColumnValue (1);
629 my $entity = $session->GetEntity ($record_name, $id);
635 my $value = $entity->GetFieldValue ($name)->GetValue;
637 $value = CheckField $log, $db_name, $record_name, $id, $name, $value;
642 sub DeleteDynamicLists {
646 my @dynamic_lists = (
660 $log->msg ("Clearing dynamic lists...");
662 foreach my $name (@dynamic_lists) {
663 my @values = @{$from->GetListMembers ($name)};
665 foreach my $value (@values) {
666 $from->DeleteListMember ($name, $value);
669 } # DeleteDynamicLists
674 my $record_name = shift;
676 # Create a query for $record_name
677 my $query = $from->BuildQuery ($record_name);
679 $query->BuildField ("dbid");
681 # Build the result set
682 my $result = $from->BuildResultSet ($query);
685 my $record_count = $result->ExecuteAndCountRecords;
687 $log->msg ("Found $record_count $record_name records to delete...");
689 return if $record_count eq 0;
691 my $old_bufffer_status = $|;
692 $| = 1; # Turn off buffering
694 # Now for each record returned by the query...
695 while ($result->MoveNext == 1) {
696 my $id = $result->GetColumnValue (1);
699 my $entity = $from->GetEntityByDbId ($record_name, $id);
702 my $errmsg = $from->DeleteEntity ($entity, "delete");
704 verbose ".", undef, "nolf";
705 $log->err ("\n$errmsg\n") if $errmsg ne "";
710 $| = $old_bufffer_status; # Restore buffering
716 CQSession::Unbuild $session;
719 sub GetAllDefectRecords {
722 my $record_name = shift;
724 # Create a query for the record
725 my $query = $from->BuildQuery ($record_name);
727 # Add only dbid to the query. We'll retrieve the whole entity record later.
728 $query->BuildField ("id");
730 # Build the result set
731 my $result = $from->BuildResultSet ($query);
734 my $record_count = $result->ExecuteAndCountRecords;
736 $log->msg ("Found $record_count $record_name records...");
738 if ($record_count eq 0) {
743 } # GetAllDefectRecords
745 sub GetDefectRecord {
748 my $record_name = shift;
751 my $query = $from->BuildQuery ($record_name);
752 my $filter = $query->BuildFilterOperator ($CQPerlExt::AD_BOOL_OP_AND);
754 $query->BuildField ("id");
756 # BuildFilter requires an array reference
759 $filter->BuildFilter ("id", $CQPerlExt::CQ_COMP_OP_EQ, \@ids);
761 my $result = $from->BuildResultSet ($query);
762 my $record_count = $result->ExecuteAndCountRecords;
764 $log->msg ("Found $record_count $record_name record...");
766 if ($record_count eq 0) {
777 my $query = $to->BuildQuery ("Project");
779 my $filter = $query->BuildFilterOperator ($CQPerlExt::AD_BOOL_OP_AND);
781 $query->BuildField ("name");
783 # BuildFilter requires an array reference
785 push @projects, $project;
786 $filter->BuildFilter ("name", $CQPerlExt::CQ_COMP_OP_EQ, \@projects);
788 my $result = $to->BuildResultSet ($query);
790 my $record_count = $result->ExecuteAndCountRecords;
792 return $record_count;
799 my $session = CQPerlExt::CQSession_Build ();
801 $masterdb = "" if !defined $masterdb;
803 $session->UserLogon ($login, $password, $db_name, $masterdb);
808 sub TransferAttachments {
815 my $from_attachment_fields = $from->GetAttachmentFields;
817 for (my $i = 0; $i < $from_attachment_fields->Count; $i++) {
818 my $from_attachment_field = $from_attachment_fields->Item ($i);
819 my $field_name = $from_attachment_field->GetFieldName;
821 # At this point we don't have any info about whether we are
822 # coming from Prod or TO, however, there are the following fields:
825 # ----------------------- ----------------------- ----------------
826 # Attachments Attachments Attachments
827 # AttachmentsBRCM AttachmentBRCM AttachmentsBRCM
829 # You may notice that Prod: AttachmentBRCM is missing the "s".
831 $field_name = "AttachmentsBRCM" if $field_name eq "AttachmentBRCM";
833 my $from_attachments = $from_attachment_field->GetAttachments;
835 my $filename_suffix = 0;
837 for (my $j = 0; $j < $from_attachments->Count; $j++) {
838 my $from_attachment = $from_attachments->Item ($j);
839 my $description = $from_attachment->GetDescription;
840 my $filename = $from_attachment->GetFileName;
842 debug "Processing attachment #$j: $filename: $description";
844 # Extract the attached file to the file named attachment;
845 # Argh! Sometimes people attach files with the same filename!
846 # This works because filename is not really used except when
847 # you initially load the file. So the user could have, for
848 # example, captured say a logfile.txt, attached it,
849 # regenerated a new logfile.txt and attached it! This is
850 # perfectly acceptable since logfile.txt is copied into the
851 # database. However, when we extract it here we just use
852 # $filename. The result is that the second logfile.txt
853 # overwrites the first logfile.txt! We need to check for
854 # clashes (only a handful of them) and generate a new
858 $filename = "$filename.$filename_suffix";
861 $from_attachment->Load ($filename);
863 $to->AddAttachmentFieldValue ($field_name, $filename, $description);
865 push @files_created, $filename;
869 return @files_created;
870 } # TransferAttachments
872 sub TransferHistory {
873 my $from_entity = shift;
874 my $to_entity = shift;
875 my $filename = shift;
877 my $history_fields = $from_entity->GetHistoryFields;
878 my $nbr_history_fields = $history_fields->Count;
880 return if $nbr_history_fields eq 0;
882 for (my $i = 0; $i < $nbr_history_fields; $i++) {
883 my $histories = $history_fields->Item ($i)->GetHistories;
884 my $nbr_histories = $histories->Count;
886 return if $nbr_histories eq 0;
888 # Write out history to History.txt
889 open HISTORY, ">$filename"
890 or error "Unable to open $filename", 1;
892 print HISTORY "Previous History:\n";
893 print HISTORY "-----------------\n";
895 for (my $j = 0; $j < $nbr_histories; $j++) {
896 my $history_item = $histories->Item ($j);
897 my $history_value = $history_item->GetValue;
900 $history_value =~ /\S*\s*(.*$)/;
901 print HISTORY "$1\n";
907 # Add previous history as an AttachmentsBRCM
908 $to_entity->AddAttachmentFieldValue ("AttachmentsBRCM", $filename, "Previous history");
911 sub TransferRecords {
916 my $record_name = shift;
919 # Create a query for the record
920 my $query = $from->BuildQuery ($record_name);
922 # Always get the $id_name field
923 $query->BuildField ("dbid");
925 # Add all of @field_list to the query
926 foreach (@field_list) {
927 $query->BuildField ($_);
930 # Build the result set
931 my $result = $from->BuildResultSet ($query);
934 my $record_count = $result->ExecuteAndCountRecords;
936 verbose "Found $record_count $record_name records to merge...";
938 return if $record_count eq 0;
940 my $old_bufffer_status = $|;
941 $| = 1; # Turn off buffering
943 # Now for each record returned by the query...
944 while ($result->MoveNext == 1) {
945 # Create a new entity
946 my $entity = $to->BuildEntity ($record_name);
948 my $cols = $result->GetNumberOfColumns;
950 my $id = $result->GetColumnValue (1);
953 for (my $i = 2; $i <= $cols; $i++) {
954 my $name = $result->GetColumnLabel ($i);
955 my $value = $result->GetColumnValue ($i);
957 # Check field for non US ASCII characters and fix them
958 $value = CheckField $dbname, $record_name, $id, $name, $value;
960 # Set the field's value
961 $entity->SetFieldValue ($name, $value);
964 # Call the Validate method
965 my $errmsg = $entity->Validate;
967 $log->err ("Unable to validate $record_name record:\n$errmsg", 1) if $errmsg ne "";
969 # Post record to database
971 verbose ".", undef, "nolf";
974 $| = $old_bufffer_status; # Restore buffering
983 my $ord = ord (substr $str, $start, 1);
985 my $orig_start = $start;
987 # Let's just show a small subset of characters
988 if (length $str < $nbr_chars) {
991 } elsif (($start + $half) > length $str) {
993 my $right = length $str - $start;
994 if (($start - ($half + ($half - $right))) lt 0) {
997 $start = $start - ($half + $right);
999 } elsif (($start - $half) < 0) {
1001 if ($start + ($half + $start) gt length $str) {
1004 $end = $start + ($half + $start);
1007 $end = $start + $half;
1008 $start = $start - $half;
1011 my $word = substr $str, $start, $end - $start;
1013 debug "\t@ pos $orig_start ($ord)\n\t\"$word\"\n";
1020 my $ord = ord (substr $str, $pos, 1);
1022 error "Unknown character found ($ord) \"" . substr ($str, $pos, 1) . "\"", 1
1023 if (!defined $char_map {$ord});
1025 if ($debug eq "yes") {
1027 DisplayWord $str, $pos;
1030 substr ($str, $pos, 1) = $char_map {$ord};
1032 if ($debug eq "yes") {
1034 DisplayWord $str, $pos;