]> lifelog.hopto.org Git - PerlCNF.git/commitdiff
multi-duplicatesimmunity algy.
authorWill Budic <redacted>
Fri, 19 Sep 2025 00:48:11 +0000 (10:48 +1000)
committerWill Budic <redacted>
Fri, 19 Sep 2025 00:48:11 +0000 (10:48 +1000)
system/modules/CNFSQL.pm
tests/testSQLPostgres_on_elite.pl

index efc9307fb0cb429b172230552632f46d603c74ea..3c0f17a1657a11997edca2b1876821d1023b40b7 100644 (file)
@@ -324,9 +324,9 @@ transaction:{
                                 }
                             }
                         }
-                        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;
                       }
                     }
@@ -493,13 +493,13 @@ sub migrate { my ($self, $name, $value) = @_;
         $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{
@@ -573,7 +573,7 @@ sub updateCNFConfigRecord {
 }
 
 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";
     }
index 5b07bbada726c7112ad98193bcaa78f5e62880fb..5ca0fee482bbc38a5d8b03a9e04e6260f395f396 100644 (file)
@@ -21,6 +21,17 @@ my $DB_SETTINGS = qq(
 );
 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.");
            #
@@ -44,16 +55,93 @@ try{
       
       $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();
     #
@@ -76,7 +164,7 @@ __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__
+<!< TASKS <DATA> __SQL_TABLE__   __SQL_PostgreSQL__
 ID  _CNF_ID_
  `Date                                         _DATE_
             `Due                               _DATE_
@@ -88,7 +176,7 @@ ID  _CNF_ID_
 #`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_
@@ -114,13 +202,31 @@ WITH (
     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