use Syntax::Keyword::Try;
use Benchmark;
use lib "tests";
-use lib 'system/modules';
+use lib '/home/will/dev_new/PerlCNF/system/modules';
# use lib "system/modules";
require TestManager;
my $test = TestManager -> new($0);
my $cnf;
-my $DB_SETTINGS = qq(
+my $DB_SETTINGS = q(
<<<CONST
DB = nomad_network
DB_CREDENTIALS = tester/tester2025
DB_SQL_SOURCE = DBI:Pg:host=elite;port=5432;
>>>
+
+/**
+ * Load and ~/.config/this_script_name.cnf
+ **/
+<<<FILE $0>>>
+
+
);
try{
+ #encode/decode text quotes and codes
+
sub encodeQuotes{
- my $ret = shift; $ret =~ s/\s*$//g;$ret =~ s/\"/\"\"/g; $ret =~ s/\'/\'\'/g;
+ my $ret = shift; $ret =~ s/\s*$//g;
+ $ret =~ s/\"/\"\"/g; $ret =~ s/\'/\'\'/g; $ret =~ s/\\n/%/g;
+ $ret =~ s/\\n/\\\\n/g;
return $ret
}
sub decodeQuotes{
- my $ret = shift; $ret =~ s/\"\"/\"/g; $ret =~ s/\'\'/\'/g;
+ my $ret = shift;
+ $ret =~ s/\"\"/\"/g; $ret =~ s/\'\'/\'/g; #$ret =~ s/\\\\/\\/g;
+ $ret =~ s/\\n/%/g;
return $ret
}
-
-
die $test->failed() if not $cnf = CNFParser->new(undef,{'%LOG'=>{console=>1}});
$test->case("Passed new instance CNFParser.");
#
$cnf->parse(undef,$DB_SETTINGS);
my($user,$pass,$source,$store)=(CNFSQL::_credentialsToArray($cnf->{DB_CREDENTIALS}),$cnf->{DB_SQL_SOURCE},$cnf->{DB});
our ($db,$test_further) = (undef,1);
+ my $now = CNFDateTime -> now() -> datetime();
+ my ($inserts, $selects,$updates, $errors) = (0,0,0,0);
+
try{
$db = CNFSQL::_connectDB($user,$pass,$source,$store);
}catch($e){
$test->case("initDatabase");
my $content = do {local $/;<DATA>};
$cnf->parse(undef, $content);
-
- $cnf->SQL()->initDatabase($db);
+ $cnf->SQL()->initDatabase($db);
}
my $SQL_SERVER = $cnf->SQL();
my %schema = $SQL_SERVER->schema();
}else{
$cnf->warn('Skipping SQL Statement for CMD_HISTORY, table exists!');
}
+
+ my @his_hosts = $cnf -> collection('@HISTORY_HOSTS___');
+ my @entries_by_ord; my $ord = 0;
+
+ if(!@his_hosts){
+ die "CNF ARRAY Property \@HISTORY_HOSTS is not defined or not set!\n".
+ q(
+###
+# Example property that can be placed in /home/user_you/.config/testSQLPostgres_on_elite.cnf
+###
+<<@<@HISTORY_HOSTS>
+user_you@192.168.1.20
+user_you@file_server
+user_you@perl2.lifelog.hopto.org
+>>
+
+As in this file tests/testSQLPostgres_on_elite.pl
+There is:
+/**
+ * Load and ~/.config/this_script_name.cnf
+ **/
+<<<FILE $0>>>
+
+
+)
+ }
+
# Following from shell actually due to pipe buffering doesn't work to give unique entries counted:
# my $list = `ssh will\@elite "cat ~/.bash_history" | awk '{print \$0}' | sort | uniq -c -u | sort -nr`;# |head -n 100`;
# So perl here is next to rescue.
- my $list = `ssh will\@elite "cat ~/.bash_history"`;
- my @entries = split ("\n", $list);
- my %hsh;my $ord = 0;
- foreach my $n(@entries){
- $n = encodeQuotes($n);
- my $c = $hsh{$n};
- if($c){
- my @c = @$$c;
- $hsh{$n} = \[++$c[0],$n,$c[2]];
- }else{
- $hsh{$n} = \[1,$n,$ord++];
+ for my $i(0..$#his_hosts){
+ my $host = $his_hosts[$i];
+ my $list = `ssh $host "cat ~/.bash_history"`;
+ my @entries = split ("\n", $list);
+ my %hsh;
+ foreach my $command(@entries){
+ $command = encodeQuotes($command);
+ my $c = $hsh{$command};
+ if($c){
+ my @c = @$$c;
+ $hsh{$command} = \[$command, ++$c[1], $c[2]];
+ }else{
+ $hsh{$command} = \[$command, 1, $ord++];
+ }
}
- }
- my @entries_by_ord;
- foreach my $n(values %hsh){
- my @next = @$$n;
- if(@next){
- my $i = int($next[2]);
- $entries_by_ord[$i] = \[$next[0], $next[1]];
- }else{
- die "What is \@next ? ->".ref($n)
+
+ foreach my $hshval(values %hsh){
+ my @next = @$$hshval;
+ if(@next){ #"COUNT"
+ my $j = int($next[1]);
+ #"ORD" "CMD" "CNY" "HIDX"
+ $entries_by_ord[$next[2]] = \[$next[0], $j, $i];
+ }else{
+ die "What is \@next ? ->".ref($hshval)
+ }
}
}
my $stSelHistCMD = $db->prepare($sel_hist_by_cmd);
my $stSelHistCNT_CMD = $db->prepare($sel_hist_by_cnt);
my $stUpdHistCNT = $db->prepare($upd_hist_cnt);
- my $now = CNFDateTime -> now() -> datetime();
- my ($inserts,$updates, $errors) = (0,0,0);
- # foreach my $next(@entries){
- # my @next = @$next;
-
- foreach my $n(@entries_by_ord){
+
+ foreach my $n(@entries_by_ord){
my @next = @$$n;
my @capture = ($next[1]=~m/^([;:"]+|cd|l|ll)(.*)$/gs);
if(@capture && length($capture[1])<2){
next
}
- $stSelHistCMD->execute($next[1]);
+ $stSelHistCMD->execute($next[0]);
my @check = $stSelHistCMD->fetchrow_array();
if(!@check){
- try{ #"DATE", "CMD", "COUNT"
- $stInsertHist->execute($now, $next[1], $next[0]); $inserts++;
+ try{ #"DATE", "CMD", "COUNT", "HIDX"
+ $stInsertHist->execute($now, $next[0], $next[1], $next[2]); $inserts++;
+ print "."
}catch($e){
- $errors++;
- print $next[1],"\n";
- $cnf->error("Failed to insert: ".decodeQuotes($next[1])." \nError: $e")
+ $errors++;
+ $cnf->warn("Failed to insert: ".decodeQuotes($next[0])." \nError: $e");
}
}else{
- $stSelHistCNT_CMD->execute($next[1], $next[0]);
+ $stSelHistCNT_CMD->execute($next[0], $next[1]);
my @r = $stSelHistCNT_CMD->fetchrow_array();
if(@r){
- $cnf->log("Has entry[$next[0]]:\t".decodeQuotes($next[1]))
+ #$cnf->log("Has entry[$next[0]]:\t".decodeQuotes($next[0]))
+ print "Has entry[$next[1]]:".decodeQuotes($next[0])
}else{
$stSelHistCMD ->execute($next[1]);
@r = $stSelHistCMD->fetchrow_array();
if(@r) {
- #SET "DATE"=?, "COUNT"=? where "ID" =?
- $stUpdHistCNT->execute($now, $next[0], $r[0]); $updates++;
- $cnf->log("Updated entry-> ID:".$r[0]." : ".$r[2]." from ".$r[3]." to count: ".$next[0]." last date: ".$r[1]);
+ #SET "DATE"=?, "COUNT"=?, "HIDX" =? where "ID" =?
+ $stUpdHistCNT->execute($now, $next[1], $next[2], $r[0]); $updates++;
+ $cnf->log("Updated entry-> ID:".$r[0]." : ".$r[2]." from ".$r[3]." to count: ".$next[1]." last date: ".$r[1]);
}
}
}
}
+ print "\n";
$cnf -> log(qq(Table [cmd_history] had: inserts:$inserts updates:$updates errors:$errors));
+ my $pstRows = $cnf->SQL()->selectRecords($db,$SQL_SERVER->{selLongest5CMDs});
+ print "\nID`\tDATE`\t Command\t `Count`Host`LenOfCMD~\n";
+ while (my @next=$pstRows->fetchrow_array()){
+ $selects++;
+ print decodeQuotes( join("` ", @next)),"~\n"
+ }
+ $test->evaluate("5==\$selects",5,$selects);
+
#
$test->done();
#
__DATA__
!CNF3.0
+
// The spaced out data column header and its meta type settings are spaced out,
// bellow for your readability, this is allowed in CNF. not in any other scripted data format.
<!< TASKS <DATA> __SQL_TABLE__ __SQL_PostgreSQL__
"ID" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
"DATE" timestamp without time zone,
"CMD" character varying(2024) COLLATE pg_catalog."default" NOT NULL,
- "COUNT" integer,
+ "COUNT" SMALLINT,
+ "HIDX" SMALLINT DEFAULT 0,
CONSTRAINT cmd_history_pkey PRIMARY KEY ("ID"),
CONSTRAINT "cmd_history_CMD_key" UNIQUE ("CMD")
)
>>
// It is convenient to keep all SQL in CNF here, rather then scattered or repeated through out the perl code.
-<<selectAllFromHist<SQL>select "ID" , "DATE","CMD", "COUNT" from public.cmd_history order by "COUNT" DESC;>>
+<<selectAllFromHist<SQL>select "ID" , "DATE","CMD", "COUNT", "HIDX" from public.cmd_history order by "COUNT" DESC;>>
<<selectHistByCMD<SQL>
-select "ID" , "DATE","CMD", "COUNT" from public.cmd_history
-where "CMD" like ?>>
+select "ID" , "DATE","CMD","COUNT","HIDX" from public.cmd_history
+where "CMD" like ?;
+>>
<<selectHistByCOUNT_AND_CMD<SQL>
-select "ID" , "DATE","CMD", "COUNT" from public.cmd_history where "CMD" like ? and "COUNT" = ?;
+select "ID" , "DATE","CMD", "COUNT", "HIDX" from public.cmd_history
+where "CMD" like ? and "COUNT" = ?;
>>
<<insertHist<SQL>
-INSERT INTO public.cmd_history( "DATE", "CMD", "COUNT" )
- VALUES (?, ?, ?);
+INSERT INTO public.cmd_history( "DATE", "CMD", "COUNT", "HIDX")
+ VALUES (?, ?, ?, ?);
>>
<<updateHistCount<SQL>
UPDATE public.cmd_history
- SET "DATE"=?, "COUNT"=?
+ SET "DATE"=?, "COUNT"=?, "HIDX"=?
WHERE "ID"=?;
+>>
+
+<<selLongest5CMDs<SQL>
+SELECT *, LENGTH("CMD") as len FROM public.cmd_history
+ORDER BY len DESC LIMIT 5;
>>
\ No newline at end of file