Merge branch 'storageareas' into tesla

This commit is contained in:
Isaac Connor 2018-01-18 08:42:12 -08:00
commit 274e8e982c
7 changed files with 142 additions and 11 deletions

View File

@ -224,7 +224,8 @@ CREATE TABLE `Events_Hour` (
`StartTime` datetime default NULL,
`DiskSpace` bigint unsigned default NULL,
PRIMARY KEY (`EventId`),
KEY `Events_Hour_MonitorId_StartTime_idx` (`MonitorId`,`StartTime`)
KEY `Events_Hour_MonitorId_idx` (`MonitorId`)
KEY `Events_Hour_StartTime_idx` (`StartTime`)
) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Day`;
@ -234,7 +235,8 @@ CREATE TABLE `Events_Day` (
`StartTime` datetime default NULL,
`DiskSpace` bigint unsigned default NULL,
PRIMARY KEY (`EventId`),
KEY `Events_Day_MonitorId_StartTime_idx` (`MonitorId`,`StartTime`)
KEY `Events_Day_MonitorId_idx` (`MonitorId`)
KEY `Events_Day_StartTime_idx` (`StartTime`)
) ENGINE=@ZM_MYSQL_ENGINE@;
@ -245,7 +247,8 @@ CREATE TABLE `Events_Week` (
`StartTime` datetime default NULL,
`DiskSpace` bigint unsigned default NULL,
PRIMARY KEY (`EventId`),
KEY `Events_Week_MonitorId_StartTime_idx` (`MonitorId`,`StartTime`)
KEY `Events_Week_MonitorId_idx` (`MonitorId`)
KEY `Events_Week_StartTime_idx` (`StartTime`)
) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Month`;
@ -255,7 +258,8 @@ CREATE TABLE `Events_Month` (
`StartTime` datetime default NULL,
`DiskSpace` bigint unsigned default NULL,
PRIMARY KEY (`EventId`),
KEY `Events_Month_MonitorId_StartTime_idx` (`MonitorId`,`StartTime`)
KEY `Events_Month_MonitorId_idx` (`MonitorId`)
KEY `Events_Month_StartTime_idx` (`StartTime`)
) ENGINE=@ZM_MYSQL_ENGINE@;
@ -265,7 +269,7 @@ CREATE TABLE `Events_Archived` (
`MonitorId` int(10) unsigned NOT NULL,
`DiskSpace` bigint unsigned default NULL,
PRIMARY KEY (`EventId`),
KEY `Events_Month_MonitorId_idx` (`MonitorId`)
KEY `Events_Archived_MonitorId_idx` (`MonitorId`)
) ENGINE=@ZM_MYSQL_ENGINE@;

61
db/zm_update-1.31.24.sql Normal file
View File

@ -0,0 +1,61 @@
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Hour' and index_name = 'Events_Hour_MonitorId_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, 'DROP INDEX Events_Hour_MonitorId_StartTime_idx ON Events_Hour', "SELECT 'Events_Hour_MonitorId_StartTime_idx INDEX is already removed.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Hour' and index_name = 'Events_Hour_MonitorId_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Hour_MonitorId_idx INDEX already exists.'", "CREATE INDEX `Events_Hour_MonitorId_idx` ON `Events_Hour` (`MonitorId`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Hour' and index_name = 'Events_Hour_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Hour_StartTime_idx INDEX already exists.'", "CREATE INDEX `Events_Hour_StartTime_idx` ON `Events_Hour` (`StartTime`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Day' and index_name = 'Events_Day_MonitorId_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, 'DROP INDEX Events_Day_MonitorId_StartTime_idx ON Events_Day', "SELECT 'Events_Day_MonitorId_StartTime_idx INDEX is already removed.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Day' and index_name = 'Events_Day_MonitorId_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Day_MonitorId_idx INDEX already exists.'", "CREATE INDEX `Events_Day_MonitorId_idx` ON `Events_Day` (`MonitorId`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Day' and index_name = 'Events_Day_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Day_StartTime_idx INDEX already exists.'", "CREATE INDEX `Events_Day_StartTime_idx` ON `Events_Day` (`StartTime`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Week' and index_name = 'Events_Week_MonitorId_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, 'DROP INDEX Events_Week_MonitorId_StartTime_idx ON Events_Week', "SELECT 'Events_Week_MonitorId_StartTime_idx INDEX is already removed.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Week' and index_name = 'Events_Week_MonitorId_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Week_MonitorId_idx INDEX already exists.'", "CREATE INDEX `Events_Week_MonitorId_idx` ON `Events_Day` (`MonitorId`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Week' and index_name = 'Events_Week_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Week_StartTime_idx INDEX already exists.'", "CREATE INDEX `Events_Week_StartTime_idx` ON `Events_Week` (`StartTime`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Month' and index_name = 'Events_Month_MonitorId_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, 'DROP INDEX Events_Month_MonitorId_StartTime_idx ON Events_Month', "SELECT 'Events_Month_MonitorId_StartTime_idx INDEX is already removed.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Month' and index_name = 'Events_Month_MonitorId_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Month_MonitorId_idx INDEX already exists.'", "CREATE INDEX `Events_Month_MonitorId_idx` ON `Events_Month` (`MonitorId`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @exist := (select count(*) from information_schema.statistics where table_name = 'Events_Month' and index_name = 'Events_Month_StartTime_idx' and table_schema = database());
set @sqlstmt := if( @exist > 0, "SELECT 'Events_Month_StartTime_idx INDEX already exists.'", "CREATE INDEX `Events_Month_StartTime_idx` ON `Events_Month` (`StartTime`)");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

View File

@ -439,6 +439,14 @@ sub DiskSpace {
sub MoveTo {
my ( $self, $NewStorage ) = @_;
$ZoneMinder::Database::dbh->begin_work();
$self->lock_and_load();
# data is reloaded, so need to check that the move hasn't already happened.
if ( $$self{StorageId} == $$NewStorage{Id} ) {
$ZoneMinder::Database::dbh->commit();
return "Event has already been moved by someone else.";
}
my $OldStorage = $self->Storage();
my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint
@ -446,16 +454,21 @@ sub MoveTo {
my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint
if ( ! $$NewStorage{Id} ) {
$ZoneMinder::Database::dbh->commit();
return "New storage does not have an id. Moving will not happen.";
} elsif ( !$NewPath ) {
$ZoneMinder::Database::dbh->commit();
return "New path ($NewPath) is empty.";
} elsif ( ! -e $NewPath ) {
$ZoneMinder::Database::dbh->commit();
return "New path $NewPath does not exist.";
} elsif ( ! -e $OldPath ) {
$ZoneMinder::Database::dbh->commit();
return "Old path $OldPath does not exist.";
}
( $NewPath ) = ( $self->Path(undef) =~ /^(.*)$/ ); # De-taint
if ( $NewPath eq $OldPath ) {
$ZoneMinder::Database::dbh->commit();
return "New path and old path are the same! $NewPath";
}
Debug("Moving event $$self{Id} from $OldPath to $NewPath");
@ -484,14 +497,22 @@ sub MoveTo {
last;
}
} # end foreach file.
return $error if $error;
if ( $error ) {
$ZoneMinder::Database::dbh->commit();
return $error;
}
# Succeeded in copying all files, so we may now update the Event.
$$self{StorageId} = $$NewStorage{Id};
$$self{Storage} = $NewStorage;
$error .= $self->save();
return $error if $error;
if ( $error ) {
$ZoneMinder::Database::dbh->commit();
return $error;
}
$self->delete_files( $OldStorage );
$ZoneMinder::Database::dbh->commit();
return $error;
} # end sub MoveTo

View File

@ -105,6 +105,44 @@ sub load {
} # end if
} # end sub load
sub lock_and_load {
my ( $self ) = @_;
my $type = ref $self;
no strict 'refs';
my $table = ${$type.'::table'};
if ( ! $table ) {
Error( 'NO table for type ' . $type );
return;
} # end if
my $primary_key = ${$type.'::primary_key'};
if ( ! $primary_key ) {
Error( 'NO primary_key for type ' . $type );
return;
} # end if
if ( ! $$self{$primary_key} ) {
my ( $caller, undef, $line ) = caller;
Error( (ref $self) . "::lock_and_load called without $primary_key from $caller:$line");
return;
}
#$log->debug("Object::load Loading from db $type");
Debug("Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
my $data = $ZoneMinder::Database::dbh->selectrow_hashref( "SELECT * FROM $table WHERE $primary_key=? FOR UPDATE", {}, $$self{$primary_key} );
if ( ! $data ) {
if ( $ZoneMinder::Database::dbh->errstr ) {
Error( "Failure to load Object record for $$self{$primary_key}: Reason: " . $ZoneMinder::Database::dbh->errstr );
} else {
Debug("No Results Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
} # end if
} # end if
if ( $data and %$data ) {
@$self{keys %$data} = values %$data;
} # end if
} # end sub lock_and_load
sub AUTOLOAD {
my ( $self, $newvalue ) = @_;
my $type = ref($_[0]);

View File

@ -320,10 +320,14 @@ sub checkFilter {
if ( $filter->{UpdateDiskSpace} ) {
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
$ZoneMinder::Database::dbh->begin_work();
$Event->lock_and_load();
my $old_diskspace = $$Event{DiskSpace};
if ( $old_diskspace != $Event->DiskSpace(undef) ) {
$Event->save();
}
$ZoneMinder::Database::dbh->commit();
} # end if UpdateDiskSpace
} # end foreach event
}

View File

@ -793,6 +793,7 @@ uint32_t Monitor::GetLastEventId() const {
// This function is crap.
double Monitor::GetFPS() const {
// last_write_index is the last capture index. It starts as == image_buffer_count so that the first asignment % image_buffer_count = 0;
int index1 = shared_data->last_write_index;
if ( index1 == image_buffer_count ) {
// last_write_index only has this value on startup before capturing anything.
@ -801,6 +802,7 @@ double Monitor::GetFPS() const {
Snapshot *snap1 = &image_buffer[index1];
if ( !snap1->timestamp || !snap1->timestamp->tv_sec ) {
// This should be impossible
Warning("Impossible situation. No timestamp on captured image");
return 0.0;
}
struct timeval time1 = *snap1->timestamp;
@ -810,9 +812,11 @@ double Monitor::GetFPS() const {
Snapshot *snap2 = &image_buffer[index2];
// the timestamp pointers are initialized on connection, so that's redundant
// tv_sec is probably only zero during the first loop of capturing, so this basically just counts the unused images.
while ( !snap2->timestamp || !snap2->timestamp->tv_sec ) {
// The problem is that there is no locking, and we set the timestamp before we set last_write_index,
// so there is a small window where the next image can have a timestamp in the future
while ( !snap2->timestamp || !snap2->timestamp->tv_sec || tvDiffSec(*snap2->timestamp, *snap1->timestamp) < 0 ) {
if ( index1 == index2 ) {
// We didn't find any initialized images
// All images are uncaptured
return 0.0;
}
index2 = (index2+1)%image_buffer_count;
@ -822,7 +826,6 @@ double Monitor::GetFPS() const {
struct timeval time2 = *snap2->timestamp;
double time_diff = tvDiffSec( time2, time1 );
double curr_fps = image_count/time_diff;
if ( curr_fps < 0.0 ) {

View File

@ -1 +1 @@
1.31.23
1.31.24