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 '
BEGIN
IF TG_OP = ''INSERT'' THEN
NEW.cuid := random_string(random_length);
NEW.date_created := ''now'';
ELSIF TG_OP = ''UPDATE'' THEN
NEW.date_updated := ''now'';
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 ;
$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>";
// 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
$table = 'foo';

View File

@@ -32,7 +32,7 @@ if ($_SESSION['DEFAULT_CHARSET']) {
if ($_SESSION['DEFAULT_LANG']) {
$lang = $_SESSION['DEFAULT_LANG'];
} elseif (!$lang) {
$lang = DEFAULT_LANG;
$lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;;
}
// create the char lang encoding
$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 default lang is not like the lang given, switch lang
if (false === strstr(LAYOUT.DEFAULT_TEMPLATE.LANG, $cms->lang_dir) || strcasecmp(DEFAULT_LANG, $lang)) {
$cms->debug('LANG', 'Orig: '.LAYOUT.DEFAULT_TEMPLATE.LANG.', New: '.$cms->lang_dir.' | Orig Lang: '.DEFAULT_LANG.', New 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: '.(defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;).', New Lang: '.$lang);
$cms->l->l10nReloadMOfile($lang, $cms->lang_dir);
// if we have login class
if ($login) {

View File

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

View File

@@ -202,7 +202,14 @@ class Basic
$this->page_name = $this->getPageName();
$this->host_name = $this->getHostName();
// 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
$this->data_path = array (
@@ -388,6 +395,22 @@ class Basic
// 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
// PARAMS: show, default 1, if set to 0 won't write to error_msg var
// RETURN: string with info

View File

@@ -461,15 +461,15 @@ class IO extends \CoreLibs\Basic
// WAS : _check_query_for_select
// PARAMS: query
// RETURN: true if matching, false if not
// DESC : checks if query is a SELECT or SHOW, if not error, 0 return
// NOTE : Query needs to start with SELECT or SHOW. if starts with "with" it is ignored
// DESC : checks if query is a SELECT, SHOW or WITH, if not error, 0 return
// NOTE : Query needs to start with SELECT, SHOW or WITH. if starts with "with" it is ignored
private function __checkQueryForSelect($query)
{
// perhaps allow spaces before select ?!?
if (!preg_match("/^(select|show|with) /i", $query)) {
return false;
if (preg_match("/^(select|show|with) /i", $query)) {
return true;
}
return true;
return false;
}
// METHOD: __checkQueryForInsert
@@ -481,16 +481,26 @@ class IO extends \CoreLibs\Basic
// NOTE : Queries need to start with INSERT, UPDATE, DELETE. Anything else is ignored
private function __checkQueryForInsert($query, $pure = false)
{
if (!preg_match("/^insert /i", $query) && !preg_match("/^update /i", $query) && !preg_match("/^delete /i", $query)) {
return false;
}
if (!$pure) {
if ($pure && preg_match("/^insert /i", $query)) {
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
@@ -683,15 +693,22 @@ class IO extends \CoreLibs\Basic
$this->query = preg_replace("/(;\s*)$/", '', $this->query);
$this->query .= " RETURNING ".$this->pk_name;
$this->returning_id = true;
} elseif (preg_match("/ returning (.*)/i", $this->query, $matches) && $this->pk_name && $this->pk_name != 'NULL') {
// add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1])) {
$this->query .= " , ".$this->pk_name;
} elseif (preg_match("/ returning (.*)/i", $this->query, $matches)) {
if ($this->pk_name && $this->pk_name != 'NULL') {
// add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1])) {
$this->query .= " , ".$this->pk_name;
}
}
$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 ;)
if ($this->db_debug) {
$this->__dbDebug('db', $this->query, '__dbPrepareExec', 'Q');
@@ -752,7 +769,9 @@ class IO extends \CoreLibs\Basic
// if not select do here
// count affected rows
$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
// if we do not have a returning, we try to get it via the primary key and another select
if (!$this->returning_id) {
@@ -770,14 +789,16 @@ class IO extends \CoreLibs\Basic
// if we have only one, revert from array to single
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 "* 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)
// 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 (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 = $this->insert_id[0][$this->pk_name];
} elseif ($this->insert_id[0][$this->pk_name]) {
if (isset($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];
}
} elseif (count($this->insert_id) == 0) {

View File

@@ -350,7 +350,8 @@ class PgSQL
// DESC : wrapper for pg_emta_data
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