}
}
}
- next if @trans && hasEntry($sqlSEL, \@trans);
+ next if @trans && $self->hasEntry($sqlSEL, \@trans);
}else{
- if ($hasRecords && hasEntry($sqlSEL, $col[0])){ # ID is assumed auto-numbered on by default
+ if ($hasRecords && $self->hasEntry($sqlSEL, $col[0])){ # ID is assumed auto-numbered on by default
$isUpdate = 1;
}
}
$mig{$name} = [@m];
}
sub addStatement { my ($self, $name, $value) = @_;
- $self->{uc $name}=$value;
+ $self->{$name}=$value;
}
-sub getStatement { my ($self, $name) = @_; my $n = uc $name;
- return $self->{$n} if exists $self->{$n};
+sub getStatement { my ($self, $name) = @_;
+ return $self->{$name} if exists $self->{$name};
return;
}
-sub hasEntry{ my ($sqlSEL, $uid) = @_;
+sub hasEntry{ my ($self, $sqlSEL, $uid) = @_;
if(ref($uid) eq 'ARRAY'){
$sqlSEL -> execute(@$uid)
}else{
}
sub selectRecords {
- my ($self, $db, $sql,$dsn) = @_;
+ my ($self, $db, $sql, $dsn) = @_;
if(scalar(@_) < 2){
die "Wrong number of arguments, expecting CNFParser::selectRecords(\$db, \$sql) got Settings::selectRecords('@_').\n";
}
);
try{
+sub encodeQuotes{
+ my $ret = shift; $ret =~ s/\s*$//g;$ret =~ s/\"/\"\"/g; $ret =~ s/\'/\'\'/g;
+ return $ret
+}
+sub decodeQuotes{
+ my $ret = shift; $ret =~ s/\"\"/\"/g; $ret =~ s/\'\'/\'/g;
+ return $ret
+}
+
+
+
die $test->failed() if not $cnf = CNFParser->new(undef,{'%LOG'=>{console=>1}});
$test->case("Passed new instance CNFParser.");
#
$cnf->SQL()->initDatabase($db);
}
+ my $SQL_SERVER = $cnf->SQL();
+ my %schema = $SQL_SERVER->schema();
+ my $tbl_cmd_history_statement = $SQL_SERVER->{cmd_history};
+ my $sql_insert_hist = $SQL_SERVER->{insertHist};
+ my $sel_hist_by_cmd = $SQL_SERVER->{selectHistByCMD};
+ my $sel_hist_by_cnt = $SQL_SERVER->{selectHistByCOUNT_AND_CMD};
+ my $upd_hist_cnt = $SQL_SERVER->{updateHistCount};
+
- my %schema = $cnf->SQL()->schema();
- if(!$schema{CMD_HISTORY}){
- my $tbl_cmd_history_statement = $cnf->SQL()->{CMD_HISTORY};
- $test->fail("SQL Statement for CMD_HISTORY");
- $db ->do($tbl_cmd_history_statement);
+ if(!$schema{CMD_HISTORY}){
+ $cnf->log("Issuing SQL Statement for CMD_HISTORY -> $tbl_cmd_history_statement");
+ $db ->do($tbl_cmd_history_statement);
+ }else{
+ $cnf->warn('Skipping SQL Statement for CMD_HISTORY, table exists!');
+ }
+ # 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++];
+ }
+ }
+ 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)
+ }
+ }
+
+
+ my $stInsertHist = $db->prepare($sql_insert_hist);
+ 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){
+ my @next = @$$n;
+ my @capture = ($next[1]=~m/^([;:"]+|cd|l|ll)(.*)$/gs);
+ if(@capture && length($capture[1])<2){
+ next
+ }
+ $stSelHistCMD->execute($next[1]);
+ my @check = $stSelHistCMD->fetchrow_array();
+ if(!@check){
+ try{ #"DATE", "CMD", "COUNT"
+ $stInsertHist->execute($now, $next[1], $next[0]); $inserts++;
+ }catch($e){
+ $errors++;
+ print $next[1],"\n";
+ $cnf->error("Failed to insert: ".decodeQuotes($next[1])." \nError: $e")
+ }
}else{
- $cnf->warn('Skipping SQL Statement for CMD_HISTORY, table exists!');
+ $stSelHistCNT_CMD->execute($next[1], $next[0]);
+ my @r = $stSelHistCNT_CMD->fetchrow_array();
+ if(@r){
+ $cnf->log("Has entry[$next[0]]:\t".decodeQuotes($next[1]))
+ }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]);
+ }
+ }
}
+ }
+ $cnf -> log(qq(Table [cmd_history] had: inserts:$inserts updates:$updates errors:$errors));
+
#
$test->done();
#
!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__
+<!< TASKS <DATA> __SQL_TABLE__ __SQL_PostgreSQL__
ID _CNF_ID_
`Date _DATE_
`Due _DATE_
#`2023-12-1`2023-12-21`Deploy HSHContact.`0`5~
>>
-<< TASKS_AUTO_VARIANT <DATA> __SQL_TABLE__ __SQL_PostgreSQL__
+<!< TASKS_AUTO_VARIANT <DATA> __SQL_TABLE__ __SQL_PostgreSQL__
ID`Date _DATE_`Due _DATE_
`Task _TEXT_
`Completed _BOOL_
autovacuum_enabled = TRUE
)
TABLESPACE pg_default;
-CREATE INDEX idx_cmd_history_cmd ON public.cmd_history ("CMD");
-
+CREATE INDEX idx_cmd_history_cmd ON public.cmd_history ("CMD");
ALTER TABLE IF EXISTS public.cmd_history
OWNER to tester;
GRANT ALL ON TABLE public.cmd_history TO tester;
+>>
+// 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;>>
+<<selectHistByCMD<SQL>
+select "ID" , "DATE","CMD", "COUNT" 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" = ?;
+>>
+<<insertHist<SQL>
+
+INSERT INTO public.cmd_history( "DATE", "CMD", "COUNT" )
+ VALUES (?, ?, ?);
+
+>>
+<<updateHistCount<SQL>
+UPDATE public.cmd_history
+ SET "DATE"=?, "COUNT"=?
+ WHERE "ID"=?;
>>
\ No newline at end of file