Skip to content

Commit

Permalink
update inventory write diff
Browse files Browse the repository at this point in the history
  • Loading branch information
alacn1 committed Jun 4, 2024
1 parent 80bc2aa commit 68c6a11
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 28 deletions.
10 changes: 5 additions & 5 deletions Apache/Ocsinventory/Map.pm
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ our %DATA_MAP= (

batteries => {
mask => 1048576,
multi => 0,
multi => 1,
auto => 1,
delOnReplace => 1,
sortBy => 'NAME',
Expand All @@ -462,7 +462,7 @@ our %DATA_MAP= (

usbdevices => {
mask => 2097152,
multi => 0,
multi => 1,
auto => 1,
delOnReplace => 1,
sortBy => 'DESCRIPTION',
Expand All @@ -483,7 +483,7 @@ our %DATA_MAP= (
auto => 1,
delOnReplace => 1,
sortBy => 'NAME',
writeDiff => 0,
writeDiff => 1,
cache => 0,
fields => {
BASEURL => {},
Expand Down Expand Up @@ -1116,7 +1116,7 @@ our %DATA_MAP= (
auto => 1,
delOnReplace => 1,
sortBy => 'NAME',
writeDiff => 0,
writeDiff => 1,
cache => 0,
fields => {
ID_USER => {},
Expand All @@ -1134,7 +1134,7 @@ our %DATA_MAP= (
auto => 1,
delOnReplace => 1,
sortBy => 'NAME',
writeDiff => 0,
writeDiff => 1,
cache => 0,
fields => {
ID_GROUP => {},
Expand Down
105 changes: 82 additions & 23 deletions Apache/Ocsinventory/Server/Inventory/Update.pm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use Apache::Ocsinventory::Interface::AssetCategory;
use Apache::Ocsinventory::Interface::Saas;

use strict;
use Encode;

require Exporter;

Expand Down Expand Up @@ -112,49 +113,107 @@ sub _update_inventory_section{
my $refXml = $result->{CONTENT}->{uc $section};
my $sth = $dbh->prepare($sectionMeta->{sql_select_string});
$sth->execute($deviceId) or return 1;
while(my @row = $sth->fetchrow_array){
push @fromDb, [ @row ];
}
for my $line (@$refXml){
&_get_bind_values($line, $sectionMeta, \@bind_values);
push @fromXml, [ @bind_values ];

while(my $row = $sth->fetchrow_hashref){
next unless defined $row->{'ID'};
# at same order of _get_bind_values
my @values;
for my $field ( @{ $sectionMeta->{field_arrayref} } ){
my $value;
if(defined $row->{$field}){
$value = $row->{$field};
}
else{
my $fieldMod = $field;
$fieldMod =~ s/^`(.*)`$/$1/;
if(defined $row->{$fieldMod}){
$value = $row->{$fieldMod};
}
}
push @values, $value;
}
push @fromDb, { 'ID' => $row->{ID}, 'VALUES' => [ @values ] };
}

if($sectionMeta->{multi}){
for my $line (@$refXml){
&_get_bind_values($line, $sectionMeta, \@bind_values);
push @fromXml, { 'VALUES' => [ @bind_values ] };
@bind_values = ();
}
}
else{
&_get_bind_values($refXml, $sectionMeta, \@bind_values);
push @fromXml, { 'VALUES' => [ @bind_values ] };
@bind_values = ();
}
#TODO: Sorting XML entries, to compare more quickly with DB elements

my $new=0;
my $del=0;
for my $l_xml (@fromXml){
for my $lineXml (@fromXml){
my $found = 0;
for my $i_db (0..$#fromDb){
next unless $fromDb[$i_db];
my @line = @{$fromDb[$i_db]};
my $comp_xml = join '', @$l_xml;
my $comp_db = join '', @line[2..$#line];
if( $comp_db eq $comp_xml ){
for my $lineDb (@fromDb){
next unless defined $lineDb;

next unless ($#{ $lineXml->{VALUES} } == $#{ $lineDb->{VALUES} });

my $eq = undef;
for my $n (0..$#{ $lineDb->{VALUES} }){
my $valueXml = $lineXml->{VALUES}[$n] // '';
my $valueDb = $lineDb->{VALUES}[$n] // '';
my $valueXmlRE;
my $valueDbRE;

if($valueXml eq $valueDb){
# xml value is equal db value
}
elsif(($valueXml eq '') && (($valueDb eq '0') || ($valueDb eq '0000-00-00'))){
# xml value is empty, at database may be 0 or 0000-00-00
}
elsif(($valueXml =~ '^[0-9]+\.[0-9]+$') && ($valueDb =~ '^[0-9]+$') && (int($valueXml + 0.5) == $valueDb)){
# xml value is float, db value is int, round compare
}
elsif(encode_utf8($valueXml) eq $valueDb){
# may need encode xml to match db utf8
}
elsif(
(($valueDbRE = $valueDb) =~ s/^([0-9]+)-0*([0-9]+)-0*([0-9]+)$/$1-$2-$3/) &&
(($valueXmlRE = $valueXml) =~ s/^([0-9]+)[\/-]0*([0-9]+)[\/-]0*([0-9]+)( [0-9]+:[0-9]+(:[0-9]+)?)?$/$1-$2-$3/) &&
($valueDbRE eq $valueXmlRE)
){
# db value is date yyyy-mm-dd, xml value may be yyyy-m-d, yyyy/m/d, yyyy/m/d hh:nn, yyyy/m/d hh:nn:ss
}
else{
# not equal
$eq = 0;
last;
}
$eq = 1 if !defined($eq);
}

if($eq){
$found = 1;
# The value has been found, we have to delete it from the db list
# (elements remaining will be deleted)
delete $fromDb[$i_db];
$lineDb = undef;
last;
}
}
if(!$found){
$new++;
$dbh->do( $sectionMeta->{sql_insert_string}, {}, $deviceId, @$l_xml ) or return 1;
$dbh->do( $sectionMeta->{sql_insert_string}, {}, $deviceId, @{ $lineXml->{VALUES} } ) or return 1;
if( $ENV{OCS_OPT_INVENTORY_CACHE_ENABLED} && $sectionMeta->{cache} ){
&_cache( 'add', $section, $sectionMeta, $l_xml );
&_cache( 'add', $section, $sectionMeta, $lineXml->{VALUES} );
}
}
}
# Now we have to delete from DB elements that still remain in fromDb
for (@fromDb){
next if !defined (${$_}[0]);
for my $lineDb (@fromDb){
next unless defined $lineDb;
$del++;
$dbh->do( $sectionMeta->{sql_delete_string}, {}, $deviceId, ${$_}[0]) or return 1;
my @ldb = @$_;
@ldb = @ldb[ 2..$#ldb ];
$dbh->do( $sectionMeta->{sql_delete_string}, {}, $deviceId, $lineDb->{ID}) or return 1;
if( $ENV{OCS_OPT_INVENTORY_CACHE_ENABLED} && $sectionMeta->{cache} && !$ENV{OCS_OPT_INVENTORY_CACHE_KEEP}){
&_cache( 'del', $section, $sectionMeta, \@ldb );
&_cache( 'del', $section, $sectionMeta, $lineDb->{VALUES} );
}
}
if( $new||$del ){
Expand Down

0 comments on commit 68c6a11

Please sign in to comment.