Первая копия

This commit is contained in:
2020-02-27 00:28:43 +06:00
commit 925cac4752
1125 changed files with 198979 additions and 0 deletions

178
metadata/update/get.php Normal file
View File

@ -0,0 +1,178 @@
<html>
<head>
<title>Синхронизация</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body bgColor="#FFFFDD">
<?php
//Для переодического запрашивания данных с другого сервера и обновления локальной базы
//ini_set('max_execution_time',600);//устанавливаем время работы скрипта
require_once("../include/class_table.php");
require_once("../../config.php");
try
{ $db = new PDO($db_connstr, $db_login, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e)
{ echo 'Ошибка соединения: ' . $e->getMessage();
Exit();
}
echo 'Synchronization started!<br>';
$sql='
select
so.id,
ss.host,
so.obj_name,
so.obj_seq,
so.limit
from
"_SynServices" ss
join "_SynObjects" so on so.synservice_id=ss.id
where
ss.del=false
and so.del=false
and ss.active=true
and extract(epoch from now())-time>interval
order by ss.host, so.sort
';
$res = $db->query($sql);
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$host=$row['host'].'?fn=1&n='.$row['obj_name'].'&s='.$row['obj_seq'].'&l='.$row['limit'];
echo $host.'<br>';
//Не знаю на сколько хорошо работает функция copy но пока ничего лучше ненашел
if(copy( $host, 'data.zip' ))
{
//Извлекаем данные из таблицы если запись существует то обновляем если нет то вставляем
$zip = new ZipArchive();
if ($zip->open('data.zip') !== true)
{
echo $row['name']." ZIP error!";
continue;
}
//Перебираем файлы архива
for($i=0;$i<$zip->numFiles;$i++)
{
$seq=0; //Запишется макс время пришедших данных (потому что данные приходят частями)
$name=$zip->getNameIndex($i);
echo $name.'<br>';
$fp = $zip->getStream($name);
if(!$fp) { continue; }
$tbl= new TCTable('',0);
$tbl->OpenTableH($fp);
//Формируем SQL запрос для обновления записи
$sql='update "'.$tbl->name.'" set ';
for($j=0;$j<count($tbl->fields);$j++)
{
if($tbl->fields[$j]->name!='id') //Первичный ключ
{
$sql.='"'.$tbl->fields[$j]->name.'"=:'.$tbl->fields[$j]->name;
if($j+1!=count($tbl->fields)) { $sql.=', '; } else { $sql.=' '; }
}
}
$sql.='where id=:id;';
$stmtU = $db->prepare($sql);
//Формируем SQL для вставки записей
$sql='insert into "'.$tbl->name.'"(';
for($j=0;$j<count($tbl->fields);$j++)
{
$sql.='"'.$tbl->fields[$j]->name.'"';
if($j+1!=count($tbl->fields)) $sql.=',';
}
$sql.=')values(';
for($j=0;$j<count($tbl->fields);$j++)
{
$sql.=':'.$tbl->fields[$j]->name;
if($j+1!=count($tbl->fields)) $sql.=',';
}
$sql.=');';
$stmtI = $db->prepare($sql);
$db->query('ALTER TABLE "'.$tbl->name.'" DISABLE TRIGGER USER;' ); //Почемуто при вставке тригер срабатывает а при обновлении соответствует условию
while($tbl->ReadNextRecord())
{
$id=$tbl->getRowByName('id')->getValue();
//Проверяем существование записи
//$resE=null;
try
{
$sql2='select true from "'.$tbl->name.'" where id=\''.$id.'\'';
$resE = $db->query( $sql2 );
} catch (Exception $e)
{ echo 'Error SQL: ' . $sql2 . '<br><br>' . $e->getMessage();
$seq--;
break;
}
if($resE->rowCount()>0){ $exist=true; } else { $exist=false; }
if($exist)
{
for($j=0;$j<count($tbl->fields);$j++)
{
//print $tbl->fields[$j]->name.'='.$tbl->fields[$j]->getValue().'<br>';
$stmtU->bindValue(':'.$tbl->fields[$j]->name, $tbl->fields[$j]->getValue(), $tbl->fields[$j]->getPDOType());
}
print '<br>Update ';
try
{ $stmtU->execute();
} catch (Exception $e)
{ echo ' Error SQL id="'.$id.'": ' . $e->getMessage();
$seq--; //Потому что могут идти с одинаковым временем подподрят несколько записей
//break;
}
}else
{
for($j=0;$j<count($tbl->fields);$j++)
{
//print $tbl->fields[$j]->name.'='.$tbl->fields[$j]->getValue().'<br>';
if(!$stmtI->bindValue($tbl->fields[$j]->name, $tbl->fields[$j]->getValue(), $tbl->fields[$j]->getPDOType())) print '<br>Error';
}
print '<br>Insert';
try
{ $stmtI->execute();
} catch (Exception $e)
{ echo ' Error SQL id="'.$id.'": ' . $e->getMessage();
$seq--; //Потому что могут идти с одинаковым временем подподрят несколько записей
//break;
}
}
if($seq<$tbl->getRowByName('seq')->getValue()) { $seq=$tbl->getRowByName('seq')->getValue(); }
}
$db->query('ALTER TABLE "'.$tbl->name.'" ENABLE TRIGGER USER;' );
fclose($fp);
//Обновляем время последнего обновления
if($seq>0)
{
$sql='update "_SynObjects" set "time"=extract(epoch from now()), obj_seq='.$seq.' where id=\''.$row['id'].'\'';
try
{
$db->query($sql);
} catch (Exception $e)
{ echo $e->getMessage().' SQL='.$sql;
Exit();
}
}
}
$zip->close();
echo "<br>ok<br><br>";
}
if(file_exists('data.zip')) { unlink('data.zip'); }
}
?>
</body>
</html>

13
metadata/update/proc.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<!--Хранимые процедуры только выборка-->
<proc n="Cities">
<sql><![CDATA[select * from Cities order by name]]></sql>
</proc>
<!--Под типы учр.-->
<proc n="Business">
<param n="city_id"><![CDATA[]]></param>
<param n="business_id"><![CDATA[]]></param>
<sql><![CDATA[select * from Business where del='f' and city_id=${city_id} and business_id=${business_id}]]></sql>
</proc>
</metadata>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<metadata name="test">
<!--
Отчёт для оформление выборки из базы в виде HTML
Процедуры для выборки находяться в файле proc.xml (копии некоторых серверных SQL процедур)
В програме при выборе элемента вдереве передаёться список параметров, которые взяты из текущего результсета и предназначенны нижнему уровню
Можно было XSL использовать но достойного крос-платформенного не нашлось!
-->
<report n="Institution">
<proc n="Cities"/><!--Процедура для выборки данных-->
<presentation>
<head><![CDATA[
<table id="table0" width="100%" border="0px" cellspacing="1px" cellpadding="2px" bgcolor="#000000" style="border: 0px solid rgb(0, 0, 0);">
<caption></caption>
<thead>
<tr bgcolor="#AAAAFF">
<th width="40%">ПАСПОРТНЫЕ ДАННЫЕ</th>
<th></th>
</tr>
</thead>
<tbody>
]]></head>
<!--строка данных-->
<body><![CDATA[ ]]></body>
<tail><![CDATA[</body></table>]]></tail>
</presentation>
<!--под отчётам доступна информация из верхнего уровня-->
</report>
</metadata>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<servers>
<server host="www.earth.kz" port="80"><![CDATA[Earth.kz]]></server>
<!--server host="213.211.111.18" port="80"><![CDATA[E-Kyzylorda.kz]]></server-->
</servers>

254
metadata/update/set.php Normal file
View File

@ -0,0 +1,254 @@
<? //Отправляет запрошенную таблицу в виде zip архива
/*
$pos=strripos ( $_SERVER['SERVER_NAME'] , '.' , 0 ) - strlen($_SERVER['SERVER_NAME']) - 1;
$pos=strripos ( $_SERVER['SERVER_NAME'] , '.' , $pos );
ini_set('session.cookie_domain', $pos ? substr($_SERVER['SERVER_NAME'],$pos) : '.'.$_SERVER['SERVER_NAME']);
*/
if(isset($_GET[session_name()]) && $_GET[session_name()]!='') //Чтоб сессия переданная гетом была главней
session_id($_GET[session_name()]);
@session_start();
if(isset($_SESSION['REMOTE_ADDR']) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR']) unset($_SESSION["USER_ID"]); //Делаемся не авторизованным если зашли с другого ip адреса
require_once("../include/zip.lib.php");
require_once("../include/class_table.php");
require_once("../../config.php");
function findFirstNode($node, $nodename)
{
$mas=array();
$pos=0;
$mas[$pos] = $node->firstChild;
while ($mas[$pos])
{
if($mas[$pos]->nodeName==$nodename)
{
return $mas[$pos];
}
if($mas[$pos]->firstChild)
{
$pos++;
$mas[$pos]=$mas[$pos-1]->firstChild;
}else
{
while (true)
{
$mas[$pos] = $mas[$pos]->nextSibling;
if (!$mas[$pos])
{
if($pos>0){ $pos--; }else{ break; }
}else
{
break;
}
}
}
}
return '';
}
try
{ $db = new PDO($db_connstr, $db_login, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e)
{ echo 'Ошибка соединения: ' . $e->getMessage();
Exit();
}
if(!isset($_SESSION["USER_ID"])) $_SESSION["USER_ID"]=0;
if(isset($_REQUEST["fn"])) $fn=$_REQUEST["fn"]; else Exit();
if ($fn==0) //Отправить время в секундах с 2000 года
{
$res = $db->query('select "getDate2000"()');
if($row = $res->fetch(PDO::FETCH_NUM)) print $row[0];
exit();
}else
if ($fn==1) //Получить данные заданных полей из таблицы в виде двоичных данных
{
if(isset($_REQUEST["r"])) $r=$_REQUEST["r"]; else $r=0; //id запроса
if(isset($_REQUEST["n"])) $n=$_REQUEST["n"]; //Название таблицы
if(isset($_REQUEST["s"])) $s=$_REQUEST["s"]; else $s=0; //Время с которого надо отправлять клиенту 0 то всё
if(isset($_REQUEST["l"])) $l=$_REQUEST["l"]; else $l=100; //Кол-во записей за раз
//Чтобы не выбирать данные при запросе к таблице с кучей полей
$res = $db->query('select id,seq from "'.$n.'" where seq>'.$s.' order by seq'); //Лимит не применяю чтоб seq не различался
$cnt=0; $seq=-1; $ids='';
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
if($cnt>=$l && $seq!=$row['seq']) break; //Заданное количество записей включая повторы последнего seq
$ids.="'".$row['id']."',";
$seq=$row['seq'];
$cnt++;
}
$ids=rtrim($ids,',');
if($ids=='') { $ids="''"; }
error_log('select * from "'.$n.'" where id in ('.$ids.') order by seq');
$res = $db->query('select * from "'.$n.'" where id in ('.$ids.') order by seq'); //Лимит не применяю чтоб seq не различался
$tbl=new TCTable($n,0);
//Записываем id типов столбцов
for($i=0;$i<$res->columnCount();$i++)
{
$meta = $res->getColumnMeta($i);
$field=new TCField($meta['name'], $meta['native_type']);
$tbl->addField($field);
}
/*
//Оперативка на хостинге не безграничная поэтому в файл сохраняем
$hTable = fopen($n.'.tbl', 'w'); //Таблица
fwrite($hTable, $tbl->getHeader()); //Записываем заголовок таблицы
$cnt=0; $seq=-1;
while ($row = $res->fetch(PDO::FETCH_NUM))
{
if($cnt>=$l && $seq!=$row[$sn]) break; //Заданное количество записей включая повторы последнего seq
$hCol = fopen('col.txt', 'w'); //1 запись таблицы
//подсчитываем пустоту и записываем значения
$null='';
for($i=0;$i<$res->columnCount();$i++)
{
if($tbl->fields[$i]->type==TCField::$BD_BLOB_4) //Двоичные данные
{
if($row[$i]=='')
{ $null.='0';
}else
{
stream_copy_to_stream($row[$i],$hCol);
$null.='1';
}
}else
{
if(fwrite($hCol, $tbl->fields[$i]->pack($row[$i]))>0) $null.='1'; else $null.='0';
}
}
fclose($hCol);
$null.='00000000';
for($i=0;$i<ceil(count($tbl->fields)/8.0);$i++)
{
fwrite($hTable, pack("C",bindec(substr($null,0,8))));
$null=substr($null,8);
}
//Копируем содержимое записи
$hCol = fopen('col.txt', 'r');
stream_copy_to_stream($hCol,$hTable);
fclose($hCol);
unlink('col.txt');
$seq=$row[$sn];
$cnt++;
}
fclose($hTable);
//Зипуем и отправляем клиенту (без поддержки докачки)
$fname = 'data_'.time().'.zip';
$zip = new ZipArchive;
$res = $zip->open($fname, ZipArchive::CREATE);
if ($res === TRUE)
{
$zip->addFile($n.'.tbl');
$zip->close();
unlink($n.'.tbl');
}
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename=data.zip');
readfile($fname);
unlink($fname);
*/
$szRez=''; //Данные из таблицы в двоичном формате
$szRez.=$tbl->getHeader(); //заголовок
while ($row = $res->fetch(PDO::FETCH_NUM))
{
for($i=0;$i<$res->columnCount();$i++)
{
if($tbl->fields[$i]->type==TCField::$BD_BLOB_4) //Двоичные данные
{
if($row[$i]=='') $tbl->fields[$i]->setValue('');
else $tbl->fields[$i]->setValue(stream_get_contents($row[$i]));
}else
$tbl->fields[$i]->setValue($row[$i]);
}
$szRez.=$tbl->getCol();
}
$zipfile = new zipfile();
$zipfile->addFile($szRez, $cnt.'_'.$n.'.tbl');
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename=data.zip');
echo $zipfile->file();
exit();
}
if ($fn==2) //Получить данные заданных полей из таблицы в виде XML
{
if(isset($_REQUEST["r"])) $r=$_REQUEST["r"]; else $r=0; //id запроса
if(isset($_REQUEST["n"])) $n=$_REQUEST["n"]; //Название таблицы
if(isset($_REQUEST["s"])) $s=$_REQUEST["s"]; else $s=0; //Время с которого надо отправлять клиенту 0 то всё
if(isset($_REQUEST["l"])) $l=$_REQUEST["l"]; else $l=100; //Кол-во записей за раз
$res = $db->query('select * from "'.$n.'" where seq>'.$s.' order by seq'); //Лимит не применяю чтоб seq не различался
$xmlString='<?xml version="1.0" encoding="utf-8"?>';
$xmlString.='<metadata>';
/* for($i=0;$i<count($someArray)-1;$i++)
{
$xmlString.='<type n="'.$sub[0].'">';
//названия запишем в строку потом разобьём на массив
$strNames="";
$currNode=findNodeOnAttribute($objXMLDocument->documentElement,'type','n',$sub[0]);
$nodeProperties=findFirstNode($currNode,"properties");
if($nodeProperties!=null)
{
$nodeProp=$nodeProperties->firstChild;
while ($nodeProp != null):
if($nodeProp->nodeName=="prop")
{
$strNames.=$nodeProp->getAttribute("n").';';
}
$nodeProp=$nodeProp->nextSibling;
endwhile;
}
$propNames=split(";", $strNames);
//Сформировали массив названий полей
//проверяем права на чтение записи
$sql->sql_query='select * from "p__Access_4"(-1,-1,\''.$sub[0].'\','.$_SESSION["USER_ID"].');';
$sql->sql_execute();
if((pg_num_rows($sql->sql_res)>0)&&(pg_result($sql->sql_res, $j, "select")=="t"))
{
$sql->sql_query='select * from "p_'.$sub[0].'_5"(0,-1,'.$sub[1].')';
$sql->sql_execute();
$j=0;
while ($j <pg_num_rows($sql->sql_res)) :
$xmlString.='<rec id="'.$sql->sql_result($j,'id').'" del="'.$sql->sql_result($j,'del').'" seq="'.$sql->sql_result($j,'seq').'">';
//перебираем название полй и строим ответ
for($k=0;$k<count($propNames)-1;$k++)
{
$xmlString.='<d><![CDATA['.$sql->sql_result($j,$propNames[$k]).']]></d>'; //гадина java удаляет пустые cdata (поэтому <d>)
}
$xmlString.='</rec>';
$j++;
endwhile;
}
$xmlString.='</type>';
}*/
$xmlString.='</metadata>';
//зипуем xml и отправляем клиенту (без поддержки докачки)
$zipfile = new zipfile();
$zipfile->addFile($xmlString, 'xml.xml');
$binarydata = $zipfile->file();
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename=xml.zip');
echo $binarydata;
exit();
}

86
metadata/update/test.php Normal file
View File

@ -0,0 +1,86 @@
<?php
//Для переодического запрашивания данных с другого сервера и обновления локальной базы
//ini_set('max_execution_time',600);//устанавливаем время работы скрипта
require_once("../include/class_table.php");
require_once("../../config.php");
try
{ $db = new PDO($db_connstr, $db_login, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e)
{ echo 'Ошибка соединения: ' . $e->getMessage();
Exit();
}
/*$res = $db->query('select * from "_Users"');
//Записываем id типов столбцов
for($i=0;$i<$res->columnCount();$i++)
{
$meta = $res->getColumnMeta($i);
print $meta['name'].'='.$meta['native_type'].' ';
}*/
$res0 = $db->query('select ss.id,ss.host from "_SynServices" ss where ss.del=false order by ss.host');
while ($row0 = $res0->fetch(PDO::FETCH_ASSOC))
{
//Так как время может быть различно получаем время с сервера с которого хотим обновится
$time = file_get_contents($row0['host'].'?fn=0');
$sql='select so.id,so.name,so.limit,coalesce(so."time",0) "time","getDate2000"() date2000 from "_SynObjects" so where so.del=false and so.synservice_id=\''.$row0['id'].'\' and '.$time.'-coalesce(so."time",0)>"interval" order by so.sort';
$res1 = $db->query($sql);
while ($row1 = $res1->fetch(PDO::FETCH_ASSOC))
{
$host=$row0['host'].'?fn=1&n='.$row1['name'].'&s='.$row1['time'].'&l='.$row1['limit'];
//Не знаю на сколько хорошо работает функция copy но пока ничего лучше ненашел
if(copy( $host, 'data.zip' ))
{
//Извлекаем данные из таблицы если запись существует то обновляем если нет то вставляем
$zip = new ZipArchive();
if ($zip->open('data.zip') !== true)
{ //fwrite(STDERR, "Error while openning archive file");
echo "ZIP error!";
exit(1);
}
//Перебираем файлы архива
for($i=0;$i<$zip->numFiles;$i++)
{
$time=0; //Запишется макс время пришедших данных (потому что данные приходят частями)
$name=$zip->getNameIndex($i);
//if($name!='2_GoodsImages.tbl') break;
echo '<br>'.$name.'<br>';
$fp = $zip->getStream($name);
/*$fpr = $zip->getStream($name);
$fpw = fopen($name, 'w');
fwrite($fpw, stream_get_contents($fpr));
fclose($fpr);
fclose($fpw);*/
$tbl= new TCTable('',0);
//$tbl->OpenTableF($name);
$tbl->OpenTableH($fp);
while($tbl->ReadNextRecord())
{
for($j=0;$j<count($tbl->fields);$j++)
{
print $tbl->fields[$j]->name.'='.$tbl->fields[$j]->getValue().'<br>';
}
}
//fclose($fp);
}
$zip->close();
}
}
}
?>