diff --git a/metadata/dbms/editrecord.js b/metadata/dbms/editrecord.js
index 8e0a827..0412c88 100644
--- a/metadata/dbms/editrecord.js
+++ b/metadata/dbms/editrecord.js
@@ -102,7 +102,7 @@ class EdtRec
{
field.value=value;
}else{
- console.error('Field "'+propName+'" not found!');
+ log.error('Field "'+propName+'" not found!');
}
}
@@ -1202,8 +1202,9 @@ class EdtRec
applyReq(req,fn,node,xmldoc,win)
{
this.hideProgressBar();
- if (fn==-1) {
- let fullText = findFirstNode(node,'#cdata-section').nodeValue;
+
+ if(node.errorCode>0) {
+ let fullText = node.errorMessage;
let smallText = '';
let pos1=fullText.indexOf('[[');
let pos2=fullText.indexOf(']]');
@@ -1224,7 +1225,9 @@ class EdtRec
else
alert2(trt('Alert'), fullText);
}
- } else
+ return;
+ }
+
if (fn==0) {
this.eRecNo(node,this.record_id);
} else
diff --git a/metadata/dbms/log.js b/metadata/dbms/log.js
new file mode 100644
index 0000000..ec786bd
--- /dev/null
+++ b/metadata/dbms/log.js
@@ -0,0 +1,78 @@
+// Самодельный логгер, почти аналог: https://thecode.media/winston/
+class Log
+{
+ constructor()
+ {
+ this.data = [];
+ this.win = null;
+ }
+ show() {
+ if (this.win != null) this.win.Close();
+
+ this.win = new TWin();
+ this.win.divsh.onclick = null;
+ this.win.shadow = false;
+ //this.win.setParent(this.parent.win);
+ this.win.BuildGUI(10, 10);
+ this.win.setCaption(trt('Log'));
+ this.win.setContent('
');
+ this.win.setSize("600px", "260px");
+ this.win.setCenter();
+ this.win.hide(false);
+
+ this.addLine(true);
+ }
+ hide(){
+ if(this.win!=null) this.win.Close();
+ this.win=null;
+ }
+ addLine(all){
+ if (this.win == null) return;
+ let elem = document.getElementById("log_" + this.win.uid);
+ let i = 0;
+ if(!all) i = this.data.length-1;
+ for (;i < this.data.length;i++) {
+ let div = document.createElement('div');
+ if(this.data[i].p==1){
+ div.style.cssText='color: maroon; width:100%;';
+ }
+ else if(this.data[i].p==2){
+ div.style.cssText='color: green; width:100%;';
+ }
+ else if(this.data[i].p==3){
+ div.style.cssText='color: orange; width:100%;';
+ }
+ else if(this.data[i].p==4){
+ div.style.cssText='color: red; width:100%;';
+ }
+ div.innerHTML = "["+this.data[i].t+"] "+this.data[i].d;
+ elem.appendChild(div);
+ }
+ }
+ getTime(){
+ let data=new Date();
+ return ('0'+data.getHours()).slice(-2)+":"+('0'+data.getMinutes()).slice(-2)+":"+('0'+data.getSeconds()).slice(-2)+":"+('00'+data.getMilliseconds()).slice(-3);
+ }
+ debug(msg){
+ this.data.push({"p":1,"d":msg,"t": this.getTime()});
+ this.addLine(false);
+ }
+ info(msg){
+ this.data.push({"p":2,"d":msg,"t": this.getTime()});
+ this.addLine(false);
+ }
+ warn(msg){
+ this.data.push({"p":3,"d":msg,"t": this.getTime()});
+ this.addLine(false);
+ }
+ error(msg){
+ this.data.push({"p":4,"d":msg,"t": this.getTime()});
+ this.addLine(false);
+ }
+}
+
+var log = new Log();
+/*log.debug("log.debug");
+log.info("log.info");
+log.warn("log.warn");
+log.error("log.error");*/
diff --git a/metadata/dbms/login.js b/metadata/dbms/login.js
index 60500c5..a3ea1fa 100644
--- a/metadata/dbms/login.js
+++ b/metadata/dbms/login.js
@@ -18,12 +18,11 @@ class DBMSUser
applyReq(req,fn,node)
{
- //alert(getXMLNodeSerialisation(node));
this.showShadow(false);
- if (fn==-1)
- {
- alert(findFirstNode(node,'#cdata-section').nodeValue);
- }else
+ if(node.errorCode>0) {
+ alert2(trt('Alert'), node.errorMessage);
+ }
+
if(fn==7)
{
var nCmd=findFirstNode(node, "cmd");
@@ -95,7 +94,7 @@ class DBMSUser
deleteHTML('TWin_CL_'+this.win.uid); //Удаляю кнопку закрыть
this.win.setCaption(trt('Authorization'));
- this.win.setSize("350px","200px");
+ this.win.setSize("350px","184px");
var str='\n\
\n\
diff --git a/metadata/dbms/records.php b/metadata/dbms/records.php
index 4301b88..0fa2d57 100644
--- a/metadata/dbms/records.php
+++ b/metadata/dbms/records.php
@@ -38,13 +38,16 @@
return substr($path,0,$position);
}
- function sendError($e)
- {
- header('Content-type: text/xml');
- header("Cache-Control: no-cache, must-revalidate");
- echo '';
- Exit();
- }
+ function sendError($code, $error)
+ {
+ $obj = new StdClass();
+ $obj->errorCode=$code;
+ $obj->errorMessage=$error;
+ header('Content-Type: application/json');
+ header("Cache-Control: no-cache, must-revalidate");
+ echo json_encode($obj);
+ exit();
+ }
function getSQLValue($t,$v)
{
@@ -174,13 +177,13 @@
}
if($xmls!='')
{
- //sendError("Metadata node \"".$name."\" not find in database!");
+ //sendError(1,"Metadata node \"".$name."\" not find in database!");
$objXMLDocument = new DOMDocument();
try
{
$objXMLDocument->loadXML($xmls);
} catch (Exception $e)
- { sendError($e->getMessage());
+ { sendError(1,$e->getMessage());
}
$currNode=findNodeOnAttribute($objXMLDocument->documentElement, "type","n",$name);
return $currNode;
@@ -191,7 +194,7 @@
function special_handler($exception)
{
- sendError($exception->getMessage());
+ sendError(1,$exception->getMessage());
}
set_exception_handler('special_handler'); //чтоб не пойманные исключения посылались в виде XML
@@ -217,7 +220,7 @@
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e)
- { sendError('Connect error '.$_SERVER['HTTP_HOST'].': "'.$e->getMessage().'"!');
+ { sendError(1,'Connect error '.$_SERVER['HTTP_HOST'].': "'.$e->getMessage().'"!');
}
//Пытаемся автоматически залогинется по GUID из COOKIE (TODO авторизация должна быть в отдельном файле! Смотри директорию password )
@@ -243,7 +246,7 @@
$doc->loadXML($HTTP_INPUT);
} catch (Exception $e)
{
- sendError($e->getMessage());
+ sendError(1,$e->getMessage());
}
$reqNode = $doc->documentElement;
@@ -282,7 +285,7 @@
$allow_upd=false;
$allow_del=false;
$sql_query='select '.$Schema.'p_getaccess(:user_id1,:action_insert) as ins,'.$Schema.'p_getaccess(:user_id2,:action_update) as upd,'.$Schema.'p_getaccess(:user_id3,:action_delete) as del;';
- $stmt = $db->prepare($sql);
+ $stmt = $db->prepare($sql_query);
$stmt->bindValue(':user_id1', $_SESSION['USER_ID'], PDO::PARAM_INT); //getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID'])
$stmt->bindValue(':user_id2', $_SESSION['USER_ID'], PDO::PARAM_INT); //getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID'])
$stmt->bindValue(':user_id3', $_SESSION['USER_ID'], PDO::PARAM_INT); //getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID'])
@@ -324,7 +327,7 @@
Exit();
}else
{
- sendError('Не найден запрошенный узел: "'.$typename.'"!');
+ sendError(1,'Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==1) //вставка записи (результат id записи)
@@ -371,7 +374,7 @@
$path= $_SERVER['DOCUMENT_ROOT'].'/'.findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("path");
@mkdir($path); //Создаём папку если её нет
if(!rename($dir.$flnm, $path.$flnm))
- sendError('Can\'t rename to "'.$path.$v.'"!');
+ sendError(1,'Can\'t rename to "'.$path.$v.'"!');
}
}else
{ $v=getSQLValue($vt, getCdataValue($nodePropData));
@@ -383,7 +386,7 @@
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query); //Потому что PostgreSQL не может хранить id пользователя привязаного к сесии
$stmt = $db->prepare($sql_query);
- if($stmt === false) sendError('Error preparing Statement');
+ if($stmt === false) sendError(1,'Error preparing Statement');
//присваеваем параметрам значения (В записи может быть только 1 двоичное поля см bindParam или сделать несколько переменных)
$nodePropData=$nodeProp->firstChild;
@@ -406,12 +409,15 @@
}
$nodePropData=$nodePropData->nextSibling;
}
-
try
{
$res = $stmt->execute();
} catch (Exception $e)
- { sendError($e->getMessage());
+ {
+ if(str_contains($e->getMessage(), ']]'))
+ sendError(1, $e->getMessage());
+ else
+ sendError(1, '[['.trt("SQL_query_error").']]'.$e->getMessage());
}
$result = $stmt->fetch(PDO::FETCH_NUM);
if($result[0]=='')
@@ -419,7 +425,7 @@
if(strpos($db_connection, 'sqlite')!==false) {
$result[0] = $db->lastInsertId(); //Для SQLite
}else{
- sendError(trt('Failed_to_insert_record').'!');
+ sendError(1,trt('Failed_to_insert_record').'!');
}
}
@@ -430,7 +436,7 @@
Exit();
}else
{
- sendError('Не найден запрошенный узел: "'.$typename.'"!');
+ sendError(1,'Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==2) //редактирование (результат id записи)
@@ -479,8 +485,8 @@
{
$path= $_SERVER['DOCUMENT_ROOT'].'/'.findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("path");
@mkdir($path);//Создаём папку если её нет
- if(!rename($dir.$flnm, $path.$flnm))
- sendError('Can\'t rename to "'.$path.$v.'"!');
+ if(!rename($dir.$flnm, $path.$flnm))
+ sendError(1,'Can\'t rename to "'.$path.$v.'"!');
}
}else
{
@@ -493,9 +499,9 @@
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query); //Потому что PostgreSQL не может хранить id пользователя привязаного к сесии
$sql_query=str_replace('${'.$currNode->getAttribute("ObjectID").'}',getSQLValue(gettype($obj_id),$obj_id),$sql_query); //Так как пока идентификатор базы отдельно передаётся
-//sendError($sql_query);
+//sendError(1,$sql_query);
$stmt = $db->prepare($sql_query);
- if($stmt === false) sendError('Error preparing Statement');
+ if($stmt === false) sendError(1,'Error preparing Statement');
//Присваеваем параметру двоичную информацию (Внимание! Только 1 параметр может быть в 1 записи (почему?))
$pos_v = 0;
@@ -528,7 +534,7 @@
try
{ $res = $stmt->execute();
} catch (Exception $e)
- { sendError($e->getMessage()."\n".$sql_query);
+ { sendError(1,$e->getMessage()."\n".$sql_query);
}
$result = $stmt->fetch(PDO::FETCH_NUM); //$obj_id
if($result[0]==''){ $result[0]=$obj_id; }
@@ -539,7 +545,7 @@
Exit();
}else
{
- sendError('Не найден запрошенный узел: "'.$typename.'"!');
+ sendError(1,'Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==3) //удаление (результат id записи)
@@ -563,7 +569,7 @@
try
{ $res = $db->query($sql_query);
}catch (Exception $e)
- { sendError($e->getMessage());
+ { sendError(1,$e->getMessage());
}
//записываем id удалённой записи для удаления без перезагрузки страницы через javascript
$xmlstring="";
@@ -577,7 +583,7 @@
Exit();
}else
{
- sendError('Не найден запрошенный узел: "'.$typename.'"!');
+ sendError(1,'Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==4 || $fn==11) //взять данные из базы по переданным значениям фильтра ($fn==11 для обновления записи у клиента после вставки или редактировании)
@@ -622,12 +628,12 @@
$sql_query=str_replace('${_order}',findNodeOnAttribute(findFirstNode($currNode,'objects-list'), "column","n",$objListR->getAttribute("order"))->getAttribute("order"),$sql_query);
}else $sql_query=str_replace('${_order}','1',$sql_query);
- //sendError($sql_query);
+ //sendError(1,$sql_query);
//Выполняем запрос
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
- { sendError($e->getMessage().' '.$sql_query);
+ { sendError(1,$e->getMessage().' '.$sql_query);
}
//Формируем ответ
$pagecount=ceil($res->rowCount()/$rowspagecount); //Кол-во страниц
@@ -663,6 +669,7 @@
}
//перебираем RS и строим XML только из тех столбцов которые записанны в секци objects-list поля column в не зависимости от их видимости
+/*
$xmlstring='';
$xmlstring.=''."\n";
$xmlstring.=''."\n";
@@ -708,7 +715,7 @@
$xmlstring.='';
}else
{
- sendError("Column \"".$nextnode->getAttribute("n")."\" not exists in \"$typename\" for select!");
+ sendError(1,"Column \"".$nextnode->getAttribute("n")."\" not exists in \"$typename\" for select!");
}
}
$nextnode = $nextnode->nextSibling;
@@ -717,15 +724,82 @@
}
$res->closeCursor();
$xmlstring.=''."\n";
-
- //sendError('pos1='.$xmlstring);
-
+
header('Content-type: text/xml');
echo $xmlstring;
+*/
+ $obj = new StdClass();
+ $obj->errorCode=0;
+ $obj->errorMessage = '';
+ $obj->fn=$fn;
+ $obj->n=$typename;
+ $obj->pc=$pagecount;
+ $obj->pp=$pagepos;
+ //Перечисляю название выбираемых столбцов через запятую (почему в JAVA версии этого куска кода нет?)
+ $obj->objects_list=[];
+ $nextnode=findNode($currNode,'objects-list')->firstChild;
+ while ($nextnode)
+ {
+ if ($nextnode->nodeName=='column')
+ {
+ array_push($obj->objects_list,$nextnode->getAttribute("n"));
+ }
+ $nextnode = $nextnode->nextSibling;
+ }
+ $obj->data=[];
+
+ $node=findFirstNode($reqNode,'objects-list');
+ $pos=-1;
+ while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
+ {
+ $pos++;
+ if (($pagepos!=-1)&&(($pos<($pagepos*$rowspagecount))||($pos>=$pagepos*$rowspagecount+$rowspagecount))) { continue; }
+
+ array_push($obj->data,new StdClass());
+
+ //разрешать или запрещять редактировать запись надо проверять в хранимке а также запрещять либо разрешать редактировать колонку
+ //для каждой записи формируеться строка настроек со значениями что нужно запретить в таком виде "iuds"
+ $access=''; //u = enable update field, d = enable delete field
+ if(!array_key_exists("_u",$row)) { $access.="u"; } else { $access.=$row["_u"]; }
+ if(!array_key_exists("_d",$row)) { $access.="d"; } else { $access.=$row["_d"]; }
+
+ if(array_key_exists($currNode->getAttribute("ObjectID"),$row)) {
+ end($obj->data)->id=$row[$currNode->getAttribute("ObjectID")];
+ end($obj->data)->a=$access;
+ }else {
+ end($obj->data)->id="";
+ end($obj->data)->a=$access;
+ }
+
+ end($obj->data)->row=[];
+
+ $nextnode=findNode($currNode,'objects-list')->firstChild;
+ while ($nextnode)
+ {
+ if ($nextnode->nodeName=='column')
+ {
+ if(array_key_exists($nextnode->getAttribute("n"),$row))
+ {
+ $field = $nextnode->getAttribute("n");
+ array_push(end($obj->data)->row,$row[$field]);
+ }else
+ {
+ sendError(1,"Column \"".$nextnode->getAttribute("n")."\" not exists in \"$typename\" for select!");
+ }
+ }
+ $nextnode = $nextnode->nextSibling;
+ }
+ }
+ $res->closeCursor();
+
+ header('Content-Type: application/json; charset=utf-8');
+ header("Cache-Control: no-cache, must-revalidate");
+ echo json_encode($obj);
+ exit;
}else
{
- sendError("Не найден запрошеный узел!");
+ sendError(1,"Не найден запрошеный узел!");
}
}else
if ($fn==5) //вернуть клиенту данные по id для редактирования одной записи
@@ -752,16 +826,16 @@
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
}
}
- //sendError($sql_query);
+ //sendError(1,$sql_query);
try
{
$res = $db->query($sql_query);
} catch (Exception $e)
- { sendError($e->getMessage());
+ { sendError(1,$e->getMessage());
}
if(strpos($db_connection, 'sqlite')===false) //Для SQLite не работает rowCount()
{
- if($res->rowCount()!=1) sendError("Количество записей не равно одному!");
+ if($res->rowCount()!=1) sendError(1,"Количество записей не равно одному!");
}
$xmls='';
@@ -772,7 +846,7 @@
}
if($xmls=='')
{
- sendError("Metadata node \"".$name."\" is empty!");
+ sendError(1,"Metadata node \"".$name."\" is empty!");
}
//загружаем мета данные и смотрим какие поля должны передать клиенту
@@ -781,7 +855,7 @@
{
$mdoc->loadXML($xmls);
} catch (Exception $e)
- { sendError($e->getMessage());
+ { sendError(1,$e->getMessage());
}
//находим нужный узел
$node=findNodeOnAttribute($mdoc->documentElement, "type","n",$typename);
@@ -816,7 +890,7 @@
if(array_key_exists($nextnode->getAttribute("cd"), $row)) {
$xmlstring .= 'getAttribute("cd")] . ']]>' . "\n";
}else{
- sendError('Поле "'.$nextnode->getAttribute("cd").'" не найдено в результирующем наборе!');
+ sendError(1,'Поле "'.$nextnode->getAttribute("cd").'" не найдено в результирующем наборе!');
}
}
else {
@@ -824,10 +898,10 @@
}
}else
{
- sendError('Поле "'.$nextnode->getAttribute("n").'" не найдено в результирующем наборе!');
+ sendError(1,'Поле "'.$nextnode->getAttribute("n").'" не найдено в результирующем наборе!');
}
- } catch (Exception $e) { sendError($e->getMessage()); }
+ } catch (Exception $e) { sendError(1,$e->getMessage()); }
}
$nextnode = $nextnode->nextSibling;
}
@@ -853,7 +927,7 @@
$currNode=getMetadataNode($typename);
- if($currNode==null) sendError("Not find \"".$typename."\"!");
+ if($currNode==null) sendError(1,"Not find \"".$typename."\"!");
$objXMLDocument=$currNode->ownerDocument;
$objListR = findFirstNode($tNodeR,'objects-list'); //Из запроса
@@ -884,7 +958,7 @@
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
- { sendError($e->getMessage());
+ { sendError(1,$e->getMessage());
}
//выбираем данные из базы и отправляем клиенту
@@ -903,7 +977,7 @@
$val.=$row[$columns[$i]];
}else
{
- sendError("Column \"$columns[$i]\" not exists in \"$typename\" for select to drop down list!");
+ sendError(1,"Column \"$columns[$i]\" not exists in \"$typename\" for select to drop down list!");
}
}
$xmlstring.='';
@@ -961,7 +1035,7 @@
$html .= '