]> lifelog.hopto.org Git - LifeLog.git/commitdiff
dev, into progresDB
authorWill Budicm <redacted>
Fri, 25 Sep 2020 02:42:41 +0000 (12:42 +1000)
committerWill Budicm <redacted>
Fri, 25 Sep 2020 02:42:41 +0000 (12:42 +1000)
Installation_ProgresSQL.txt
dbLifeLog/main.cnf
htdocs/cgi-bin/login_ctr.cgi
htdocs/cgi-bin/main.cgi
htdocs/cgi-bin/system/modules/Settings.pm
htdocs/cgi-bin/testPGDB.pl [new file with mode: 0644]
htdocs/cgi-bin/wsrc/main.css
htdocs/cgi-bin/wsrc/main.js

index 722fb3f5069119c9a80204ea0e7607abcf30b276..9fabbdcb21e638aa71eac41bedbc4bb2a20d8724 100644 (file)
@@ -1,4 +1,4 @@
-#Install ProgresSQL
+# Install ProgresSQL
 sudo mkdir /usr/include/postgresql
 sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" > \
 /etc/apt/sources.list.d/postgresql.list'
@@ -6,28 +6,42 @@ sudo apt update -y
 sudo apt upgrade -y
 sudo apt install postgresql-12 -y
 
-##Install required libpq-dev to compile test perl driver, later. 
+## Install required libpq-dev to compile test perl driver, later. 
 sudo apt install libpq-dev
 
 ##Install perl driver.
 sudo cpan DBD::Pg;
 
 
+# To assign default postgres user and db
+sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
+sudo -u postgres psql -c "CREATE DATABASE testdb;"
+
+## Start stop ProgresSQL
+sudo service postgresql start
+
 ###manually Obtain dep. if encountering lib problems. with i.e.:
 wget https://apt.postgresql.org/pub/repos/apt/pool/main/p/postgresql-12/libpq-dev_12.4-1.pgdg20.04+1_amd64.deb
 dpkg -i libpq-dev_12.4-1.pgdg20.04+1_amd64.deb
 ###Than run again driver install
 sudo cpan DBD::Pg;
 
-#Notes
+# Notes
+
+ProgresSQL Server is an full database service solution. Handling interaction, like databases, users and backups.
+These all can be handled outside the scope of the LifeLog application.
+However, it is not required or recomended to have an fully managed database system, like this, 
+just to use the LifeLog app.
+
+Modify the following anon property tag in main.cnf to specify:
+<<DBI_DRV_PRFIX<DBI:Pg:host=localhost>
+
+The alias is by default assumed the database name, and the user.
 
-ProgresSQL Server is an full database service solution. So interaction, like databases, users and backups.
-These are all handled outside the scope of the LifeLog application. You will need to set this up,
-prior of using this application. And make an setting in main.cnf that this is handled outside.
-Mainly what driver you are using. In this case it is the ProgresSQL one. Modify the Anon property to say:
-<DBI_DRV_PRFIX<DBI:Pg:host=localhost;dbname=>
-Don't specify the dbname. You don't need to run a schema, as on a new blank database, all will be created.
-The alias is assumed the database name, and the user.
+Modify the following anon property, to have multiple users as aliases loging into same database.
+<<DBI_MULTI_USER_DB<0>
+to something like:
+<<DBI_MULTI_USER_DB<lifelog>
 
 Hope all works for you, and happy logging!
 
index d87a0e76b895a8fdc5827f91e945272edfd71818..63f0241d0f361e22bbad06e0b31f37ed12c4b598 100644 (file)
@@ -7,10 +7,16 @@ Credential format:<<AUTO_LOGIN <{alias}/{password}> , don't enable here using AU
 <<AUTO_LOGIN</>
 # BACKUP_ENABLED -> Enable (1), disable (0) backups to be restored from config page.
 <<BACKUP_ENABLED<1>
-# Default database driver prefix, for SQLite.
-<<DBI_DRV_PRFIX_SQLITE<DBI:SQLite:dbname=>
-# Progress DB driver (must have database, the user(alias) and password, pre-created or set)
-<<DBI_DRV_PRFIX<DBI:Pg:host=localhost;dbname=>
+# Default database driver prefix, is SQLite.
+<<!DBI_SOURCE<DBI:SQLite:>
+# ProgresSQL DB driver. Remove -> '!' prefix to tag name, to enable.
+<<DBI_SOURCE<DBI:Pg:host=localhost;>
+
+# Set folowing to an database name, if multiple aliases connect to a single log database.
+# Users have to be set, and alias is then used for their userid to be able to login.
+# By default this setting is disabled with 0, making alias, its own log database.
+<<DBI_MULTI_USER_DB<0>
+
 <<CONFIG<4>
 00|$RELEASE_VER = 2.1`LifeLog Application Version.
 01|$REC_LIMIT   = 25`Records shown per page.
@@ -52,6 +58,8 @@ Credential format:<<AUTO_LOGIN <{alias}/{password}> , don't enable here using AU
 NOTES|DROP TABLE NOTES;' ver. 1.5 fts4 virtual tables have been scratched as they require special SQLite compilation.
 LOG<5>|Run Query ' ver. 1.5
 
+## Following are historical migration changes.
+
 //ALTER TABLE LOG RENAME AMMOUNT TO AMOUNT;
 
 CREATE TABLE life_log_temp_table AS SELECT * FROM LOG;
index 8bd061d14641d54a66fd50fa6337b948fe6c271a..2cfb331afaa5884a2eba68dd8fcde5aaaebb19bb 100755 (executable)
@@ -112,7 +112,8 @@ sub processSubmit {
             if(&checkCreateTables()==0){
                 $session->param('alias', $alias);
                 $session->param('passw', $passw);
-                $session->param('database', 'data_'.$alias.'_log.db');
+                $session->param('db_source', Settings::dbSrc());
+                $session->param('database',  Settings::dbFile());                
                 $session->flush();
                 ### To MAIN PAGE
                 print $cgi->header(-expires=>"0s", -charset=>"UTF-8", -cookie=>$cookie, -location=>"main.cgi");
@@ -148,8 +149,8 @@ sub checkAutologinSet {
                 if($v){ @cre = split '/', $v; next}
                 $v = parseAutonom('BACKUP_ENABLED',$line);
                 if($v){ $BACKUP_ENABLED = $v; next}
-                $v = parseAutonom('DBI_DRV_PRFIX',$line);
-                if($v){Settings::DBIPrefix($v); next} 
+                $v = parseAutonom('DBI_SOURCE',$line);
+                if($v){Settings::dbSrc($v); next} 
                 last if parseAutonom('CONFIG',$line); #By specs the config tag, is not an autonom, if found we stop reading. So better be last one spec. in file.
     }
     close $fh;
@@ -172,18 +173,68 @@ sub checkAutologinSet {
 
 }
 
+sub checkPreparePGDB {
+    my $create =1;
+    $passw = $cgi->param('passw'); #PG handles password encryption itself.
+    my @data_sources = DBI->data_sources("Pg");
+    foreach my $ln (@data_sources){
+            my $i = rindex $ln, '=';
+            my $n = substr $ln, $i+1;
+            if($n eq $alias){ $create = 0; last;}
+    }
+    if($create){
+        my $db = DBI->connect("dbi:Pg:dbname=postgres");
+        Settings::debug(1);
+        $db->do(qq(
+            CREATE ROLE $alias WITH
+                LOGIN
+                SUPERUSER
+                CREATEDB
+                CREATEROLE
+                INHERIT
+                NOREPLICATION
+                CONNECTION LIMIT -1
+                PASSWORD '$passw';
+        ));
+        $db->do(qq(
+            CREATE DATABASE $alias
+                WITH 
+                OWNER = $alias
+                ENCODING = 'UTF8'
+                LC_COLLATE = 'en_AU.UTF-8'
+                LC_CTYPE = 'en_AU.UTF-8'
+                TABLESPACE = pg_default
+                CONNECTION LIMIT = -1;
+        ));
+        $db->disconnect(); undef $db;
+    }
+    return Settings::connectDB($alias, $passw) if !$db; 
+}
+
 sub checkCreateTables {
 
     my $today = DateTime->now;
        $today-> set_time_zone( &Settings::timezone );
     my ($pst, $sql,$rv, $changed) = 0;
-    $db = Settings::connectDB($alias, $passw) if !$db; 
+    
     # We live check database for available tables now only once.
     # If brand new database, this sill returns fine an empty array.
-    $pst = Settings::selectRecords($db,"SELECT name FROM sqlite_master WHERE type='table' or type='view';");
     my %curr_tables = ();
-    while(my @r = $pst->fetchrow_array()){
-        $curr_tables{$r[0]} = 1;
+
+    if(Settings::isProgressDB()){
+        $db = checkPreparePGDB();
+        my @tbls = $db->tables(undef, 'public');
+        foreach (@tbls){
+            my $t = uc substr($_,7);
+            $curr_tables{$t} = 1;
+        }
+    }
+    else{
+        $db = Settings::connectDB($alias, $passw) if !$db; 
+        $pst = Settings::selectRecords($db,"SELECT name FROM sqlite_master WHERE type='table' or type='view';");        
+        while(my @r = $pst->fetchrow_array()){
+            $curr_tables{$r[0]} = 1;
+        }
     }
     if($curr_tables{'CONFIG'}) {
         #Set changed if has configuration data been wiped out.
@@ -192,7 +243,7 @@ sub checkCreateTables {
     else{
         #v.1.3 -> v.1.4
         #has alter table CONFIG add DESCRIPTION VCHAR(128);
-        $rv = $db->do(&Settings::createCONFIGStmt);
+        $rv = $db->do(Settings::createCONFIGStmt());
         $changed = 1;
     }
     # Now we got a db with CONFIG, lets get settings from there.
@@ -351,7 +402,7 @@ sub checkCreateTables {
         #It is also good to run db fix (config page) to renum if this is an release update?
         #Release in software might not be what is in db, which counts.
         #This here next we now update.
-        my @r = Settings::selectRecords($db, 'SELECT ID, VALUE FROM CONFIG WHERE NAME IS "RELEASE_VER";')->fetchrow_array();
+        my @r = Settings::selectRecords($db, 'SELECT ID, VALUE FROM CONFIG WHERE NAME LIKE \'RELEASE_VER\';')->fetchrow_array();
         my $did = $r[0];
         my $dnm = $r[1];
         my $cmp = $dnm eq $SCRIPT_RELEASE;
@@ -401,7 +452,7 @@ sub populate {
              @lines  = split '\n', $content;
     close $fh;
 
-    my $insConfig = $db->prepare('INSERT INTO CONFIG VALUES (?,?,?,?)');
+    my $insConfig = $db->prepare('INSERT INTO CONFIG (NAME,VALUE,DESCRIPTION) VALUES (?,?,?)');
     my $insCat    = $db->prepare('INSERT INTO CAT VALUES (?,?,?)');
                     $db->begin_work();
     foreach my $line (@lines) {
@@ -426,13 +477,14 @@ sub populate {
                                                                     if($vars{$id}){
 $err .= "UID{$id} taken by $vars{$id}-> $line\n";
                                                                     }
-                                                                    else{
-                                                                            my $st = $db->prepare("SELECT rowid FROM CONFIG WHERE NAME LIKE '$name';");
-                                                                                $st->execute();
-                                                                                $inData = 1;
-                                                                                if(!$st->fetchrow_array()) {
-                                                                                      $insConfig->execute($id,$name,$value,$tick[1]);
-                                                                                }
+                                                                    else{                                                                            
+                                                                            my @arr = Settings::selectRecords($db,"SELECT ID FROM CONFIG WHERE NAME LIKE '$name';")->fetchrow_array();                                                                                 
+                                                                            $inData = 1;                                                                                
+                                                                            if(!@arr) {
+                                                                                $debug .= "conf.ins->".$name.",".$value.",".$tick[1]."\n";
+                                                                                $insConfig->execute($name,$value,$tick[1]);
+                                                                            }
+                                                                                
                                                                     }
                                                                 }
                                                         }else{
@@ -451,6 +503,7 @@ $err .= "Invalid, spec'd entry -> $line\n";
                                                                         # Then check if the  ID is available. If not just skip, the import. Reseting can fix that latter.
                                                                         if(!Settings::selectRecords($db, "SELECT ID FROM CAT WHERE NAME LIKE '$pair[1]';")->fetchrow_array()) {
                                                                             if(!Settings::selectRecords($db, "SELECT ID FROM CAT WHERE ID = $pair[0];")->fetchrow_array()){
+                                                                                $debug .= "cat.ins->".$pair[0].",".$pair[1].",".$tick[1]."\n";
                                                                                $insCat->execute($pair[0],$pair[1],$tick[1]);
                                                                             }
                                                                         }
@@ -494,10 +547,10 @@ sub logout {
     try{
         $alias = $session->param('alias');
         $passw = $session->param('passw');
-        my $database = &Settings::logPath.'data_'.$alias.'_log.db';
-        my $dsn= "DBI:SQLite:dbname=$database";
-        my $db = DBI->connect($dsn, $alias, $passw, { RaiseError => 1 })
-                    or LifeLogException->throw($DBI::errstri);
+        Settings::dbSrc( $session->param('db_source'));
+        Settings::dbFile($session->param('database'));
+
+        my $db = Settings::connectDB($alias, $passw);
         Settings::toLog($db, "Log properly loged out by $alias.");
         $db->disconnect();
     }catch{
@@ -539,5 +592,5 @@ sub logout {
 
     exit;
 }
-
+1;
 ### CGI END
index 02fa5970fc37f5d26f0ad3ec833835c327341617..b2e836a91d63435656fa1b0312c35177bfda38b4 100755 (executable)
@@ -33,22 +33,29 @@ $CGI::POST_MAX = 1024 * 1024 * 5;  # max 5GB file post size limit.
 my $cgi = CGI->new;
 my $sss = new CGI::Session( "driver:File", $cgi, { Directory => &Settings::logPath } );
 my $sid      = $sss->id();
-my $dbname   = $sss->param('database');
-my $userid   = $sss->param('alias');
-my $password = $sss->param('passw');
+
+my $alias   = $sss->param('alias');
+my $passw    = $sss->param('passw');
 my $sssCDB   = $sss->param('cdb');
 my $vmode;
 
-if ( !$userid || !$dbname ) {
+Settings::dbSrc( $sss->param('db_source'));
+Settings::dbFile($sss->param('database'));
+use Data::Dumper;
+
+
+if ( !$alias ||  !$passw) {
     print $cgi->redirect("login_ctr.cgi?CGISESSID=$sid");
     exit;
 }
-my $db       = Settings::connectDB($userid, $password);
+# print $cgi->header, '<pre>dbFile:'.Settings::dbFile()."\n". Dumper(\$sss).'</pre>';
+# exit;
+my $db = Settings::connectDB($alias, $passw);
 my ( $imgw, $imgh );
 #Fetch settings
  Settings::getConfiguration($db);
  Settings::getTheme();
-### Authenticate sss to alias password
+### Authenticate sss to alias passw
     &authenticate;
 #
 my $log_rc      = 0;
@@ -214,7 +221,7 @@ else {    #defaults
 
 my $st;
 my $sqlCAT = "SELECT ID, NAME, DESCRIPTION FROM CAT ORDER BY ID;";
-my $sqlVWL = "$stmS STICKY = 1 $stmE";
+my $sqlVWL = "$stmS STICKY = true $stmE";
 
 toBuf ("## Using db ->". Settings::dsn(). "\n") if $DEBUG;
 
@@ -303,7 +310,7 @@ qq(<FORM id="frm_log" action="data.cgi" onSubmit="return formDelValidation();">
 
         if (@keywords) {
             foreach (@keywords) {
-                $stmS .= " LOWER(LOG) REGEXP '\\b" . lc $_ . "\\b'";
+                if(Settings::isProgressDB()){$stmS .= " LOWER(LOG) ~ '" . lc $_ . "'"}else{$stmS .= " LOWER(LOG) REGEXP '\\b" . lc $_ . "\\b'"}
                 if ( \$_ != \$keywords[-1] ) {
                     $stmS = $stmS . " OR ";
                 }
@@ -371,8 +378,8 @@ qq(<FORM id="frm_log" action="data.cgi" onSubmit="return formDelValidation();">
     my $tfId      = 0;
     my $id        = 0;
     my $log_start = index $sqlVWL, "<=";
-    my $re_a_tag  = qr/<a\s+.*?>.*<\/a>/si;
-    my $isInViewMode = rindex ($sqlVWL, 'PID<=') > 0 || rindex ($sqlVWL, 'ID_CAT=') > 0 || $prm_aa || rindex ($sqlVWL, 'REGEXP')>0 || $prm_rtf;
+    my $re_a_tag  = qr/<a\s+.*?>.*<\/a>/si; my $regex = 'REGEXP'; $regex = ') ~' if Settings::isProgressDB();
+    my $isInViewMode = rindex ($sqlVWL, 'PID<=') > 0 || rindex ($sqlVWL, 'ID_CAT=') > 0 || $prm_aa || rindex ($sqlVWL, $regex)>0 || $prm_rtf;
 
     toBuf $cgi->pre("###[Session PARAMS->isV:$isInViewMode|vc=$prm_vc|xc=$prm_xc|aa: $prm_aa|xc_lst=$prm_xc_lst|\@xc_lst=@xc_lst|vrtf=$prm_rtf|keepExcludes=".&Settings::keepExcludes."] -> ".$sqlVWL) if $DEBUG;
 
@@ -401,7 +408,7 @@ qq(<FORM id="frm_log" action="data.cgi" onSubmit="return formDelValidation();">
     buildLog(traceDBExe($sqlVWL));
     #Following is saying is in page selection, not view selection, or accounting on type of sticky entries.
     if( !$isInViewMode && !$prm_vc  && !$prm_xc && !$rs_keys && !$rs_dat_from ){
-        $sqlVWL = "$stmS STICKY != 1 $stmE";
+        $sqlVWL = "$stmS STICKY = false $stmE";
         toBuf $cgi->pre("###2 -> ".$sqlVWL)  if $DEBUG;
         ;
         &buildLog(traceDBExe($sqlVWL));
@@ -416,7 +423,7 @@ sub traceDBExe {
            $st -> execute() or LifeLogException->throw("Execute failed [$DBI::errstri]", show_trace=>1);
         return $st;
     }catch{
-       LifeLogException->throw(error=>"Database error encountered.", show_trace=>1);
+       LifeLogException->throw(error=>"DSN: [".Settings::dsn()."] Error encountered -> $@", show_trace=>1);
     }
 }
 
@@ -602,7 +609,7 @@ sub buildLog {
             $tagged = 1;
         }
         #bold on start markup
-        $log =~ s/(^\*)(.*)(\*)(\\n)/<b>\2<\/b><br>/oi;
+        $log =~ s/(^\*)(.*)(\*)(\\n)/<b>$2<\/b><br>/oi;
         #Decode escaped \\n
         $log =~ s/\r\n/<br>/gs;
         $log =~ s/\\n/<br>/gs;
@@ -788,8 +795,10 @@ $log_output .= qq(<form id="frm_srch" action="main.cgi"><TABLE class="tbl" borde
 
             </td>
                        <td style="text-align:top; vertical-align:top">Category:&nbsp;
-            <span id="lcat" class="ui-button">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i><font size=1>--Select --</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</i></span>
-                <button class="bordered" data-dropdown="#dropdown-standard">&#171;</button>
+            
+                <button data-dropdown="#dropdown-standard">
+                <span id="lcat" class="ui-button">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i><font size=1>--Select --</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</i></span>                
+               &nbsp; &#171;</button>
 
             <div class="dropdown-menu dropdown-anchor-top-right dropdown-has-anchor" id="dropdown-standard">
                         <table class="tbl">$td_cat</table>
@@ -1061,7 +1070,7 @@ try {
                 toBuf $stm if $DEBUG;
                 #
 
-                my $dbUpd = DBI->connect(Settings::dsn(), $userid, $password, { RaiseError => 1 } )  or LifeLogException->throw("Execute failed [$DBI::errstri]");
+                my $dbUpd = Settings::connectDB($alias, $passw);#@  or LifeLogException->throw("Execute failed [$DBI::errstri]");
                 traceDBExe($stm);
                 return;
             }
@@ -1098,7 +1107,7 @@ try {
 
                     }
 
-                    $sqlVWL = qq($stmS PID<=$rs_cur and STICKY!=1 $sand $stmE);
+                    $sqlVWL = qq($stmS PID<=$rs_cur and STICKY=false $sand $stmE);
                     return;
                 }
             }
@@ -1122,6 +1131,7 @@ try {
                     return;
                 }
                 if ($dtCur > $dt){$sticky = 1; toBuf $cgi->p("<b>Insert forced to be sticky, it is in the past!</b>");}
+                $sticky=castToBool($sticky);
                 $stm = qq(INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY) VALUES ($cat,$rtf,'$date','$log',$am,$af,$sticky););
                 $st = traceDBExe($stm);
                 if($sssCDB){
@@ -1230,16 +1240,16 @@ my $dbg = qq(--DEBUG OUTPUT--\n
 sub authenticate {
     try {
 
-        my $st = traceDBExe("SELECT alias FROM AUTH WHERE alias='$userid' and passw='$password';");
+        my $st = traceDBExe("SELECT alias FROM AUTH WHERE alias='$alias' and passw='$passw';");
         my @c = $st->fetchrow_array();
-        if (@c && $c[0] eq $userid ) { return; }
+        if (@c && $c[0] eq $alias ) { return; }
 
         #Check if passw has been wiped for reset?
-        $st = traceDBExe("SELECT * FROM AUTH WHERE alias='$userid';");
+        $st = traceDBExe("SELECT * FROM AUTH WHERE alias='$alias';");
         @c = $st->fetchrow_array();
         if ( @c && $c[1] == "" ) {
-            #Wiped with -> UPDATE AUTH SET passw='' WHERE alias='$userid';
-            $st = traceDBExe("UPDATE AUTH SET passw='$password' WHERE alias='$userid';");
+            #Wiped with -> UPDATE AUTH SET passw='' WHERE alias='$alias';
+            $st = traceDBExe("UPDATE AUTH SET passw='$passw' WHERE alias='$alias';");
             return;
         }
 
@@ -1253,7 +1263,7 @@ sub authenticate {
         );
         if($DEBUG){
                 print $cgi->center(
-                    $cgi->div("<b>Access Denied!</b> alias:$userid pass:$password SQL->SELECT * FROM AUTH WHERE alias='$userid' and passw='$password'; ")
+                    $cgi->div("<b>Access Denied!</b> alias:$alias pass:$passw SQL->SELECT * FROM AUTH WHERE alias='$alias' and passw='$passw'; ")
                 );
         }
         else{
@@ -1524,3 +1534,7 @@ sub outputPage {
     print $BUFFER;
     print $cgi->end_html;
 }
+
+sub castToBool {if(shift){return 'true'}else{return 'false'}}
+
+1;
\ No newline at end of file
index a5d0a279924ca9f4d7dc213ee3cbd96bdc142fd8..fd4dd4837e692d1de69c3c9e2c6c908085d088d4 100644 (file)
@@ -36,10 +36,10 @@ our $THEME        = 'Standard';
 our $TRACK_LOGINS = 1;
 our $KEEP_EXCS    = 0;
 our $COMPRESS_ENC = 0; #HTTP Compressed encoding.
-our $DBI_DRV_PRFIX= "DBI:SQLite:dbname=";
+our $DBI_SOURCE   = "DBI:SQLite:";
 our $DSN;
 our $DBFILE;
-our $IS_PROGRESSDB=0;
+our $IS_PG_DB=0;
 
 
 #Annons here, variables that could be overiden in  code or database, per need.
@@ -81,71 +81,98 @@ sub bgcol          {return $BGCOL}
 sub css            {return $TH_CSS}
 sub compressPage   {return $COMPRESS_ENC}
 sub debug          {my $r = shift; if(!$r){$r = $DEBUG}else{$DEBUG=$r}  return $r}
-sub DBIPrefix      {my $r = shift; if(!$r){$r = $DBI_DRV_PRFIX}else{$DBI_DRV_PRFIX=$r}  return $r}
+sub dbSrc          {my $r = shift; if($r) {$DBI_SOURCE=$r; $IS_PG_DB = 1 if(index (uc $r, 'DBI:PG') ==0)}  
+                    return $DBI_SOURCE}
+sub dbFile         {my $r = shift; if($r) {$DBFILE=$r} return $DBFILE}
 sub dsn            {return $DSN}
-sub dbFile         {return $DBFILE}
-
+sub isProgressDB   {return $IS_PG_DB}
 
 
 sub createCONFIGStmt {
 return qq(
     CREATE TABLE CONFIG(
-        ID INT             PRIMARY KEY NOT NULL,
-        NAME VARCHAR(16)      UNIQUE,
-        VALUE VARCHAR(28),
-        DESCRIPTION VARCHAR(128)
+        ID integer NOT NULL UNIQUE GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
+        NAME VARCHAR(16)  UNIQUE,
+        VALUE             VARCHAR(28),
+        DESCRIPTION       VARCHAR(128),
+        PRIMARY KEY(ID)
     );
     CREATE INDEX idx_config_name ON CONFIG (NAME);
 )}
 sub createCATStmt {
-return qq(
+
+if($IS_PG_DB){
+    return qq(    
     CREATE TABLE CAT(
-        ID INT             PRIMARY KEY NOT NULL,
-        NAME                VARCHAR(16),
-        DESCRIPTION         VARCHAR(64)
+        ID INT             GENERATED BY DEFAULT AS IDENTITY,
+        NAME               VARCHAR(16),
+        DESCRIPTION        VARCHAR(225),
+        PRIMARY KEY(ID)
+    );
+    CREATE INDEX idx_cat_name ON CAT (NAME);
+)}
+
+return qq(    
+    CREATE TABLE CAT(
+        ID INT             PRIMARY UNIQUE KEY NOT NULL,
+        NAME               VARCHAR(16),
+        DESCRIPTION        VARCHAR(225)
     );
     CREATE INDEX idx_cat_name ON CAT (NAME);
 )}
 sub createLOGStmt {
-return qq(
+if($IS_PG_DB){
+  return qq(
     CREATE TABLE LOG (
+        ID INT UNIQUE GENERATED ALWAYS AS IDENTITY,
         ID_CAT INT        NOT NULL,
-        ID_RTF INTEGER     DEFAULT 0,
-        DATE   DATETIME    NOT NULL,
-        LOG    VARCHAR (128) NOT NULL,
+        ID_RTF INTEGER    DEFAULT 0,
+        DATE TIMESTAMP    NOT NULL,
+        LOG VARCHAR (128) NOT NULL,
         AMOUNT INTEGER,
         AFLAG INT         DEFAULT 0,
-        STICKY BOOL        DEFAULT 0
+        STICKY BOOL       DEFAULT FALSE,
+        PRIMARY KEY(ID)
+    );)
+} 
+  return qq(
+    CREATE TABLE LOG (
+        ID_CAT INT        NOT NULL,
+        ID_RTF INTEGER    DEFAULT 0,
+        DATE DATETIME     NOT NULL,
+        LOG VARCHAR (128) NOT NULL,
+        AMOUNT INTEGER,
+        AFLAG INT         DEFAULT 0,
+        STICKY BOOL       DEFAULT 0
     );
 )}
 
-#pgSQL -> CREATE TABLE LOG (
-#         ID_CAT INT        NOT NULL,
-#         ID_RTF INTEGER     DEFAULT 0,
-#         DATE   TIMESTAMP    NOT NULL,
-#         LOG    VARCHAR (128) NOT NULL,
-#         AMOUNT INTEGER,
-#         AFLAG INT         DEFAULT 0,
-#         STICKY BOOL       DEFAULT FALSE 
-#     );
-
-
-
 sub createVW_LOGStmt {
+if($IS_PG_DB){
+  return qq(
+    CREATE VIEW VW_LOG AS
+     SELECT *, (select count(ID) from LOG as recount where a.id >= recount.id) as PID
+         FROM LOG as a ORDER BY Date(DATE) DESC;
+    );
+} 
 return qq(
 CREATE VIEW VW_LOG AS
     SELECT rowid as ID,*, (select count(rowid) from LOG as recount where a.rowid >= recount.rowid) as PID
         FROM LOG as a ORDER BY Date(DATE) DESC, Time(DATE) DESC;
 )}
 
-#pgSQL -> CREATE VIEW VW_LOG AS
-    # SELECT ctid as ID,*, (select count(ctid) from LOG as recount where a.ctid >= recount.ctid) as PID
-    #     FROM LOG as a ORDER BY Date(DATE) DESC;
-
-
-
-
 sub createAUTHStmt {
+
+if($IS_PG_DB){
+  return qq(
+    CREATE TABLE AUTH(
+        ALIAS varchar(20)   PRIMARY KEY,
+        PASSW TEXT,
+        EMAIL               varchar(44),
+        ACTION INT
+    );
+    CREATE INDEX idx_auth_name_passw ON AUTH (ALIAS, PASSW);      
+)}
 return qq(
     CREATE TABLE AUTH(
         ALIAS varchar(20)   PRIMARY KEY,
@@ -156,25 +183,28 @@ return qq(
     CREATE INDEX idx_auth_name_passw ON AUTH (ALIAS, PASSW);
 )}
 
-    #pgSQL -> CREATE TABLE AUTH(
-    #     ALIAS varchar(20)   PRIMARY KEY,
-    #     PASSW TEXT,
-    #     EMAIL               varchar(44),
-    #     ACTION INT
-    # );
-    # CREATE INDEX idx_auth_name_passw ON AUTH (ALIAS, PASSW);
 
 
 sub createNOTEStmt {
     return qq(CREATE TABLE NOTES (LID INTEGER PRIMARY KEY NOT NULL, DOC TEXT);)
 }
 sub createLOGCATSREFStmt {
+if($IS_PG_DB){
+return qq(
+    CREATE TABLE LOGCATSREF (
+        LID INTEGER NOT NULL,
+        CID INT NOT NULL,
+               primary key(LID)                
+    );    
+)}
+# CONSTRAINT fk_log  FOREIGN KEY(LID) REFERENCES LOG(ID) ON DELETE CASCADE, 
+# CONSTRAINT fk_cats FOREIGN KEY(CID) REFERENCES CAT(ID) ON DELETE CASCADE 
 return qq(
     CREATE TABLE LOGCATSREF (
         LID INTEGER NOT NULL,
         CID INT NOT NULL,
     FOREIGN KEY (LID) REFERENCES LOG(ID),
-    FOREIGN KEY(CID) REFERENCES CAT(ID)
+    FOREIGN KEY (CID) REFERENCES CAT(ID)
     );
 )}
 
@@ -250,8 +280,6 @@ sub getTheme {
 
 }
 
-
-
 #From v.1.8 Changed
 sub renumerate {
     my $db = shift;
@@ -259,12 +287,12 @@ sub renumerate {
     my $sql;
     selectRecords($db,'CREATE TABLE life_log_temp_table AS SELECT * FROM LOG;');
     #update  notes table with new log id only for reference sake.
-    my $st = selectRecords($db, 'SELECT rowid, DATE FROM LOG WHERE ID_RTF > 0 ORDER BY DATE;');
+    my $st = selectRecords($db, 'SELECT ID, DATE FROM LOG WHERE ID_RTF > 0 ORDER BY DATE;');
     while(my @row =$st->fetchrow_array()) {
         my $sql_date = $row[1];
         #$sql_date =~ s/T/ /;
         $sql_date = DateTime::Format::SQLite->parse_datetime($sql_date);
-        $sql = "SELECT rowid, DATE FROM life_log_temp_table WHERE ID_RTF > 0 AND DATE = '".$sql_date."';";
+        $sql = "SELECT ID, DATE FROM life_log_temp_table WHERE ID_RTF > 0 AND DATE = '".$sql_date."';";
         my @new  = selectRecords($db, $sql)->fetchrow_array();
         if(scalar @new > 0){
              try{#can fail here, for various reasons.
@@ -279,13 +307,13 @@ sub renumerate {
 
     # Delete any possible orphaned Notes records.
     $st->finish();
-    $st = selectRecords($db, "SELECT LID, LOG.rowid from NOTES LEFT JOIN LOG ON
-                                    NOTES.LID = LOG.rowid WHERE LOG.rowid is NULL;");
+    $st = selectRecords($db, "SELECT LID, LOG.ID from NOTES LEFT JOIN LOG ON
+                                    NOTES.LID = LOG.ID WHERE LOG.ID is NULL;");
     while($st->fetchrow_array()) {
         $db->do("DELETE FROM NOTES WHERE LID=".$_[0].";")
     }
     $st->finish();
-    $db->do('DROP TABLE LOG;');
+    $db->do('DROP TABLE LOG CASCADE;');
     $db->do(&createLOGStmt);
     $db->do('INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT,AFLAG,STICKY)
                        SELECT ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY FROM life_log_temp_table ORDER by DATE;');    
@@ -342,7 +370,7 @@ sub toLog {
             }
         }
        $log =~ s/'/''/g;
-       $db->do("INSERT INTO LOG (ID_CAT, DATE, LOG) VALUES($cat,'$stamp', \"$log\");");
+       $db->do("INSERT INTO LOG (ID_CAT, DATE, LOG) VALUES($cat,'$stamp', '$log');");
 }
 
 sub countRecordsIn {
@@ -385,7 +413,7 @@ sub removeOldSessions {
 sub obtainProperty {
     my($db, $name) = @_;
     SettingsException->throw("Invalid use of subroutine obtainProperty($db, $name)", show_trace=>$DEBUG) if(!$db || !$name);
-    my $dbs = selectRecords($db, "SELECT ID, VALUE FROM CONFIG WHERE NAME IS '$name';");
+    my $dbs = selectRecords($db, "SELECT ID, VALUE FROM CONFIG WHERE NAME LIKE '$name';");
     my @row = $dbs->fetchrow_array();
     if(scalar @row > 0){
        return $row[1];
@@ -418,9 +446,9 @@ sub configProperty {
         }
     }
     else{
-        my $dbs = selectRecords($db, "SELECT ID, NAME FROM CONFIG WHERE NAME IS '$name';");
+        my $dbs = selectRecords($db, "SELECT ID, NAME FROM CONFIG WHERE NAME LIKE '$name';");
         if($dbs->fetchrow_array()){
-            $db->do("UPDATE CONFIG SET VALUE = '$value' WHERE NAME IS '$name';");
+            $db->do("UPDATE CONFIG SET VALUE = '$value' WHERE NAME LIKE '$name';");
         }
         else{
             my $sql = "INSERT INTO CONFIG (ID, NAME, VALUE) VALUES ($id, '$name', '$value');";
@@ -440,15 +468,16 @@ sub configProperty {
 
 sub connectDB {
     my ($a,$p) = @_;
-    $DBFILE = $LOG_PATH.'data_'.$a.'_log.db';
-    $DSN= $DBI_DRV_PRFIX.$DBFILE;
-    if (rindex ($DBI_DRV_PRFIX ,'DBI:Pg') ==0) {#progress
-        $DSN=$DBI_DRV_PRFIX.$a; $p=$a;
-        $IS_PROGRESSDB = 1;
+    $DBFILE = $LOG_PATH.'data_'.$a.'_log.db' if(!$DBFILE);    
+    if ($IS_PG_DB)  {
+        $DSN = $DBI_SOURCE .'dbname='.$a; $DBFILE = $a;        
+    }else{
+        $DSN = $DBI_SOURCE .'dbname='.$DBFILE
+    }
+    try{
+        return DBI->connect($DSN, $a, $p, {AutoCommit => 1, RaiseError => 1, PrintError => 0, show_trace=>1});
+    }catch{
+           LifeLogException->throw(error=>"<p>Error->$@</p>",  show_trace=>1);
     }
-    return DBI->connect($DSN, $a, $p, { RaiseError => 1, PrintError => 0})
-                       or LifeLogException->throw(error=>"<p>Error->"& $DBI::errstri &"</p>$!",  show_trace=>1);
 }
-
-
 1;
\ No newline at end of file
diff --git a/htdocs/cgi-bin/testPGDB.pl b/htdocs/cgi-bin/testPGDB.pl
new file mode 100644 (file)
index 0000000..cf0ce52
--- /dev/null
@@ -0,0 +1,90 @@
+use strict;
+use warnings;
+use Exception::Class ('LifeLogException');
+use Syntax::Keyword::Try;
+use CGI;
+use CGI::Session '-ip_match';
+use DBI;
+
+use DateTime;
+use DateTime::Format::SQLite;
+use DateTime::Duration;
+
+# my @data_sources = DBI->data_sources("Pg");
+# foreach (@data_sources){
+#             print $_ ,"\n";
+#         }
+
+# my $db = DBI->connect("DBI:Pg:host=localhost;dbname=admin", "admin", "admin", {AutoCommit => 1, RaiseError => 1, PrintError => 0})
+#                        or LifeLogException->throw(error=>"<p>Error->"& $DBI::errstri &"</p>$!",  show_trace=>1);
+
+#         my @tbls = $db->tables(undef, 'public');
+#         foreach (@tbls){
+#             print uc substr($_,7) ,"\n";
+#         }
+
+#  $db->disconnect();
+
+
+# $db = DBI->connect("dbi:Pg:dbname=postgres", "will", "will69", {AutoCommit => 1, RaiseError => 1, PrintError => 0});
+# $db ->do('drop database from_perl_createdDB');
+# $db ->do('create database from_perl_createdDB');
+# $db->disconnect();
+
+# @data_sources = DBI->data_sources("Pg");
+# foreach (@data_sources){
+#             print $_ ,"\n";
+#         }
+my ($alias,$pass)=("admin3", "admin3");
+
+my $SQL1=<<SQL;
+
+CREATE ROLE $alias WITH
+       LOGIN
+       SUPERUSER
+       CREATEDB
+       CREATEROLE
+       INHERIT
+       NOREPLICATION
+       CONNECTION LIMIT -1
+       PASSWORD '$pass';
+
+GRANT postgres TO $alias;
+SQL
+my $SQL2=<<SQL;
+CREATE DATABASE $alias
+    WITH 
+    OWNER = $alias
+    ENCODING = 'UTF8'
+    LC_COLLATE = 'en_AU.UTF-8'
+    LC_CTYPE = 'en_AU.UTF-8'
+    TABLESPACE = pg_default
+    CONNECTION LIMIT = -1;
+SQL
+
+#print $SQL,"\n";
+
+my $db = DBI->connect("dbi:Pg:dbname=postgres");#", "will", "will69", {AutoCommit => 1, RaiseError => 1, PrintError => 0});
+$db ->do($SQL1);
+$db ->do($SQL2);
+
+my @data_sources = DBI->data_sources("Pg");
+foreach (@data_sources){
+            print $_ ,"\n";
+}
+
+    foreach my $ln (@data_sources){
+            my $i = rindex $ln, '=';
+            my $n = substr $ln, $i+1;
+            print $n,"\n";
+    }
+
+
+ $db->disconnect();
+
+
+  $db = DBI->connect("DBI:Pg:host=localhost;dbname=admin3", "admin3", "admin3", {AutoCommit => 1, RaiseError => 1, PrintError => 0});
+        my @tbls = $db->tables(undef, 'public');
+        foreach (@tbls){
+            print uc substr($_,7) ,"\n";
+        }
\ No newline at end of file
index 1f8ad9ef2bdd02b2dbe1b9d5c0a42644da9ce292..a7cb2365e5b59bf09e37eab192baeb5f3d37bd62 100644 (file)
@@ -288,4 +288,6 @@ a:hover {
 
 .hover{
     background-color: #c0c9c9;
-}
\ No newline at end of file
+}
+
+#lcat{ margin: 0; padding: 5px;}
\ No newline at end of file
index 7d0febf25ad45396408ece29f7e61c785f7ea20d..496a95883deae7639ca80c484df2c8cdcd97c27d 100644 (file)
@@ -207,7 +207,6 @@ function onBodyLoad(toggle, tz, today, expires, rs_cur) {
             pnl.show();
     }
 
-
     $("#dropdown-standard a").click(function(e){
         e.preventDefault();
         var ci = $(event.target).parent(); ci = ci.attr('id');