Все переписано на фасады
This commit is contained in:
132
ContingentParser/Database/Database.php
Normal file
132
ContingentParser/Database/Database.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace ContingentParser\Database;
|
||||
|
||||
use ContingentParser\Logger\DatabaseLogger;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use PDOException;
|
||||
use PDO;
|
||||
|
||||
final class Database
|
||||
{
|
||||
private PDO $_pdo;
|
||||
private static $_logFile = 'log/database.log';
|
||||
private DatabaseConfig $_databaseConfig;
|
||||
private DatabaseLogger $_logger;
|
||||
/**
|
||||
* Конструктор
|
||||
* @param \ContingentParser\Database\DatabaseConfig $config
|
||||
* Конфигурация подключения к базе данных
|
||||
*/
|
||||
public function __construct(DatabaseConfig $config)
|
||||
{
|
||||
$this->_logger = new DatabaseLogger(self::$_logFile);
|
||||
$this->_databaseConfig = $config;
|
||||
try {
|
||||
$dsn = $this->_databaseConfig->getDsn();
|
||||
$username = $this->_databaseConfig->getUsername();
|
||||
$password = $this->_databaseConfig->getPassword();
|
||||
$this->_pdo = new PDO(
|
||||
$dsn,
|
||||
$username,
|
||||
$password,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
$message = "Подключение к {$this->_databaseConfig->getDBName()} успешно!";
|
||||
$this->_logger->log($message);
|
||||
} catch (PDOException $e) {
|
||||
$message = "Ошибка подключения к {$this->_databaseConfig->getDBName()}: {$e->getMessage()}";
|
||||
$this->_logger->log($message);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Сообщение о разрыве соединения
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$message = "Подключение к {$this->_databaseConfig->getDBName()} прервано!";
|
||||
$this->_logger->log($message);
|
||||
}
|
||||
/**
|
||||
* Выборка данных из базы
|
||||
* @param string $sql
|
||||
* SQL-запрос
|
||||
* @param array $params
|
||||
* Параметры запроса
|
||||
* @return array
|
||||
*/
|
||||
public function select(string $sql, array $params = []) : array
|
||||
{
|
||||
try {
|
||||
$stmt = $this->_pdo->prepare($sql);
|
||||
if (!empty($params)) {
|
||||
for ($i = 0; $i < count($params); $i++) {
|
||||
$stmt->bindParam(":v".($i+1), $params[$i]);
|
||||
}
|
||||
}
|
||||
$stmt->execute();
|
||||
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
$message = "Ошибка запроса: " . $e->getMessage();
|
||||
$this->_logger->log($message);
|
||||
} finally {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Добавление данных в базу
|
||||
* @param string $sql
|
||||
* SQL-запрос
|
||||
* @param array $params
|
||||
* Параметры запроса
|
||||
* @return void
|
||||
*/
|
||||
public function insert(string $sql, array $params)
|
||||
{
|
||||
try {
|
||||
$stmt = $this->_pdo->prepare($sql);
|
||||
$count = 1;
|
||||
$size = count($params[0]);
|
||||
foreach ($params as $param) {
|
||||
for ($i = $count; $i <= $size; $i++) {
|
||||
$param = array_values($param);
|
||||
$stmt->bindParam(":v$i", $param[$i-$count]);
|
||||
}
|
||||
$count += count($param);
|
||||
$size += count($param);
|
||||
}
|
||||
$stmt->execute();
|
||||
$this->_logger->log("Запрос выполнен успешно!");
|
||||
} catch (PDOException $e) {
|
||||
$message = "Ошибка запроса:" . $e->getMessage();
|
||||
$this->_logger->log($message);
|
||||
// При ошибке запроса сохраняем валидные данные в yaml-файл
|
||||
if ($e->getCode() === "HY000") {
|
||||
$yaml = Yaml::dump($params);
|
||||
file_put_contents('not-recorded-in-db.yaml', $yaml, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Обновление данных в базе
|
||||
* @param string $sql
|
||||
* SQL-запрос
|
||||
* @param array $params
|
||||
* Параметры запроса
|
||||
* @return void
|
||||
*/
|
||||
public function update(string $sql, array $params)
|
||||
{
|
||||
try {
|
||||
$stmt = $this->_pdo->prepare($sql);
|
||||
$count = count($params);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$stmt->bindParam(":v".($i+1), $params[$i]);
|
||||
}
|
||||
// $stmt->execute();
|
||||
$this->_logger->log("Запрос выполнен успешно!");
|
||||
} catch (PDOException $e) {
|
||||
$message = "Ошибка запроса:" . $e->getMessage();
|
||||
$this->_logger->log($message);
|
||||
}
|
||||
}
|
||||
}
|
62
ContingentParser/Database/DatabaseConfig.php
Normal file
62
ContingentParser/Database/DatabaseConfig.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace ContingentParser\Database;
|
||||
|
||||
final class DatabaseConfig
|
||||
{
|
||||
private string $_driver;
|
||||
private string $_host;
|
||||
private string $_dbname;
|
||||
private string $_port;
|
||||
private string $_charset;
|
||||
private string $_username;
|
||||
private string $_password;
|
||||
|
||||
public function __construct(string $db)
|
||||
{
|
||||
$config = $this->getDataEnv($db);
|
||||
|
||||
$this->_driver = $config['DB_DRIVER'];
|
||||
$this->_host = $config['DB_HOST'];
|
||||
$this->_dbname = $config['DB_NAME'];
|
||||
$this->_port = $config['DB_PORT'];
|
||||
$this->_charset = $config["DB_CHARSET"];
|
||||
$this->_username = $config['DB_USERNAME'];
|
||||
$this->_password = $config['DB_PASSWORD'];
|
||||
}
|
||||
|
||||
private function getDataEnv(string $db) : array
|
||||
{
|
||||
$envVars = parse_ini_file('.env', true);
|
||||
$db = strtoupper($db);
|
||||
$config = [];
|
||||
foreach ($envVars as $dbname => $dbconfig) {
|
||||
if ($dbname == $db) {
|
||||
$config = $dbconfig;
|
||||
}
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function getDBName(): string
|
||||
{
|
||||
return $this->_dbname;
|
||||
}
|
||||
|
||||
public function getDsn() : string
|
||||
{
|
||||
return $this->_driver.":host=".$this->_host
|
||||
.";dbname=".$this->_dbname
|
||||
.";charset=".$this->_charset
|
||||
.";port=".$this->_port;
|
||||
}
|
||||
|
||||
public function getUsername() : string
|
||||
{
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
public function getPassword() : string
|
||||
{
|
||||
return $this->_password;
|
||||
}
|
||||
}
|
214
ContingentParser/Database/DatabaseFacade.php
Normal file
214
ContingentParser/Database/DatabaseFacade.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
namespace ContingentParser\Database;
|
||||
|
||||
use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
|
||||
|
||||
class DatabaseFacade
|
||||
{
|
||||
private GenericBuilder $builder;
|
||||
private Database $opendata;
|
||||
private Database $niimko;
|
||||
private array $specialties;
|
||||
private array $universities;
|
||||
/**
|
||||
* Конструктор
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->niimko = new Database(new DatabaseConfig('niimko'));
|
||||
$this->opendata = new Database(new DatabaseConfig('opendata'));
|
||||
$this->specialties = $this->getSpecialties();
|
||||
$this->universities = $this->getUniversities();
|
||||
}
|
||||
/**
|
||||
* Извлечение URL сайтов из базы данных niimko
|
||||
* @return array
|
||||
*/
|
||||
public function getSitesFromNiimko() : array
|
||||
{
|
||||
/*
|
||||
SELECT kod AS org_id, site FROM niimko.s_vuzes
|
||||
WHERE ootype = 'vuz' AND deleted = 'n' AND fake = 'n'
|
||||
*/
|
||||
$builder = new GenericBuilder();
|
||||
$params = ['vuz', 'n', 'n', 'RU'];
|
||||
$query = $builder->select()
|
||||
->setTable('s_vuzes')
|
||||
->setColumns(['org_id' => 'kod', 'site'])
|
||||
->where('AND')
|
||||
->equals('ootype', 'vuz')
|
||||
->equals('deleted', 'n')
|
||||
->equals('fake', 'n')
|
||||
->equals('country', 'RU')
|
||||
->end();
|
||||
$sql = $builder->write($query);
|
||||
$sites = $this->niimko->select($sql, $params);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
/**
|
||||
* Извлечение сайтов базы данных opendata
|
||||
* из таблицы miccedu_monitoring.
|
||||
* @param array $params
|
||||
* Сайты, у которых устаревшие URL
|
||||
* @return array
|
||||
*/
|
||||
public function getSitesFromMiccedu(array $params) : array
|
||||
{
|
||||
/*
|
||||
SELECT site, vuzkod AS org_id FROM opendata.miccedu_monitoring
|
||||
WHERE year = 2023 AND (vuzkod = :val1 OR vuzkod = :val2 OR ...)
|
||||
*/
|
||||
$builder = new GenericBuilder();
|
||||
$year = 2023;
|
||||
foreach ($params as $key => $org) {
|
||||
$params[$key] = (int)$org['org_id'];
|
||||
}
|
||||
$query = $builder->select()
|
||||
->setTable('miccedu_monitoring')
|
||||
->setColumns(['org_id' => 'vuzkod','site'])
|
||||
->where('AND')
|
||||
->equals('year', $year)
|
||||
->subWhere('OR');
|
||||
foreach ($params as $orgId) {
|
||||
$query->equals('vuzkod', $orgId);
|
||||
}
|
||||
$query = $query->end();
|
||||
$sql = $builder->write($query);
|
||||
array_unshift($params, $year);
|
||||
$sites = $this->opendata->select($sql, $params);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
/**
|
||||
* Внесение данных численности обучающихся в базу данных opendata
|
||||
* @param array $contingent
|
||||
* Массив записей численности по специальностям
|
||||
* @return void
|
||||
*/
|
||||
public function insertContingent(array $contingent) : void
|
||||
{
|
||||
/*
|
||||
INSERT INTO sveden_education_contingent
|
||||
(org_id, spec_id, spec_code, spec_name, edu_level, edu_forms, contingent)
|
||||
VALUES
|
||||
(:v1, :v2, :v3, :v4, :v5, :v6, :v7)
|
||||
...
|
||||
*/
|
||||
$builder = new GenericBuilder();
|
||||
$countAtributes = count($contingent[0]);
|
||||
$size = $countAtributes * (count($contingent) - 1);
|
||||
$query = $builder->insert()
|
||||
->setTable('sveden_education_contingent')
|
||||
->setValues(
|
||||
$contingent[0]
|
||||
);
|
||||
$sql = $builder->write($query);
|
||||
for ($i = $countAtributes; $i <= $size;) {
|
||||
$sql .= " (:v".(++$i).", :v".(++$i).", :v".(++$i).", :v"
|
||||
.(++$i).", :v".(++$i).", :v".(++$i).", :v".(++$i).")\n";
|
||||
}
|
||||
$sql = preg_replace('/\)\s*VALUES\s*/', ') VALUES ', $sql);
|
||||
$sql = preg_replace('/\)\s*\(/', '), (', $sql);
|
||||
$this->opendata->insert($sql, $contingent);
|
||||
}
|
||||
/**
|
||||
* Публичное получение специальностей
|
||||
* @return array
|
||||
*/
|
||||
public function specialties() : array
|
||||
{
|
||||
return $this->specialties ? $this->universities : [];
|
||||
}
|
||||
/**
|
||||
* Публичное получение id вузов, занесенных в базу opendata
|
||||
* @return array
|
||||
*/
|
||||
public function universities() : array
|
||||
{
|
||||
return $this->universities ? $this->specialties : [];
|
||||
}
|
||||
/**
|
||||
* Извлечение кодов специальности из базы данных niimko
|
||||
* @return array
|
||||
*/
|
||||
private function getSpecialties() : array
|
||||
{
|
||||
/*
|
||||
SELECT id AS spec_id, kod AS spec_code FROM niimko.s_specs
|
||||
WHERE oopkodes = 'gos3p'
|
||||
*/
|
||||
$builder = new GenericBuilder();
|
||||
$params = ['gos3p'];
|
||||
$query = $builder->select()
|
||||
->setTable('s_specs')
|
||||
->setColumns(['spec_id' =>'id', 'spec_code' => 'kod'])
|
||||
->where()
|
||||
->equals('oopkodes','gos3p')
|
||||
->end();
|
||||
$sql = $builder->write($query);
|
||||
$specialties = $this->niimko->select($sql, $params);
|
||||
|
||||
return $specialties;
|
||||
}
|
||||
/**
|
||||
* Извлечение id вузов, занесенных в базу opendata
|
||||
* @return array
|
||||
*/
|
||||
private function getUniversities() : array
|
||||
{
|
||||
/*
|
||||
SELECT DISTINCT org_id FROM sveden_education_contingent
|
||||
*/
|
||||
$builder = new GenericBuilder();
|
||||
$query = $builder->select()
|
||||
->setTable('sveden_education_contingent')
|
||||
->setColumns(['org_id'])
|
||||
->where()
|
||||
->greaterThan('org_id', 0)
|
||||
->end();
|
||||
$sql = $builder->write($query);
|
||||
$sql = preg_replace("/ WHERE.*/", '', $sql);
|
||||
$sql = preg_replace('/SELECT/', 'SELECT DISTINCT', $sql);
|
||||
$universities = $this->opendata->select($sql);
|
||||
|
||||
return array_column($universities, 'org_id');
|
||||
}
|
||||
/**
|
||||
* Обновление сайтов в базе данных niimko
|
||||
* @param array $params
|
||||
* Массив [['org_id' => val1, 'site' => val1,],...]
|
||||
* @return void
|
||||
*/
|
||||
public function updateSitesOpendata(array $params) : void
|
||||
{
|
||||
/*
|
||||
UPDATE niimko.s_vuzes
|
||||
SET site = CASE kod
|
||||
WHEN :v1 THEN :v2
|
||||
WHEN :v3 THEN :v4
|
||||
...
|
||||
ELSE kod
|
||||
END
|
||||
WHERE kod IN (:v1, :v2...)
|
||||
*/
|
||||
$count = count($params);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if ($i % 2 == 0) {
|
||||
$params[] = $params[$i];
|
||||
}
|
||||
}
|
||||
$sql = "UPDATE niimko.s_vuzes\nSET site = CASE kod\n";
|
||||
|
||||
for ($i = 0; $i < $count;) {
|
||||
$sql .= "WHEN :v".++$i." THEN :v".++$i."\n";
|
||||
}
|
||||
$sql .= "ELSE kod\nEND\nWHERE kod in(";
|
||||
for ($i = $count++; $i < count($params);) {
|
||||
$sql .= ":v".++$i.",\n";
|
||||
}
|
||||
$sql = rtrim($sql,",\n") .")\n";
|
||||
|
||||
$this->opendata->update($sql, $params);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user