Fixes for DB IO, DB general functions, JS core updates

DB IO
- Update/Select/Insert checks are sane now and not reverse
- UPDATE can now use RETURNING
- meta table check in postgresql is supressing warning for not existing
table and just returns false

JS (edit)
- update for the html element creation functions

Basic:
- SITE LANG settings added to change default lang based on vhost
- log file id is now set more lienient via globals and not with a global
constant

DB Tables/Functions:
- fix wrong general function and set uid function was missing
This commit is contained in:
Clemens Schwaighofer
2018-09-27 17:06:32 +09:00
parent b2f5d439d5
commit c6a15506c5
8 changed files with 93 additions and 30 deletions

View File

@@ -3,7 +3,7 @@
CREATE OR REPLACE FUNCTION set_generic() RETURNS TRIGGER AS ' CREATE OR REPLACE FUNCTION set_generic() RETURNS TRIGGER AS '
BEGIN BEGIN
IF TG_OP = ''INSERT'' THEN IF TG_OP = ''INSERT'' THEN
NEW.cuid := random_string(random_length); NEW.date_created := ''now'';
ELSIF TG_OP = ''UPDATE'' THEN ELSIF TG_OP = ''UPDATE'' THEN
NEW.date_updated := ''now''; NEW.date_updated := ''now'';
END IF; END IF;

View File

@@ -0,0 +1,12 @@
-- adds the created or updated date tags
CREATE OR REPLACE FUNCTION set_uid() RETURNS TRIGGER AS '
DECLARE
random_length INT = 12; -- that should be long enough
BEGIN
IF TG_OP = ''INSERT'' THEN
NEW.uid := random_string(random_length);
END IF;
RETURN NEW;
END;
' LANGUAGE 'plpgsql';

View File

@@ -97,6 +97,9 @@ print "DIRECT MULTIPLE INSERT STATUS: $status | PRIMARY KEYS: ".print_r($basic->
// no returning, but not needed ; // no returning, but not needed ;
$status = $basic->dbExec("INSERT INTO foo (test) VALUES ('FOO; TEST ".time()."');"); $status = $basic->dbExec("INSERT INTO foo (test) VALUES ('FOO; TEST ".time()."');");
print "DIRECT INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id." | PRIMARY KEY EXT: ".print_r($basic->insert_id_ext, 1)."<br>"; print "DIRECT INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id." | PRIMARY KEY EXT: ".print_r($basic->insert_id_ext, 1)."<br>";
// UPDATE WITH RETURNING
$status = $basic->dbExec("UPDATE foo SET test = 'SOMETHING DIFFERENT' WHERE foo_id = 3688452 RETURNING test");
print "UPDATE STATUS: $status | RETURNING EXT: ".print_r($basic->insert_id_ext, 1)."<br>";
# db write class test # db write class test
$table = 'foo'; $table = 'foo';

View File

@@ -32,7 +32,7 @@ if ($_SESSION['DEFAULT_CHARSET']) {
if ($_SESSION['DEFAULT_LANG']) { if ($_SESSION['DEFAULT_LANG']) {
$lang = $_SESSION['DEFAULT_LANG']; $lang = $_SESSION['DEFAULT_LANG'];
} elseif (!$lang) { } elseif (!$lang) {
$lang = DEFAULT_LANG; $lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;;
} }
// create the char lang encoding // create the char lang encoding
$lang_short = substr($lang, 0, 2); $lang_short = substr($lang, 0, 2);
@@ -108,8 +108,8 @@ if (!is_dir($cms->cache_pictures)) {
// if the template_dir is != DEFAULT_TEMPLATE, then try to make a lang switch // if the template_dir is != DEFAULT_TEMPLATE, then try to make a lang switch
// if the default lang is not like the lang given, switch lang // if the default lang is not like the lang given, switch lang
if (false === strstr(LAYOUT.DEFAULT_TEMPLATE.LANG, $cms->lang_dir) || strcasecmp(DEFAULT_LANG, $lang)) { if (false === strstr(LAYOUT.DEFAULT_TEMPLATE.LANG, $cms->lang_dir) || strcasecmp(defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;, $lang)) {
$cms->debug('LANG', 'Orig: '.LAYOUT.DEFAULT_TEMPLATE.LANG.', New: '.$cms->lang_dir.' | Orig Lang: '.DEFAULT_LANG.', New Lang: '.$lang); $cms->debug('LANG', 'Orig: '.LAYOUT.DEFAULT_TEMPLATE.LANG.', New: '.$cms->lang_dir.' | Orig Lang: '.(defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;).', New Lang: '.$lang);
$cms->l->l10nReloadMOfile($lang, $cms->lang_dir); $cms->l->l10nReloadMOfile($lang, $cms->lang_dir);
// if we have login class // if we have login class
if ($login) { if ($login) {

View File

@@ -356,9 +356,12 @@ function phfo(tree)
// push finished line // push finished line
content.push(line); content.push(line);
// dive into sub tree to attach sub nodes // dive into sub tree to attach sub nodes
// NOTES: we cannot have content (text) AND sub nodes at the same level // NOTES: we can have content (text) AND sub nodes at the same level
// NODE takes preference over content // CONTENT (TEXT) takes preference over SUB NODE in order
if (tree.sub.length > 0) { if (tree.sub.length > 0) {
if (tree.content) {
content.push(tree.content);
}
tree.sub.each(function(t) { tree.sub.each(function(t) {
content.push(phfo(t)); content.push(phfo(t));
}); });
@@ -416,7 +419,7 @@ function html_options(name, data, selected = '', options_only = false, return_st
} else { } else {
// strip select part // strip select part
if (return_string) { if (return_string) {
element.sub.each(function(t) { element_select.sub.each(function(t) {
content.push(phfo(t)); content.push(phfo(t));
}); });
return content.join(''); return content.join('');

View File

@@ -202,7 +202,14 @@ class Basic
$this->page_name = $this->getPageName(); $this->page_name = $this->getPageName();
$this->host_name = $this->getHostName(); $this->host_name = $this->getHostName();
// init the log file id // init the log file id
$this->log_file_id = defined('LOG_FILE_ID') ? LOG_FILE_ID : ''; // * GLOBALS
// * CONSTANT
// can be overridden with basicSetLogFileId
if (isset($GLOBALS['LOG_FILE_ID'])) {
$this->basicSetLogId($GLOBALS['LOG_FILE_ID']);
} elseif (defined('LOG_FILE_ID')) {
$this->basicSetLogId(LOG_FILE_ID);
}
// set the paths matching to the valid file types // set the paths matching to the valid file types
$this->data_path = array ( $this->data_path = array (
@@ -388,6 +395,22 @@ class Basic
// GENERAL METHODS // GENERAL METHODS
// ************************************************************* // *************************************************************
// METHOD: basicSetLogId
// PARAMS: string
// RETURN: current set string
// DESC : sets the log file prefix id
// must be alphanumeric only (\w)
public function basicSetLogId($string)
{
if (!isset($log_file_id)) {
$log_file_id = '';
}
if (isset($string) && preg_match("/^\w+$/", $string)) {
$this->log_file_id = $string;
}
return $log_file_id;
}
// METHOD: db_io_info // METHOD: db_io_info
// PARAMS: show, default 1, if set to 0 won't write to error_msg var // PARAMS: show, default 1, if set to 0 won't write to error_msg var
// RETURN: string with info // RETURN: string with info

View File

@@ -461,15 +461,15 @@ class IO extends \CoreLibs\Basic
// WAS : _check_query_for_select // WAS : _check_query_for_select
// PARAMS: query // PARAMS: query
// RETURN: true if matching, false if not // RETURN: true if matching, false if not
// DESC : checks if query is a SELECT or SHOW, if not error, 0 return // DESC : checks if query is a SELECT, SHOW or WITH, if not error, 0 return
// NOTE : Query needs to start with SELECT or SHOW. if starts with "with" it is ignored // NOTE : Query needs to start with SELECT, SHOW or WITH. if starts with "with" it is ignored
private function __checkQueryForSelect($query) private function __checkQueryForSelect($query)
{ {
// perhaps allow spaces before select ?!? // perhaps allow spaces before select ?!?
if (!preg_match("/^(select|show|with) /i", $query)) { if (preg_match("/^(select|show|with) /i", $query)) {
return false; return true;
} }
return true; return false;
} }
// METHOD: __checkQueryForInsert // METHOD: __checkQueryForInsert
@@ -481,16 +481,26 @@ class IO extends \CoreLibs\Basic
// NOTE : Queries need to start with INSERT, UPDATE, DELETE. Anything else is ignored // NOTE : Queries need to start with INSERT, UPDATE, DELETE. Anything else is ignored
private function __checkQueryForInsert($query, $pure = false) private function __checkQueryForInsert($query, $pure = false)
{ {
if (!preg_match("/^insert /i", $query) && !preg_match("/^update /i", $query) && !preg_match("/^delete /i", $query)) { if ($pure && preg_match("/^insert /i", $query)) {
return false;
}
if (!$pure) {
return true; return true;
} elseif (preg_match("/^insert /i", $query)) {
return true;
} else {
return false;
} }
if (!$pure && preg_match("/^(insert|update|delete) /i", $query)) {
return true;
}
return false;
}
// METHOD: __checkQueryForUpdate
// PARAMS: query
// RETURN: true if UPDATE, else false
// DESC : returns true if the query starts with UPDATE
// NOTE : query NEEDS to start with UPDATE
private function __checkQueryForUpdate($query)
{
if (preg_match("/^update /i", $query)) {
return true;
}
return false;
} }
// METHOD: __printArray // METHOD: __printArray
@@ -683,15 +693,22 @@ class IO extends \CoreLibs\Basic
$this->query = preg_replace("/(;\s*)$/", '', $this->query); $this->query = preg_replace("/(;\s*)$/", '', $this->query);
$this->query .= " RETURNING ".$this->pk_name; $this->query .= " RETURNING ".$this->pk_name;
$this->returning_id = true; $this->returning_id = true;
} elseif (preg_match("/ returning (.*)/i", $this->query, $matches) && $this->pk_name && $this->pk_name != 'NULL') { } elseif (preg_match("/ returning (.*)/i", $this->query, $matches)) {
// add the primary key if it is not in the returning set if ($this->pk_name && $this->pk_name != 'NULL') {
if (!preg_match("/$this->pk_name/", $matches[1])) { // add the primary key if it is not in the returning set
$this->query .= " , ".$this->pk_name; if (!preg_match("/$this->pk_name/", $matches[1])) {
$this->query .= " , ".$this->pk_name;
}
} }
$this->returning_id = true; $this->returning_id = true;
} }
} }
} }
// if we have an UPDATE and RETURNING, flag for true, but do not add anything
if ($this->__checkQueryForUpdate($this->query) && preg_match("/ returning (.*)/i", $this->query, $matches)) {
$this->returning_id = true;
}
// $this->debug('DB IO', 'Q: '.$this->query.', RETURN: '.$this->returning_id);
// for DEBUG, only on first time ;) // for DEBUG, only on first time ;)
if ($this->db_debug) { if ($this->db_debug) {
$this->__dbDebug('db', $this->query, '__dbPrepareExec', 'Q'); $this->__dbDebug('db', $this->query, '__dbPrepareExec', 'Q');
@@ -752,7 +769,9 @@ class IO extends \CoreLibs\Basic
// if not select do here // if not select do here
// count affected rows // count affected rows
$this->num_rows = $this->db_functions->__dbAffectedRows($this->cursor); $this->num_rows = $this->db_functions->__dbAffectedRows($this->cursor);
if ($this->__checkQueryForInsert($this->query, true) && $this->pk_name != 'NULL') { if (($this->__checkQueryForInsert($this->query, true) && $this->pk_name != 'NULL') ||
($this->__checkQueryForUpdate($this->query) && $this->returning_id)
) {
// set insert_id // set insert_id
// if we do not have a returning, we try to get it via the primary key and another select // if we do not have a returning, we try to get it via the primary key and another select
if (!$this->returning_id) { if (!$this->returning_id) {
@@ -770,14 +789,16 @@ class IO extends \CoreLibs\Basic
// if we have only one, revert from array to single // if we have only one, revert from array to single
if (count($this->insert_id) == 1) { if (count($this->insert_id) == 1) {
// echo "* SINGLE DATA CONVERT: ".count($this->insert_id[0])." => ".array_key_exists($this->pk_name, $this->insert_id[0])."<br>"; // echo "* SINGLE DATA CONVERT: ".count($this->insert_id[0])." => ".array_key_exists($this->pk_name, $this->insert_id[0])."<br>";
// echo "* PK DIRECT: ".$this->insert_id[0][$this->pk_name]."<Br>"; // echo "* PK DIRECT: ".(isset($this->insert_id[0][$this->pk_name]) ? $this->insert_id[0][$this->pk_name] : '[NO PK NAME SET]' )."<Br>";
// if this has only the pk_name, then only return this, else array of all data (but without the position) // if this has only the pk_name, then only return this, else array of all data (but without the position)
// example if insert_id[0]['foo'] && insert_id[0]['bar'] it will become insert_id['foo'] & insert_id['bar'] // example if insert_id[0]['foo'] && insert_id[0]['bar'] it will become insert_id['foo'] & insert_id['bar']
// if only ['foo_id'] and it is the PK then the PK is directly written to the insert_id // if only ['foo_id'] and it is the PK then the PK is directly written to the insert_id
if (count($this->insert_id[0]) > 1 || !array_key_exists($this->pk_name, $this->insert_id[0])) { if (count($this->insert_id[0]) > 1 || !array_key_exists($this->pk_name, $this->insert_id[0])) {
$this->insert_id_ext = $this->insert_id[0]; $this->insert_id_ext = $this->insert_id[0];
$this->insert_id = $this->insert_id[0][$this->pk_name]; if (isset($this->insert_id[0][$this->pk_name])) {
} elseif ($this->insert_id[0][$this->pk_name]) { $this->insert_id = $this->insert_id[0][$this->pk_name];
}
} elseif (isset($this->insert_id[0][$this->pk_name])) {
$this->insert_id = $this->insert_id[0][$this->pk_name]; $this->insert_id = $this->insert_id[0][$this->pk_name];
} }
} elseif (count($this->insert_id) == 0) { } elseif (count($this->insert_id) == 0) {

View File

@@ -350,7 +350,8 @@ class PgSQL
// DESC : wrapper for pg_emta_data // DESC : wrapper for pg_emta_data
public function __dbMetaData($table) public function __dbMetaData($table)
{ {
return pg_meta_data($this->dbh, $table); // needs to prefixed with @ or it throws a warning on not existing table
return @pg_meta_data($this->dbh, $table);
} }
// METHOD: __dbEscapeString // METHOD: __dbEscapeString