-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9906265
commit 6ff0a0a
Showing
6 changed files
with
313 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<?php | ||
|
||
namespace App\Console; | ||
|
||
use Yii; | ||
use App\Model\DataForm; | ||
|
||
class ValidationController extends \yii\console\Controller | ||
{ | ||
public function actionInsertApp($needError) | ||
{ | ||
$needError = (int)$needError; | ||
$data = $this->generateData($needError); | ||
|
||
$form = new DataForm(); | ||
|
||
if ($form->load($data, '') && $form->validate()) { | ||
$this->saveData($data, 'data_for_validation_app'); | ||
|
||
} else { | ||
echo implode("\n", $form->getErrorSummary(false)) . "\n"; | ||
} | ||
} | ||
|
||
public function actionInsertDb($needValidData) | ||
{ | ||
$needValidData = (int)$needValidData; | ||
$data = $this->generateData($needValidData); | ||
try { | ||
$this->saveData($data, 'data_for_validation_db'); | ||
|
||
} catch (\yii\db\Exception $e) { | ||
$errorMsg = $e->errorInfo[2]; | ||
if ($e->errorInfo[1] === 3819) { | ||
preg_match("/Check constraint 'chk_(.*)' is violated/", $errorMsg, $matches); | ||
$field = $matches[1]; | ||
echo "Field '" . $field . "'" . ' is incorrect' . "\n"; | ||
} elseif ($e->errorInfo[1] === 1292) { | ||
preg_match("/Incorrect .* value: '.*' for column '(.*)'/", $errorMsg, $matches); | ||
$field = $matches[1]; | ||
echo "Field '" . $field . "'" . ' is incorrect' . "\n"; | ||
} else { | ||
echo $e; | ||
} | ||
|
||
return; | ||
} | ||
} | ||
|
||
public function generateData($needError) | ||
{ | ||
$data = [ | ||
'name' => $this->randomString() . ' ' . $this->randomString(), | ||
'login' => $this->randomString(), | ||
'email' => $this->randomString() . '@example.com', | ||
'password' => $this->randomString(8, 64), | ||
'agreed' => rand(0, 1), | ||
'date' => date('Y-m-d H:i:s', time() - rand(0, 86400 - 1)), | ||
'ipv4' => implode('.', [rand(0, 255), rand(0, 255), rand(0, 255), rand(0, 255)]), | ||
'guid' => implode('-', [$this->randomHex(8), $this->randomHex(4), '4' . $this->randomHex(3), '8' . $this->randomHex(3), $this->randomHex(12)]), | ||
]; | ||
|
||
$incorrectData = [ | ||
'name' => $this->randomString() . $this->randomString(), | ||
'login' => '#' . rand(100000000, 999999999), | ||
'email' => $this->randomString(), | ||
'password' => $this->randomString(4, 6), | ||
'agreed' => rand(10, 20), | ||
'date' => $this->randomString(), | ||
'ipv4' => $this->randomString(), | ||
'guid' => $this->randomString(), | ||
]; | ||
|
||
if ($needError) { | ||
$fields = array_keys($data); | ||
$field = $fields[rand(0, count($fields) - 1)]; | ||
$data[$field] = $incorrectData[$field]; | ||
} | ||
|
||
return $data; | ||
} | ||
|
||
protected $letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; | ||
protected $hexDigits = '0123456789ABCDEF'; | ||
|
||
protected function randomString($minLen = 1, $maxLen = 30) | ||
{ | ||
$len = rand($minLen, $maxLen); | ||
$str = ''; | ||
for ($i = 0; $i < $len; $i++) { | ||
$ch = $this->letters[rand(0, strlen($this->letters) - 1)]; | ||
$str .= $ch; | ||
} | ||
|
||
return $str; | ||
} | ||
|
||
protected function randomHex($len) | ||
{ | ||
$str = ''; | ||
for ($i = 0; $i < $len; $i++) { | ||
$ch = $this->hexDigits[rand(0, strlen($this->hexDigits) - 1)]; | ||
$str .= $ch; | ||
} | ||
|
||
return $str; | ||
} | ||
|
||
|
||
public function saveData($data, $tbl) | ||
{ | ||
$sql = " | ||
INSERT INTO {$tbl}(`name`, `login`, `email`, `password`, `agreed`, `date`, `ipv4`, `guid`) | ||
VALUES (:name, :login, :email, :password, :agreed, :date, :ipv4, :guid) | ||
"; | ||
$params = [ | ||
':name' => $data['name'], | ||
':login' => $data['login'], | ||
':email' => $data['email'], | ||
':password' => $data['password'], | ||
':agreed' => $data['agreed'], | ||
':date' => $data['date'], | ||
':ipv4' => $data['ipv4'], | ||
':guid' => $data['guid'], | ||
]; | ||
\Yii::$app->db->createCommand($sql, $params)->execute(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
|
||
namespace App\Console; | ||
|
||
use App\Model\DataForm; | ||
use App\Model\Document; | ||
use App\Model\CurrentStock; | ||
|
||
class ValidationPerformanceTestController extends PerformanceTestController | ||
{ | ||
protected $testingTime = 10; | ||
protected $emulateDocumentPage = false; | ||
protected $usleepTimeout = 100; | ||
|
||
protected function resetData() | ||
{ | ||
\Yii::$app->db->createCommand('DELETE FROM data_for_validation_app')->execute(); | ||
\Yii::$app->db->createCommand('DELETE FROM data_for_validation_db')->execute(); | ||
} | ||
|
||
protected function generateActionParams() | ||
{ | ||
$needError = (rand(0, 999) >= 950); | ||
|
||
return [$needError, 0]; | ||
} | ||
|
||
public function actionRunApp() | ||
{ | ||
$this->runPerformanceTest('validation/insert-app'); | ||
} | ||
|
||
public function actionRunDb() | ||
{ | ||
$this->runPerformanceTest('validation/insert-db'); | ||
} | ||
|
||
public function actionRunPureCalls($callNumber = 600) | ||
{ | ||
$controller = new ValidationController('validation', $this->module); | ||
|
||
$this->resetData(); | ||
|
||
$startTime = microtime(true); | ||
for ($i = 0; $i < $callNumber; $i++) { | ||
if ($i % 10 === 0) { | ||
echo $i . "\r"; | ||
} | ||
|
||
list($needError, $stub) = $this->generateActionParams(); | ||
|
||
ob_start(); | ||
$controller->actionInsertApp($needError); | ||
ob_get_clean(); | ||
} | ||
$stopTime = microtime(true); | ||
$timeDiff = $stopTime - $startTime; | ||
|
||
echo 'App:' . "\n"; | ||
echo 'Call number: ' . $callNumber . "\n"; | ||
echo 'Total time: ' . $timeDiff . "\n"; | ||
echo 'Calls per second: ' . ($callNumber / $timeDiff) . "\n"; | ||
|
||
|
||
echo "\n"; | ||
$this->resetData(); | ||
|
||
$startTime = microtime(true); | ||
for ($i = 0; $i < $callNumber; $i++) { | ||
if ($i % 10 === 0) { | ||
echo $i . "\r"; | ||
} | ||
|
||
list($needError, $stub) = $this->generateActionParams(); | ||
|
||
ob_start(); | ||
$controller->actionInsertDb($needError); | ||
ob_get_clean(); | ||
} | ||
$stopTime = microtime(true); | ||
$timeDiff = $stopTime - $startTime; | ||
|
||
echo 'DB:' . "\n"; | ||
echo 'Call number: ' . $callNumber . "\n"; | ||
echo 'Total time: ' . $timeDiff . "\n"; | ||
echo 'Calls per second: ' . ($callNumber / $timeDiff) . "\n"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace App\Model; | ||
|
||
class DataForm extends \yii\base\Model | ||
{ | ||
public $name; | ||
public $login; | ||
public $email; | ||
public $password; | ||
public $agreed; | ||
public $date; | ||
public $ipv4; | ||
public $guid; | ||
|
||
public function rules() | ||
{ | ||
return [ | ||
[['name'], 'match', 'pattern' => '/^[A-Za-z]+\s[A-Za-z]+$/u'], | ||
[['login'], 'match', 'pattern' => '/^[a-zA-Z0-9\-_]+$/'], | ||
[['email'], 'email'], | ||
[['email', 'password'], 'required'], | ||
[['password'], 'string', 'length' => [8, 64]], | ||
[['agreed'], 'boolean'], | ||
[['date'], 'datetime', 'format' => 'php:Y-m-d H:i:s'], | ||
[['ipv4'], 'ip', 'ipv6' => false], | ||
[['guid'], 'match', 'pattern' => '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i'], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
namespace App\Model; | ||
|
||
class Material extends \App\Db\ActiveRecord | ||
{ | ||
public static function tableName() | ||
{ | ||
return 'materials'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
|
||
use yii\db\Migration; | ||
|
||
/** | ||
* Class m201004_163540_validation | ||
*/ | ||
class m201004_163540_validation extends Migration | ||
{ | ||
public function up() | ||
{ | ||
$this->createTable('data_for_validation_app', [ | ||
'id' => $this->primaryKey(), | ||
'name' => $this->string()->null(), | ||
'login' => $this->string()->null(), | ||
'email' => $this->string()->notNull(), | ||
'password' => $this->string()->notNull(), | ||
'agreed' => $this->boolean()->null(), | ||
'date' => $this->dateTime()->null(), | ||
'ipv4' => $this->string()->null(), | ||
'guid' => $this->string()->null(), | ||
]); | ||
|
||
$this->createTable('data_for_validation_db', [ | ||
'id' => $this->primaryKey(), | ||
'name' => $this->string()->null(), | ||
'login' => $this->string()->null(), | ||
'email' => $this->string()->notNull(), | ||
'password' => $this->string()->notNull(), | ||
'agreed' => $this->boolean()->null(), | ||
'date' => $this->dateTime()->null(), | ||
'ipv4' => $this->string()->null(), | ||
'guid' => $this->string()->null(), | ||
]); | ||
|
||
$sql = " | ||
ALTER TABLE data_for_validation_db | ||
ADD CONSTRAINT chk_name CHECK (name REGEXP '^[A-Za-z]+ [A-Za-z]+$'), | ||
ADD CONSTRAINT chk_login CHECK (login REGEXP '^[a-zA-Z0-9\-_]+$'), | ||
ADD CONSTRAINT chk_email CHECK (email REGEXP :email_pattern), | ||
ADD CONSTRAINT chk_password CHECK (LENGTH(password) BETWEEN 8 AND 64), | ||
ADD CONSTRAINT chk_agreed CHECK (agreed BETWEEN 0 AND 1), | ||
ADD CONSTRAINT chk_ipv4 CHECK (ipv4 REGEXP '^(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))$'), | ||
ADD CONSTRAINT chk_guid CHECK (guid REGEXP '^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$') | ||
"; | ||
|
||
$this->execute($sql, [':email_pattern' => trim((new \yii\validators\EmailValidator())->pattern, '/')]); | ||
} | ||
|
||
public function down() | ||
{ | ||
$this->dropTable('data_for_validation_db'); | ||
$this->dropTable('data_for_validation_app'); | ||
} | ||
} |