#!/usr/bin/perl use strict; #################### main pod documentation begin ################### =head1 NAME Zymonic - Test script to add records to a table, for performance testing =head1 SYNOPSIS =head1 DESCRIPTION This script will take in a table name then create a record in that table with random data. =head1 SUPPORT As in the license, Zymonic is provided without warranty or support unless purchased separately, however... If you email zymonic-support@zednax.com your issue will be noted and may receive a response. For security issues, please contact zymonic-security@zednax.com and someone will respond within 8 working hours. =head1 AUTHOR Alex Masidlover et al. CPAN ID: MODAUTHOR Zednax Limited alex.masidlover@zednax.com http://www.zednax.com =head1 COPYRIGHT This program is free software licensed under the... Zymonic Public License 1.0 The full text of the license can be found in the LICENSE file included with this module. Other licenses may be acceptable if including parts of Zymonic in larger projects, please contact Zednax for details. =head1 SEE ALSO perl(1). =cut #################### main pod documentation end ################### # modules use Data::Dumper; use List::Util qw(shuffle); use Time::HiRes qw(time); use Zymonic; use Zymonic::Auth; use Zymonic::Config; use Zymonic::Session; use Zymonic::Utils qw(death_handler random_string); # death handler $main::SIG{__DIE__} = \&death_handler; # setup the field factory $Zymonic::field_factory = Zymonic::FieldFactory->new(); # enable cache for table includes and relationship permissions $Zymonic::object_cache = { 'Zymonic::TableInclude' => {}, 'Zymonic::RelationshipPermissions' => {}, }; # Create a session (CGI only) $Zymonic::session = Zymonic::Session->new(); print "Loaded Session\n"; # force no debugs $Zymonic::Utils::debugs_written = 1; # set system $Zymonic::system = $ARGV[0]; usage() unless $Zymonic::system; # create config $Zymonic::ZCONFIG{$Zymonic::system} = Zymonic::Config->new( system_name => $Zymonic::system, config_dir => "/etc/zymonic", ); print "Loaded Config\n"; # set session db $Zymonic::session->{DB} = $Zymonic::ZCONFIG{$Zymonic::system}->{DB}; # create auth my $auth = Zymonic::Auth->new( config => $Zymonic::ZCONFIG{$Zymonic::system}, session => $Zymonic::session, DB => $Zymonic::ZCONFIG{$Zymonic::system}->{DB}, user => '', credentials => '', logged_in => '', ); main(); exit(0); #################### subroutine header begin #################### =head2 main Usage : main(); Purpose : main script functionality Returns : nothing Argument : nothing Throws : nothing Comment : See Also : =cut #################### subroutine header end ################### sub main { my $table_zname = $ARGV[1]; usage() unless $table_zname; my $number_of_records = $ARGV[2] || 1; my $number_of_fields = $ARGV[3] || ''; # load the table my $table = Zymonic::Table->new( parent => $Zymonic::session, zname => $table_zname, ident => 'add_random_record_script_' . $table_zname . '_', config => $Zymonic::ZCONFIG{$Zymonic::system}, auth => $auth, DB => $Zymonic::ZCONFIG{$Zymonic::system}->{DB}, get_user_values => 'true', ); # keep track of what was added my @ids = (); # get fields to add data to my $table_fields = table_fields( $table, $number_of_fields ); # create the random records my $total = 0; print "Adding $number_of_records random records to table '" . $table->display_name() . "' with " . ( scalar keys %{$table_fields} ) . " fields\n"; foreach my $i ( 1 .. $number_of_records ) { print "Adding record $i:\t"; my $record = $table->setup_placeholder(); random_record_data( $table, $record, $table_fields ); my $start = time() * 1000; $table->before_add('no_perms'); my $id = $table->add_record( 'no_perms', 'no_new_placeholder' ); $table->after_add($id); my $end = time() * 1000; my $time_taken = ( $end - $start ); print '' . sprintf( '%5.6f', $time_taken ) . " ms\n"; $total += $time_taken; push( @ids, $id ); } print "Total Time: \t" . sprintf( '%5.6f', $total ) . " ms\n"; print "Average Time:\t" . sprintf( '%5.6f', $total / $number_of_records ) . " ms\n"; print "Deleting random records.\n"; clear_random_records( $table, \@ids ); print "Done.\n"; } #################### subroutine header begin #################### =head2 table_fields Usage : table_fields($table); Purpose : Returns name of fields we can set random data on on in this table Returns : hashref of field zname => length of random data Argument : table and optional number of fields to limit it to Throws : nothing Comment : See Also : =cut #################### subroutine header end ################### sub table_fields { my $table = shift; my $number_of_fields = shift || ''; my $auto_inc_key; eval { $auto_inc_key = $table->keyfields('auto_inc'); 1; } or do { my $exception = $@; if ( ref($exception) && $exception->isa('Zymonic::Exception::Db::No_Auto_Inc_Primary_Key') ) { $auto_inc_key = undef; } else { rethrow_exception($exception); } }; # get table fields, if limiting number then shuffle it my @table_fields = values %{ $table->get_fields() }; if ($number_of_fields) { @table_fields = shuffle @table_fields; } my $count = 0; my %fields = (); foreach my $field_ref (@table_fields) { # ignore auto fields # ignore auto id # ignore any special fields # ignore anything other than number/text next if $field_ref->{zname} =~ /sec_id|parent_process_id|deleted|autocreated|posix_process_id|zz_updated|zz_updated_timestamp/ || $auto_inc_key && $field_ref->{field} eq $auto_inc_key || $field_ref->{class} || $field_ref->{field_type} !~ /int|float|double|varchar|char|text/ || ( $number_of_fields && $count >= $number_of_fields ); # generate random data my $len; if ( $field_ref->{field_type} =~ /int|float|double/ ) { # max int is 2147483647, so don't generate num bigger $len = ( ( $field_ref->{max_length} > 9 && $field_ref->{field_type} eq 'int' ) ? 9 : $field_ref->{max_length} ); } else { # limit strings to length 10 $len = ( $field_ref->{max_length} > 10 ? 10 : $field_ref->{max_length} ); } $fields{ $field_ref->{zname} } = $len; ++$count; } return \%fields; } #################### subroutine header begin #################### =head2 clear_random_records Usage : clear_random_records($table, \@ids); Purpose : deletes the random records from the db Returns : nothing Argument : table and ids Throws : nothing Comment : See Also : =cut #################### subroutine header end ################### sub clear_random_records { my $table = shift; my $ids = shift; foreach my $id ( @{$ids} ) { $table->delete_record( $id, 'no_perms', 'actual_delete' ); } } #################### subroutine header begin #################### =head2 random_record_data Usage : random_record_data($table, $record); Purpose : Adds random data to the record Returns : nothing Argument : Table and record Throws : nothing Comment : See Also : =cut #################### subroutine header end ################### sub random_record_data { my $table = shift; my $record = shift; my $table_fields = shift; foreach my $field_zname ( keys %{$table_fields} ) { # generate random data my $random_data = random_string( $table_fields->{$field_zname}, ( 0 .. 9 ) ); # set random data as cgi param $Zymonic::session->set_cgi_param( $record->{ident} . $field_zname, $random_data ); } } #################### subroutine header begin #################### =head2 usage Usage : usage(); Purpose : Prints script usage. Returns : nothing Argument : nothing Throws : nothing Comment : See Also : =cut #################### subroutine header end ################### sub usage { print "Usage: add_random_record.pl [system] [table] [number of records (defaults to 1)] [number of fields to set values for (defaults to all)]\n"; exit(1); }