Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Jul 18, 2024
1 parent f09ffd6 commit 21ca236
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 23 deletions.
5 changes: 4 additions & 1 deletion src/Auditor/EmptyColumn/EmptyColumnMysqlAuditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ private function createProcedure(): void
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_SCHEMA = DATABASE()
AND (IS_NULLABLE = 'YES' OR DATA_TYPE IN ('varchar', 'text', 'mediumtext', 'longtext', 'tinytext'))
AND (
IS_NULLABLE = 'YES'
OR DATA_TYPE IN ('varchar', 'tinytext', 'text', 'mediumtext', 'longtext')
)
ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
Expand Down
41 changes: 32 additions & 9 deletions src/Auditor/MixedEmptyValues/MixedEmptyValuesMysqlAuditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Orisai\DbAudit\Auditor\MixedEmptyValues;

use Orisai\DbAudit\Report\ColumnViolationSource;
use Orisai\DbAudit\Report\Violation;

final class MixedEmptyValuesMysqlAuditor extends MixedEmptyValuesAuditor
{

Expand All @@ -15,8 +18,25 @@ public function analyse(): array
$this->cleanup();
}

//TODO - violations
return $records;
$violations = [];
foreach ($records as $record) {
$source = new ColumnViolationSource(
$record['TABLE_SCHEMA'],
null,
$record['TABLE_NAME'],
$record['COLUMN_NAME'],
);

$violations[] = new Violation(
self::getKey(),
'Column '
. $source->toString()
. ' contains mixed empty values.',
$source,
);
}

return $violations;
}

private function createProcedure(): void
Expand All @@ -33,11 +53,14 @@ private function createProcedure(): void
DECLARE done TINYINT DEFAULT 0;
DECLARE empty_string_exists INT DEFAULT 0;
DECLARE null_value_exists INT DEFAULT 0;
DECLARE cur CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND DATA_TYPE IN ('char', 'varchar', 'text', 'tinytext', 'mediumtext', 'longtext')
AND DATA_TYPE IN ('varchar', 'tinytext', 'text', 'mediumtext', 'longtext')
AND IS_NULLABLE = 'YES'
ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME;
Expand All @@ -59,19 +82,19 @@ private function createProcedure(): void
END IF;
-- Check for empty string
SET @query_empty_string = CONCAT('SELECT 1 FROM `', fetched_table_schema, '`.`', fetched_table_name, '` WHERE `', fetched_column_name, '` = \'\' LIMIT 1');
SET @query_empty_string = CONCAT('SELECT COUNT(*) INTO @empty_string_exists FROM `', fetched_table_schema, '`.`', fetched_table_name, '` WHERE `', fetched_column_name, '` = \'\' LIMIT 1');

Check failure on line 85 in src/Auditor/MixedEmptyValues/MixedEmptyValuesMysqlAuditor.php

View workflow job for this annotation

GitHub Actions / Coding standard (ubuntu-latest, 8.3)

Line exceeds maximum limit of 150 characters, contains 196 characters.
PREPARE stmt_empty_string FROM @query_empty_string;
EXECUTE stmt_empty_string;
DEALLOCATE PREPARE stmt_empty_string;
IF (@query_empty_string = 1) THEN
IF @empty_string_exists > 0 THEN
-- Check for null value
SET @query_null_value = CONCAT('SELECT 1 FROM `', fetched_table_schema, '`.`', fetched_table_name, '` WHERE `', fetched_column_name, '` IS NULL LIMIT 1');
SET @query_null_value = CONCAT('SELECT COUNT(*) INTO @null_value_exists FROM `', fetched_table_schema, '`.`', fetched_table_name, '` WHERE `', fetched_column_name, '` IS NULL LIMIT 1');

Check failure on line 92 in src/Auditor/MixedEmptyValues/MixedEmptyValuesMysqlAuditor.php

View workflow job for this annotation

GitHub Actions / Coding standard (ubuntu-latest, 8.3)

Line exceeds maximum limit of 150 characters, contains 197 characters.
PREPARE stmt_null_value FROM @query_null_value;
EXECUTE stmt_null_value;
DEALLOCATE PREPARE stmt_null_value;
IF (@query_null_value = 1) THEN
IF @null_value_exists > 0 THEN
INSERT INTO OrisaiDbAudit_mixed_empty_columns (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE)
VALUES (fetched_table_schema, fetched_table_name, fetched_column_name, fetched_column_type);
END IF;
Expand All @@ -87,12 +110,12 @@ private function createProcedure(): void
private function cleanup(): void
{
$this->dbal->exec(
/** @lang MySQL */
/** @lang MySQL */
'DROP PROCEDURE OrisaiDbAudit_FindMixedEmptyColumns;',
);

$this->dbal->exec(
/** @lang MySQL */
/** @lang MySQL */
'DROP TEMPORARY TABLE OrisaiDbAudit_mixed_empty_columns;',
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public function test(DbalAdapter $dbal): void
$shortcuts->createDatabase($db);
$shortcuts->useDatabase($db);

self::assertSame([], $auditor->analyse());

// //////
// TABLES
// //////
Expand Down
52 changes: 51 additions & 1 deletion tests/Integration/Auditor/BoolLikeColumnMysqlAuditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public function test(DbalAdapter $dbal): void
$shortcuts->createDatabase($db);
$shortcuts->useDatabase($db);

self::assertSame([], $auditor->analyse());

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
Expand Down Expand Up @@ -87,7 +89,6 @@ public function test(DbalAdapter $dbal): void
SQL,
);

// TODO - vylepšit check na 0 a 1
$dbal->exec(
/** @lang MySQL */
<<<'SQL'
Expand Down Expand Up @@ -134,6 +135,31 @@ public function test(DbalAdapter $dbal): void
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
CREATE TABLE `non_tiny_types` (
`smallint` smallint unsigned NOT NULL,
`mediumint` mediumint unsigned NOT NULL,
`int` int unsigned NOT NULL,
`bigint` bigint unsigned NOT NULL,
CHECK ( `smallint` IN (0, 1)),
CHECK ( `mediumint` IN (0, 1)),
CHECK ( `int` IN (0, 1)),
CHECK ( `bigint` IN (0, 1))
)
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
INSERT INTO `non_tiny_types` (`smallint`, `mediumint`, `int`, `bigint`) VALUES
(1, 1, 1, 1),
(0, 0, 0, 0)
SQL,
);

$report = $auditor->analyse();
self::assertEquals($report, $auditor->analyse());
self::assertEquals([
Expand Down Expand Up @@ -161,6 +187,30 @@ public function test(DbalAdapter $dbal): void
(new ColumnViolationSource($db, null, 'no_checks', 'tinyint'))
->setColumnType('tinyint unsigned'),
),
new Violation(
$key,
"Column [bool_like_column][non_tiny_types][bigint] (Column type: 'bigint unsigned') contains only 0 and 1 but is not defined as tinyint.",

Check failure on line 192 in tests/Integration/Auditor/BoolLikeColumnMysqlAuditorTest.php

View workflow job for this annotation

GitHub Actions / Coding standard (ubuntu-latest, 8.3)

Line exceeds maximum limit of 150 characters, contains 154 characters.
(new ColumnViolationSource($db, null, 'non_tiny_types', 'bigint'))
->setColumnType('bigint unsigned'),
),
new Violation(
$key,
"Column [bool_like_column][non_tiny_types][int] (Column type: 'int unsigned') contains only 0 and 1 but is not defined as tinyint.",
(new ColumnViolationSource($db, null, 'non_tiny_types', 'int'))
->setColumnType('int unsigned'),
),
new Violation(
$key,
"Column [bool_like_column][non_tiny_types][mediumint] (Column type: 'mediumint unsigned') contains only 0 and 1 but is not defined as tinyint.",

Check failure on line 204 in tests/Integration/Auditor/BoolLikeColumnMysqlAuditorTest.php

View workflow job for this annotation

GitHub Actions / Coding standard (ubuntu-latest, 8.3)

Line exceeds maximum limit of 150 characters, contains 160 characters.
(new ColumnViolationSource($db, null, 'non_tiny_types', 'mediumint'))
->setColumnType('mediumint unsigned'),
),
new Violation(
$key,
"Column [bool_like_column][non_tiny_types][smallint] (Column type: 'smallint unsigned') contains only 0 and 1 but is not defined as tinyint.",

Check failure on line 210 in tests/Integration/Auditor/BoolLikeColumnMysqlAuditorTest.php

View workflow job for this annotation

GitHub Actions / Coding standard (ubuntu-latest, 8.3)

Line exceeds maximum limit of 150 characters, contains 158 characters.
(new ColumnViolationSource($db, null, 'non_tiny_types', 'smallint'))
->setColumnType('smallint unsigned'),
),
], $report);
}

Expand Down
49 changes: 49 additions & 0 deletions tests/Integration/Auditor/EmptyColumnMysqlAuditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public function test(DbalAdapter $dbal): void
$shortcuts->createDatabase($db);
$shortcuts->useDatabase($db);

self::assertSame([], $auditor->analyse());

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
Expand Down Expand Up @@ -134,8 +136,55 @@ public function test(DbalAdapter $dbal): void
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
CREATE TABLE `all_string_types` (
`varchar` varchar(255) NULL,
`tinytext` varchar(255) NULL,
`text` varchar(255) NULL,
`mediumtext` varchar(255) NULL,
`longtext` varchar(255) NULL
)
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
INSERT INTO `all_string_types` (`varchar`, `tinytext`, `text`, `mediumtext`, `longtext`) VALUES
('', '', '', '', ''),
(null, null, null, null, null)
SQL,
);

$report = $auditor->analyse();
self::assertEquals([
new Violation(
$key,
'Column [empty_column][all_string_types][longtext] is empty.',
new ColumnViolationSource($db, null, 'all_string_types', 'longtext'),
),
new Violation(
$key,
'Column [empty_column][all_string_types][mediumtext] is empty.',
new ColumnViolationSource($db, null, 'all_string_types', 'mediumtext'),
),
new Violation(
$key,
'Column [empty_column][all_string_types][text] is empty.',
new ColumnViolationSource($db, null, 'all_string_types', 'text'),
),
new Violation(
$key,
'Column [empty_column][all_string_types][tinytext] is empty.',
new ColumnViolationSource($db, null, 'all_string_types', 'tinytext'),
),
new Violation(
$key,
'Column [empty_column][all_string_types][varchar] is empty.',
new ColumnViolationSource($db, null, 'all_string_types', 'varchar'),
),
new Violation(
$key,
'Column [empty_column][empty_column_null][b] is empty.',
Expand Down
2 changes: 2 additions & 0 deletions tests/Integration/Auditor/EmptyTableMysqlAuditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public function test(DbalAdapter $dbal): void
$shortcuts->createDatabase($db);
$shortcuts->useDatabase($db);

self::assertSame([], $auditor->analyse());

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public function test(DbalAdapter $dbal): void
//TODO - kontrolovat i nevalidní datumy, nejen nulové? případně přejmenovat auditor
$dbal->exec('SET sql_mode = `ALLOW_INVALID_DATES`');

$result = $auditor->analyse();
self::assertSame([], $result);
self::assertSame([], $auditor->analyse());

$dbal->exec(
/** @lang MySQL */
Expand Down
84 changes: 79 additions & 5 deletions tests/Integration/Auditor/MixedEmptyValuesMysqlAuditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Orisai\DbAudit\Dbal\DbalAdapter;
use Orisai\DbAudit\Dbal\DibiAdapter;
use Orisai\DbAudit\Dbal\NextrasAdapter;
use Orisai\DbAudit\Report\ColumnViolationSource;
use Orisai\DbAudit\Report\Violation;
use PHPUnit\Framework\TestCase;
use Tests\Orisai\DbAudit\Helper\MysqlConnectionConfig;
use Tests\Orisai\DbAudit\Helper\MysqlShortcuts;
Expand Down Expand Up @@ -50,9 +52,10 @@ public function test(DbalAdapter $dbal): void
$shortcuts->createDatabase($db);
$shortcuts->useDatabase($db);

//TODO - otestovat různé typy sloupců, ze všech auditorů
self::assertSame([], $auditor->analyse());

$dbal->exec(
/** @lang MySQL */
/** @lang MySQL */
<<<'SQL'
CREATE TABLE `empty_table` (
`string` varchar(255) NOT NULL,
Expand All @@ -61,10 +64,81 @@ public function test(DbalAdapter $dbal): void
SQL,
);

$report = $auditor->analyse();
self::assertSame($report, $auditor->analyse());
self::assertSame([
$dbal->exec(
/** @lang MySQL */
<<<'SQL'
CREATE TABLE `full_table` (
`string` varchar(255) NOT NULL,
`string_null` varchar(255) NULL
)
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
INSERT INTO `full_table` (`string`, `string_null`) VALUES
('foo', 'bar'),
('', ''),
('', null)
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
CREATE TABLE `all_types` (
`varchar` varchar(255) NULL,
`tinytext` varchar(255) NULL,
`text` varchar(255) NULL,
`mediumtext` varchar(255) NULL,
`longtext` varchar(255) NULL
)
SQL,
);

$dbal->exec(
/** @lang MySQL */
<<<'SQL'
INSERT INTO `all_types` (`varchar`, `tinytext`, `text`, `mediumtext`, `longtext`) VALUES
('', '', '', '', ''),
(null, null, null, null, null)
SQL,
);

$report = $auditor->analyse();
self::assertEquals($report, $auditor->analyse());
self::assertEquals([
new Violation(
$key,
'Column [mixed_empty_values][all_types][longtext] contains mixed empty values.',
new ColumnViolationSource($db, null, 'all_types', 'longtext'),
),
new Violation(
$key,
'Column [mixed_empty_values][all_types][mediumtext] contains mixed empty values.',
new ColumnViolationSource($db, null, 'all_types', 'mediumtext'),
),
new Violation(
$key,
'Column [mixed_empty_values][all_types][text] contains mixed empty values.',
new ColumnViolationSource($db, null, 'all_types', 'text'),
),
new Violation(
$key,
'Column [mixed_empty_values][all_types][tinytext] contains mixed empty values.',
new ColumnViolationSource($db, null, 'all_types', 'tinytext'),
),
new Violation(
$key,
'Column [mixed_empty_values][all_types][varchar] contains mixed empty values.',
new ColumnViolationSource($db, null, 'all_types', 'varchar'),
),
new Violation(
$key,
'Column [mixed_empty_values][full_table][string_null] contains mixed empty values.',
new ColumnViolationSource($db, null, 'full_table', 'string_null'),
),
], $report);
}

Expand Down
5 changes: 0 additions & 5 deletions tools/phpstan.baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ parameters:
count: 1
path: ../src/Auditor/InvalidDefaultDate/InvalidDefaultDateMysqlAuditor.php

-
message: "#^Method Orisai\\\\DbAudit\\\\Auditor\\\\MixedEmptyValues\\\\MixedEmptyValuesMysqlAuditor\\:\\:analyse\\(\\) should return list\\<Orisai\\\\DbAudit\\\\Report\\\\Violation\\> but returns list\\<array\\{TABLE_SCHEMA\\: string, TABLE_NAME\\: string, COLUMN_NAME\\: string, COLUMN_TYPE\\: string\\}\\>\\.$#"
count: 1
path: ../src/Auditor/MixedEmptyValues/MixedEmptyValuesMysqlAuditor.php

-
message: "#^Method Orisai\\\\DbAudit\\\\Auditor\\\\MixedEmptyValues\\\\MixedEmptyValuesMysqlAuditor\\:\\:getRecords\\(\\) should return list\\<array\\{TABLE_SCHEMA\\: string, TABLE_NAME\\: string, COLUMN_NAME\\: string, COLUMN_TYPE\\: string\\}\\> but returns list\\<array\\<string, mixed\\>\\>\\.$#"
count: 1
Expand Down

0 comments on commit 21ca236

Please sign in to comment.