upload files into repos

This commit is contained in:
Nikiroy78 2023-03-12 00:31:45 +03:00
parent fecd0c9535
commit e816c73b5e
4 changed files with 318 additions and 41 deletions

20
1.php/index.php Normal file
View File

@ -0,0 +1,20 @@
<?php
error_reporting(E_ERROR | E_PARSE);
include "./logic/mysql-realization.php";
function output () {
$model = new Model(
new RealizationMySQL("127.0.0.1", "root", "root", "realizations-db")
);
$modelElements = $model->getModelElement();
$outputList = array();
foreach ($modelElements as $item) {
$outputList[] = $item['id'] . ' ' . $item['data'];
}
return implode("\n", $outputList);
}
die(output());
?>

75
1.php/logic/model.php Normal file
View File

@ -0,0 +1,75 @@
<?php
class Model {
private $realization;
public function __construct( $realization ) {
$this->realization = $realization;
}
public function getModelElement ($root = null, $stringData = true, $reversiveModelId="") {
$returnValues = array();
$this->realization->ready();
$items = $this->realization->getElement($root);
$logicItemId = 1;
foreach ($items as $item) {
$rootId = $reversiveModelId == "" ? (string)$logicItemId : $reversiveModelId . "." . $logicItemId;
if ($item['isElement'] == false) {
if ($stringData) $returnValues[] = array (
"id" => $rootId,
"data" => $item['stringData']
);
else $returnValues[] = array (
"id" => $rootId,
"data" => $item['data']
);
}
else {
if ($stringData) $returnValues[] = array (
"id" => $rootId,
"data" => $item['stringData']
);
else $returnValues[] = array (
"id" => $rootId,
"data" => $item['data']
);
$childElements = $this->getModelElement(
$item['id'],
$stringData,
$rootId
);
foreach ($childElements as $childElement) {
$returnValues[] = array (
"id" => $childElement['id'],
"data" => $childElement['data']
);
}
}
$logicItemId++;
}
if ($reversiveModelId == "") $this->realization->finish();
return $returnValues;
}
}
abstract class Realization {
public $isReady = false;
public function getElement ($root = null) {
// ... код реализации
}
public function ready () {
if (!$this->isReady) {
$this->isReady = true;
// ... Запрос и запись это в кэш
}
}
public function finish () {
$this->isReady = false;
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
include "model.php";
class RealizationMySQL extends Realization { // Создал класс, наследующий Realization, чтобы можно было выбирать при необходимости между реализациями.
public $isReady = false;
private $db; // Объект базы данных pdo
private $cache = array(); // Тот самый кэш
public function __construct ($host, $user, $pass, $dbname) {
$this->db = new PDO("mysql:host=". $host .";dbname=". $dbname, $user, $pass);
$this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
private function hasLegatees ($elId) { // Метод для определения есть ли у элемента наследники
foreach ($this->cache as $item) {
if ($item['legatee'] == $elId) return true;
}
return false;
}
public function getElement ($root = null) {
$selectedItems = array();
foreach ($this->cache as $item) {
if ($item['legatee'] == $root) {
$selectedItems[] = array(
"isElement" => $this->hasLegatees($item['id']),
"data" => $item['data'],
"stringData" => $item['data'],
"id" => $item['id']
);
}
}
return $selectedItems;
}
public function ready () {
if (!$this->isReady) {
$this->isReady = true;
// Запрос и запись в кэш
$selectedItems = $this->db->query('SELECT * FROM `model-table`');
$selectedItems->setFetchMode(PDO::FETCH_ASSOC);
// Очистим кэш
$this->cache = array();
while($row = $selectedItems->fetch()) {
$this->cache[] = $row;
}
}
}
public function finish () {
$this->isReady = false;
}
}
?>

View File

@ -24,7 +24,7 @@
Поскольку вывод информации происходит из абстрактной модели, нам необходимо сделать собственную реализацию модели. Далее, обеспечить модульность, чтобы можно было менять практическую реализацию модели *(например, заменить запросы к БД на запросы к файловой системе и т.д.)*. Поскольку вывод информации происходит из абстрактной модели, нам необходимо сделать собственную реализацию модели. Далее, обеспечить модульность, чтобы можно было менять практическую реализацию модели *(например, заменить запросы к БД на запросы к файловой системе и т.д.)*.
При разработки модели было принято решение реализовать класс для модели и для её реализации: При разработки модели было принято решение реализовать класс для модели и для её реализации:
```php ```php
class Realization { abstract class Realization {
public function getElement ($root = null) { public function getElement ($root = null) {
// ... код реализации // ... код реализации
/* /*
@ -70,22 +70,20 @@ class Model {
public function getModelElement ($root = null, $stringData = true) { public function getModelElement ($root = null, $stringData = true) {
$returnValues = array(); $returnValues = array();
while (true) { $items = $this->realization->getElement($root);
$items = $this->realization->getElement($root);
foreach ($items as $item) { foreach ($items as $item) {
if ($item->isElement) { if ($item->isElement) {
if ($stringData) $returnValues[] = $item->stringData; if ($stringData) $returnValues[] = $item['stringData'];
else $returnValues[] = $item->data; else $returnValues[] = $item['data'];
} }
else { else {
if ($stringData) $returnValues[] = $item->stringData; if ($stringData) $returnValues[] = $item['stringData'];
else $returnValues[] = $item->data; else $returnValues[] = $item['data'];
$childElements = $this->getModelElement($item->id, $stringData); $childElements = $this->getModelElement($item->id, $stringData);
foreach ($childElements as $childElement) { foreach ($childElements as $childElement) {
if ($stringData) $returnValues[] = $childElements->stringData; $returnValues[] = $childElement['data'];
else $returnValues[] = $childElements->data;
}
} }
} }
} }
@ -95,7 +93,8 @@ class Model {
} }
``` ```
Как можно понять, <Model.object>->getModelElement(); является рекурсивным методом и из этого вытекают как плюсы, так и минусы. Как можно понять, <Model.object>->getModelElement(); является рекурсивным методом и из этого вытекают как плюсы, так и минусы.
Главным минусом является то, что при запросах к БД, у нас вместо одного запроса, который вернёт остальные элементы будет несколько запросов к БД. Поэтому, при первой инициализации экземпляра класса Realization у нас должен происходить только один запрос. В связи с чем, мы меняем код в <Model.object>->getModelElement(); а также его входные параметры. Главным минусом является то, что при запросах к БД, у нас вместо одного запроса, который вернёт остальные элементы будет несколько запросов к БД. Поэтому, при первой инициализации экземпляра класса Realization у нас должен происходить только один запрос. В связи с чем, мы меняем код в <Model.object>->getModelElement(); а также его входные параметры.
Вдобавок ко всему, нам необходимо найти способ индексации элемента, чтобы его индекс был привязан к родительскому элементу.
```php ```php
class Model { class Model {
private $realization; private $realization;
@ -104,30 +103,50 @@ class Model {
$this->realization = $realization; $this->realization = $realization;
} }
public function getModelElement ($root = null, $stringData = true) { public function getModelElement ($root = null, $stringData = true, $reversiveModelId="") {
$returnValues = array(); $returnValues = array();
$this->realization->ready(); $this->realization->ready();
while (true) { $items = $this->realization->getElement($root);
$items = $this->realization->getElement($root);
foreach ($items as $item) { $logicItemId = 1;
if ($item->isElement) { foreach ($items as $item) {
if ($stringData) $returnValues[] = $item->stringData; $rootId = $reversiveModelId == "" ? (string)$logicItemId : $reversiveModelId . "." . $logicItemId;
else $returnValues[] = $item->data; if ($item['isElement'] == false) {
} if ($stringData) $returnValues[] = array (
else { "id" => $rootId,
if ($stringData) $returnValues[] = $item->stringData; "data" => $item['stringData']
else $returnValues[] = $item->data; );
else $returnValues[] = array (
$childElements = $this->getModelElement($item->id, $stringData); "id" => $rootId,
foreach ($childElements as $childElement) { "data" => $item['data']
if ($stringData) $returnValues[] = $childElements->stringData; );
else $returnValues[] = $childElements->data; }
} else {
if ($stringData) $returnValues[] = array (
"id" => $rootId,
"data" => $item['stringData']
);
else $returnValues[] = array (
"id" => $rootId,
"data" => $item['data']
);
$childElements = $this->getModelElement(
$item['id'],
$stringData,
$rootId
);
foreach ($childElements as $childElement) {
$returnValues[] = array (
"id" => $childElement['id'],
"data" => $childElement['data']
);
} }
} }
$logicItemId++;
} }
$this->realization->finish(); if ($reversiveModelId == "") $this->realization->finish();
return $returnValues; return $returnValues;
} }
} }
@ -135,7 +154,7 @@ class Model {
Как мы видим, для класса Realization появились новые методы. Метод ready будет означать, что реализации необходимо совершить запрос и записать его в кэш, чтобы при помощи метода getElement мы могли вместо отправки запросов отправлять нужные данные из кэша. Реализуем это: Как мы видим, для класса Realization появились новые методы. Метод ready будет означать, что реализации необходимо совершить запрос и записать его в кэш, чтобы при помощи метода getElement мы могли вместо отправки запросов отправлять нужные данные из кэша. Реализуем это:
```php ```php
class Realization { abstract class Realization {
public $isReady = false; public $isReady = false;
public function getElement ($root = null) { public function getElement ($root = null) {
@ -145,7 +164,7 @@ class Realization {
public function ready () { public function ready () {
if (!$this->isReady) { if (!$this->isReady) {
$this->isReady = true; $this->isReady = true;
// ... Запрос и запись это в кэш // ... Запрос и запись в кэш
} }
} }
@ -157,17 +176,123 @@ class Realization {
Для метода ready мы реализовали механизм проверки, чтобы кэш не писался несколько раз, поскольку данный метод, в виду рекурсивности метода <Model.object>->getModelElement(), будет вызываться несколько раз. Для метода ready мы реализовали механизм проверки, чтобы кэш не писался несколько раз, поскольку данный метод, в виду рекурсивности метода <Model.object>->getModelElement(), будет вызываться несколько раз.
Теперь ближе к конкретной реализации: будем использовать pdo в нашей реализации. Будем использовать базу данных MySQL в виду того, что прописывать адрес сервера MySQL будет легче, чем путь до файла БД SQLite3 *(Однако ввиду специфики pdo и модульности нашей системы, какая БД и какая модель будет использоваться не играет значимой роли)* Теперь ближе к конкретной реализации: будем использовать pdo в нашей реализации. Будем использовать базу данных MySQL в виду того, что прописывать адрес сервера MySQL будет легче, чем путь до файла БД SQLite3 *(Однако ввиду специфики pdo и модульности нашей системы, какая БД и какая модель будет использоваться не играет значимой роли)*
```php ```php
class RealizationMySQL { // Да, я изменил имя класса, чтобы было яснее какая именно это реализация. class RealizationMySQL extends Realization { // Создал класс, наследующий Realization, чтобы можно было выбирать при необходимости между реализациями.
public $isReady = false; public $isReady = false;
private $db; // Объект базы данных pdo
private $cache = array(); // Тот самый кэш
public function __construct ($host, $user, $pass, $dbname) {
$this->db = new PDO("mysql:host=". $host .";dbname=". $dbname, $user, $pass);
$this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
private function hasLegatees ($elId) { // Метод для определения есть ли у элемента наследники
foreach ($this->cache as $item) {
if ($item['legatee'] == $elId) return true;
}
return false;
}
public function getElement ($root = null) { public function getElement ($root = null) {
// ... код реализации $selectedItems = array();
foreach ($this->cache as $item) {
if ($item['legatee'] == $root) {
$selectedItems[] = array(
"isElement" => $this->hasLegatees($item['id']),
"data" => $item['data'],
"stringData" => $item['data'],
"id" => $item['id']
);
}
}
return $selectedItems;
} }
public function ready () { public function ready () {
if (!$this->isReady) { if (!$this->isReady) {
$this->isReady = true; $this->isReady = true;
// ... Запрос и запись это в кэш // Запрос и запись в кэш
$selectedItems = $this->db->query('SELECT * FROM `model-table`');
$selectedItems->setFetchMode(PDO::FETCH_ASSOC);
// Очистим кэш
$this->cache = array();
while($row = $selectedItems->fetch()) {
$this->cache[] = $row;
}
}
}
public function finish () {
$this->isReady = false;
}
}
```
Теперь подробнее про структуру базы данных:
id (int) = NULL | pk, uq, ai, nn | Ключ записи
legatee (int) = NULL | | Информация о родительской записи (NULL, если нет родительской записи)
data(VARCHAR(64)) = "" | nn | Запись в текстовом виде.
SQL-Запрос *(Полный дамп в папке "sql")*:
```sql
CREATE TABLE `realizations-db`.`model-table` (
`id` INT NOT NULL AUTO_INCREMENT,
`legatee` INT NULL,
`data` VARCHAR(64) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE
);
```
Далее, после того, как мы определились со структурой нашей модели, мы можем закончить с реализацией класса RealizationMySQL:
```php
class RealizationMySQL extends Realization { // Создал класс, наследующий Realization, чтобы можно было выбирать при необходимости между реализациями.
public $isReady = false;
private $db; // Объект базы данных pdo
private $cache = array(); // Тот самый кэш
public function __construct ($host, $user, $pass, $dbname) {
$this->db = new PDO("mysql:host=". $host .";dbname=". $dbname, $user, $pass);
$this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
private function hasLegatees ($elId) { // Метод для определения есть ли у элемента наследники
foreach ($this->cache as $item) {
if ($item['legatee'] == $elId) return true;
}
return false;
}
public function getElement ($root = null) {
$selectedItems = array();
foreach ($this->cache as $item) {
if ($item['legatee'] == $root) {
$selectedItems[] = array(
"isElement" => $this->hasLegatees($item['id']),
"data" => $item['data'],
"stringData" => $item['data'],
"id" => $item['id']
);
}
}
return $selectedItems;
}
public function ready () {
if (!$this->isReady) {
$this->isReady = true;
// Запрос и запись в кэш
$selectedItems = $this->db->query('SELECT * FROM `model-table`');
$selectedItems->setFetchMode(PDO::FETCH_ASSOC);
// Очистим кэш
$this->cache = array();
while($row = $selectedItems->fetch()) {
$this->cache[] = $row;
}
} }
} }