From: Will Budicm Date: Fri, 25 Sep 2020 02:42:41 +0000 (+1000) Subject: dev, into progresDB X-Git-Url: https://lifelog.hopto.org/gitweb/?a=commitdiff_plain;h=9119603b75263270f1cd9768674869dae6e38881;p=LifeLog.git dev, into progresDB --- diff --git a/Installation_ProgresSQL.txt b/Installation_ProgresSQL.txt index 722fb3f..9fabbdc 100644 --- a/Installation_ProgresSQL.txt +++ b/Installation_ProgresSQL.txt @@ -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: +< + +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: - -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. +< +to something like: +< Hope all works for you, and happy logging! diff --git a/dbLifeLog/main.cnf b/dbLifeLog/main.cnf index d87a0e7..63f0241 100644 --- a/dbLifeLog/main.cnf +++ b/dbLifeLog/main.cnf @@ -7,10 +7,16 @@ Credential format:< , don't enable here using AU < # BACKUP_ENABLED -> Enable (1), disable (0) backups to be restored from config page. < -# Default database driver prefix, for SQLite. -< -# Progress DB driver (must have database, the user(alias) and password, pre-created or set) -< +# Default database driver prefix, is SQLite. +< +# ProgresSQL DB driver. Remove -> '!' prefix to tag name, to enable. +< + +# 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. +< + < 00|$RELEASE_VER = 2.1`LifeLog Application Version. 01|$REC_LIMIT = 25`Records shown per page. @@ -52,6 +58,8 @@ Credential format:< , 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; diff --git a/htdocs/cgi-bin/login_ctr.cgi b/htdocs/cgi-bin/login_ctr.cgi index 8bd061d..2cfb331 100755 --- a/htdocs/cgi-bin/login_ctr.cgi +++ b/htdocs/cgi-bin/login_ctr.cgi @@ -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 diff --git a/htdocs/cgi-bin/main.cgi b/htdocs/cgi-bin/main.cgi index 02fa597..b2e836a 100755 --- a/htdocs/cgi-bin/main.cgi +++ b/htdocs/cgi-bin/main.cgi @@ -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, '
dbFile:'.Settings::dbFile()."\n". Dumper(\$sss).'
'; +# 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(
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( my $tfId = 0; my $id = 0; my $log_start = index $sqlVWL, "<="; - my $re_a_tag = qr/.*<\/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>/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( 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)/\2<\/b>
/oi; + $log =~ s/(^\*)(.*)(\*)(\\n)/$2<\/b>
/oi; #Decode escaped \\n $log =~ s/\r\n/
/gs; $log =~ s/\\n/
/gs; @@ -788,8 +795,10 @@ $log_output .= qq(
Category:  -       --Select --       - + +