MsiTable.pm (c9b362f6) | MsiTable.pm (9f91b7e3) |
---|---|
1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance --- 30 unchanged lines hidden (view full) --- 39 40=cut 41sub new ($$$) 42{ 43 my ($class, $filename, $table_name) = @_; 44 45 my $self = { 46 'name' => $table_name, | 1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance --- 30 unchanged lines hidden (view full) --- 39 40=cut 41sub new ($$$) 42{ 43 my ($class, $filename, $table_name) = @_; 44 45 my $self = { 46 'name' => $table_name, |
47 'is_valid' => 1 | 47 'filename' => $filename, 48 'columns' => undef, 49 'column_specs' => undef, 50 'codepage' => undef, 51 'is_valid' => 1, 52 'is_modified' => 0 |
48 }; 49 bless($self, $class); 50 | 53 }; 54 bless($self, $class); 55 |
51 if ( -f $filename) | 56 if (defined $filename && -f $filename) |
52 { 53 $self->ReadFile($filename); 54 } 55 return $self; 56} 57 58 59 60 | 57 { 58 $self->ReadFile($filename); 59 } 60 return $self; 61} 62 63 64 65 |
66sub SetColumnData ($@) 67{ 68 my ($self, @data) = @_; 69 70 if (((scalar @data) % 2) != 0) 71 { 72 installer::logger::PrintError("column data has to have an even number of elements: (<column-name> <data-spec>)+)\n"); 73 $self->{'is_valid'} = 0; 74 return; 75 } 76 77 $self->{'columns'} = []; 78 $self->{'column_specs'} = []; 79 while (scalar @data > 0) 80 { 81 my $name = shift @data; 82 my $spec = shift @data; 83 push @{$self->{'columns'}}, $name; 84 push @{$self->{'column_specs'}}, $spec; 85 } 86} 87 88 89 90 91sub SetIndexColumns ($@) 92{ 93 my ($self, @index_columns) = @_; 94 95 $self->{'index_columns'} = [@index_columns]; 96} 97 98 99 100 101sub SetCodepage ($$) 102{ 103 my ($self, $codepage) = @_; 104 105 $self->{'codepage'} = $codepage; 106} 107 108 109 110 |
|
61sub IsValid ($) 62{ 63 my ($self) = @_; 64 return $self->{'is_valid'}; 65} 66 67 68 --- 32 unchanged lines hidden (view full) --- 101 $self->{'columns'} = [split(/\t/, $columns)]; 102 103 my $column_specs = Trim(<$in>); 104 $self->{'column_specs'} = [split(/\t/, $column_specs)]; 105 106 # Table name, index columns. 107 my $line = Trim(<$in>); 108 my @items = split(/\t/, $line); | 111sub IsValid ($) 112{ 113 my ($self) = @_; 114 return $self->{'is_valid'}; 115} 116 117 118 --- 32 unchanged lines hidden (view full) --- 151 $self->{'columns'} = [split(/\t/, $columns)]; 152 153 my $column_specs = Trim(<$in>); 154 $self->{'column_specs'} = [split(/\t/, $column_specs)]; 155 156 # Table name, index columns. 157 my $line = Trim(<$in>); 158 my @items = split(/\t/, $line); |
109 if (scalar @items == 3) | 159 my $item_count = scalar @items; 160 if ($item_count>=1 && $items[0] eq $self->{'name'}) |
110 { | 161 { |
162 # No codepage. 163 } 164 elsif ($item_count>=2 && $items[1] eq $self->{'name'}) 165 { |
|
111 $self->{'codepage'} = shift @items; 112 } | 166 $self->{'codepage'} = shift @items; 167 } |
113 my $table_name = shift @items; 114 if ($table_name ne $self->{'name'}) | 168 else |
115 { | 169 { |
116 printf STDERR ("reading wrong table data for table '%s' (got %s)\n", $self->{'name'}, $table_name); | 170 printf STDERR ("reading wrong table data for table '%s' (got %s)\n", $self->{'name'}, $items[0]); |
117 $self->{'is_valid'} = 0; 118 return; 119 } | 171 $self->{'is_valid'} = 0; 172 return; 173 } |
174 shift @items; |
|
120 $self->{'index_columns'} = [@items]; 121 $self->{'index_column_index'} = $self->GetColumnIndex($items[0]); 122 123 my $rows = []; 124 while (<$in>) 125 { 126 # Remove all trailing returns and newlines. Keep trailing spaces and tabs. 127 s/[\r\n]+$//g; 128 129 my @items = split(/\t/, $_); 130 push @$rows, new installer::patch::MsiRow($self, @items); 131 } 132 $self->{'rows'} = $rows; 133 134 return $self; 135} 136 137 138 | 175 $self->{'index_columns'} = [@items]; 176 $self->{'index_column_index'} = $self->GetColumnIndex($items[0]); 177 178 my $rows = []; 179 while (<$in>) 180 { 181 # Remove all trailing returns and newlines. Keep trailing spaces and tabs. 182 s/[\r\n]+$//g; 183 184 my @items = split(/\t/, $_); 185 push @$rows, new installer::patch::MsiRow($self, @items); 186 } 187 $self->{'rows'} = $rows; 188 189 return $self; 190} 191 192 193 |
194 195=head WriteFile($self, $filename) 196 197 Write a text file containing the current table content. 198 199=cut 200sub WriteFile ($$) 201{ 202 my ($self, $filename) = @_; 203 204 open my $out, ">".$self->{'filename'}; 205 206 print $out join("\t", @{$self->{'columns'}})."\r\n"; 207 print $out join("\t", @{$self->{'column_specs'}})."\r\n"; 208 if (defined $self->{'codepage'}) 209 { 210 print $out $self->{'codepage'} . "\t"; 211 } 212 print $out $self->{'name'} . "\t"; 213 print $out join("\t",@{$self->{'index_columns'}})."\r\n"; 214 215 foreach my $row (@{$self->{'rows'}}) 216 { 217 print $out $row->Format("\t")."\r\n"; 218 } 219 220 close $out; 221} 222 223 224 225 226sub UpdateTimestamp ($) 227{ 228 my $self = shift; 229 230 utime(undef,undef, $self->{'filename'}); 231} 232 233 234 235 236sub GetName ($) 237{ 238 my $self = shift; 239 240 return $self->{'name'}; 241} 242 243 244 245 |
|
139=head2 GetColumnCount($self) 140 141 Return the number of columns in the table. 142 143=cut 144sub GetColumnCount ($) 145{ 146 my ($self) = @_; --- 41 unchanged lines hidden (view full) --- 188 } 189 190 printf STDERR ("did not find column %s in %s\n", $column_name, join(" and ", @{$self->{'columns'}})); 191 return -1; 192} 193 194 195 | 246=head2 GetColumnCount($self) 247 248 Return the number of columns in the table. 249 250=cut 251sub GetColumnCount ($) 252{ 253 my ($self) = @_; --- 41 unchanged lines hidden (view full) --- 295 } 296 297 printf STDERR ("did not find column %s in %s\n", $column_name, join(" and ", @{$self->{'columns'}})); 298 return -1; 299} 300 301 302 |
303=head2 GetRowIndex($self, $index_column_index, $index_column_value) |
|
196 | 304 |
305 Return the index, starting at 0, of the (first) row that has value $index_column_value 306 in column with index $index_column_index. 307 308 Return -1 if now such row is found. 309 310=cut 311sub GetRowIndex ($$$) 312{ 313 my ($self, $index_column_index, $index_column_value) = @_; 314 315 my $rows = $self->{'rows'}; 316 for (my ($row_index,$row_count)=(0,scalar @$rows); $row_index<$row_count; ++$row_index) 317 { 318 my $row = $rows->[$row_index]; 319 if ($row->GetValue($index_column_index) eq $index_column_value) 320 { 321 return $row_index; 322 } 323 } 324 325 return -1; 326} 327 328 329 330 |
|
197=head2 GetValue($self, $selector_column, $selector_column_value, $value_column) 198 199 Find the row in which the $selector_column has value 200 $selector_column_value and return its value in the $value_column. 201 202=cut 203 204sub GetValue ($$$$) --- 60 unchanged lines hidden (view full) --- 265 my $self = shift; 266 267 return $self->{'rows'}; 268} 269 270 271 272 | 331=head2 GetValue($self, $selector_column, $selector_column_value, $value_column) 332 333 Find the row in which the $selector_column has value 334 $selector_column_value and return its value in the $value_column. 335 336=cut 337 338sub GetValue ($$$$) --- 60 unchanged lines hidden (view full) --- 399 my $self = shift; 400 401 return $self->{'rows'}; 402} 403 404 405 406 |
407=head2 SetRow($self, {$key, $value}*) |
|
273 | 408 |
409 Replace an existing row. If no matching row is found then add the row. 410 411 The row is defined by a set of key/value pairs. Their order is defined by the keys (column names) 412 and their indices as defined in $self->{'columns'}. 413 414 Rows are compared by their values of the index column. By default this is the first element of 415 $self->{'index_columns'} but is overruled by the last key that starts with a '*'. 416 417=cut 418sub SetRow ($@) 419{ 420 my $self = shift; 421 my @data = @_; 422 423 my @items = (); 424 my $index_column = $self->{'index_columns'}->[0]; 425 426 # Key/Value has to have an even number of entries. 427 MsiTools::Die("invalid arguments given to MsiTable::SetRow()\n") if (scalar @data%2) != 0; 428 429 # Find column indices for column names. 430 while (scalar @data > 0) 431 { 432 my $column_name = shift @data; 433 if ($column_name =~ /^\*(.*)$/) 434 { 435 # Column name starts with a '*'. Use it as index column. 436 $column_name = $1; 437 $index_column = $1; 438 } 439 my $value = shift @data; 440 my $column_index = $self->GetColumnIndex($column_name); 441 $items[$column_index] = $value; 442 } 443 444 my $index_column_index = $self->GetColumnIndex($index_column); 445 my $row_index = $self->GetRowIndex($index_column_index, $items[$index_column_index]); 446 447 if ($row_index < 0) 448 { 449 # Row does not yet exist. Add it. 450 push @{$self->{'rows'}}, installer::patch::MsiRow->new($self, @items); 451 } 452 else 453 { 454 # Row does already exist. Replace it. 455 $self->{'rows'}->[$row_index] = installer::patch::MsiRow->new($self, @items); 456 } 457 458 $self->MarkAsModified(); 459} 460 461 462 463 464sub MarkAsModified ($) 465{ 466 my $self = shift; 467 468 $self->{'is_modified'} = 1; 469} 470 471 472 473 474sub MarkAsUnmodified ($) 475{ 476 my $self = shift; 477 478 $self->{'is_modified'} = 0; 479} 480 481 482 483 484sub IsModified ($) 485{ 486 my $self = shift; 487 488 return $self->{'is_modified'}; 489} 490 491 |
|
2741; | 4921; |