Skip to content

Commit 127d738

Browse files
committed
Added Table not exists first implementation and tests
1 parent 7c2b04c commit 127d738

11 files changed

+218
-4
lines changed

.php_cs.cache

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"php":"7.4.1","version":"2.16.1","indent":" ","lineEnding":"\n","rules":{"blank_line_after_namespace":true,"braces":{"allow_single_line_closure":true},"class_definition":{"single_line":true},"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":true,"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_import_per_statement":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"binary_operator_spaces":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":{"statements":["return"]},"cast_spaces":true,"class_attributes_separation":{"elements":["method"]},"concat_space":true,"declare_equal_normalize":true,"function_typehint_space":true,"include":true,"increment_style":true,"lowercase_cast":true,"lowercase_static_reference":true,"magic_constant_casing":true,"magic_method_casing":true,"native_function_casing":true,"native_function_type_declaration_casing":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":true,"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unneeded_curly_braces":true,"no_unneeded_final_method":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"ordered_imports":true,"php_unit_fqcn_annotation":true,"phpdoc_align":{"tags":["method","param","property","return","throws","type","var"]},"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":true,"phpdoc_types_order":{"null_adjustment":"always_last","sort_algorithm":"none"},"phpdoc_var_without_name":true,"return_type_declaration":true,"semicolon_after_instruction":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_line_comment_style":{"comment_types":["hash"]},"single_line_throw":true,"single_quote":true,"single_trait_insert_per_statement":true,"space_after_semicolon":{"remove_in_empty_for_expressions":true},"standardize_increment":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"yoda_style":true},"hashes":{"src\/Driver\/MysqlDriver.php":197127788,"src\/Driver\/SQLiteDriver.php":1109810055,"src\/Driver\/Driver.php":2042956636,"src\/Driver\/PostgreSQLDriver.php":1279477825,"src\/Credentials.php":1692415050,"src\/Result.php":1584290880,"src\/Connection.php":816626996,"src\/Mock\/MockedDBALConnection.php":3644978697,"src\/Mock\/MockedDriver.php":1694662546,"tests\/ConnectionTest.php":1471950575,"tests\/SQLiteConnectionTest.php":3708921004,"tests\/PostgreSQLConnectionTest.php":3914901716,"tests\/MysqlConnectionTest.php":2079191261}}
1+
{"php":"7.4.1","version":"2.16.1","indent":" ","lineEnding":"\n","rules":{"blank_line_after_namespace":true,"braces":{"allow_single_line_closure":true},"class_definition":{"single_line":true},"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":true,"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_import_per_statement":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"binary_operator_spaces":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":{"statements":["return"]},"cast_spaces":true,"class_attributes_separation":{"elements":["method"]},"concat_space":true,"declare_equal_normalize":true,"function_typehint_space":true,"include":true,"increment_style":true,"lowercase_cast":true,"lowercase_static_reference":true,"magic_constant_casing":true,"magic_method_casing":true,"native_function_casing":true,"native_function_type_declaration_casing":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":true,"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unneeded_curly_braces":true,"no_unneeded_final_method":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"ordered_imports":true,"php_unit_fqcn_annotation":true,"phpdoc_align":{"tags":["method","param","property","return","throws","type","var"]},"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":true,"phpdoc_types_order":{"null_adjustment":"always_last","sort_algorithm":"none"},"phpdoc_var_without_name":true,"return_type_declaration":true,"semicolon_after_instruction":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_line_comment_style":{"comment_types":["hash"]},"single_line_throw":true,"single_quote":true,"single_trait_insert_per_statement":true,"space_after_semicolon":{"remove_in_empty_for_expressions":true},"standardize_increment":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"yoda_style":true},"hashes":{"src\/Driver\/MysqlDriver.php":1808796082,"src\/Driver\/SQLiteDriver.php":3459327179,"src\/Driver\/Driver.php":2379534927,"src\/Driver\/PostgreSQLDriver.php":503805631,"src\/Credentials.php":1470751445,"src\/Result.php":1940786624,"src\/Connection.php":2724048866,"src\/Mock\/MockedDBALConnection.php":2847858253,"src\/Mock\/MockedDriver.php":3163021275,"tests\/ConnectionTest.php":2058819372,"tests\/SQLiteConnectionTest.php":1617704118,"tests\/PostgreSQLConnectionTest.php":3923346312,"tests\/MysqlConnectionTest.php":2136983192,"src\/Exception\/DBALException.php":1503670777,"src\/Exception\/ConnectionException.php":3611662295,"src\/Exception\/TableNotFoundException.php":2519572257}}

src/Driver/MysqlDriver.php

+32
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
namespace Drift\DBAL\Driver;
1717

1818
use Drift\DBAL\Credentials;
19+
use Drift\DBAL\Exception\DBALException;
20+
use Drift\DBAL\Exception\TableNotFoundException;
1921
use Drift\DBAL\Result;
2022
use React\EventLoop\LoopInterface;
2123
use React\MySQL\ConnectionInterface;
24+
use React\MySQL\Exception;
2225
use React\MySQL\Factory;
2326
use React\MySQL\QueryResult;
2427
use React\Promise\PromiseInterface;
@@ -74,6 +77,35 @@ public function query(
7477
->query($sql, $parameters)
7578
->then(function (QueryResult $queryResult) {
7679
return new Result($queryResult->resultRows);
80+
})
81+
->otherwise(function (Exception $exception) {
82+
$this->parseException($exception);
7783
});
7884
}
85+
86+
/**
87+
* Parse exception.
88+
*
89+
* @param Exception $exception
90+
*
91+
* @throws DBALException
92+
*/
93+
private function parseException(Exception $exception)
94+
{
95+
$message = $exception->getMessage();
96+
$match = null;
97+
98+
if (
99+
preg_match('~^Unknown table \'(.*?)\'$~', $message, $match) ||
100+
preg_match('~^Table \'(.*?)\' doesn\'t exist$~', $message, $match)
101+
) {
102+
$tableName = $match[1];
103+
$tableParts = explode('.', $tableName, 2);
104+
$tableName = end($tableParts);
105+
106+
throw TableNotFoundException::createByTableName($tableName);
107+
}
108+
109+
throw DBALException::createGeneric($message);
110+
}
79111
}

src/Driver/PostgreSQLDriver.php

+30-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
namespace Drift\DBAL\Driver;
1717

1818
use Drift\DBAL\Credentials;
19+
use Drift\DBAL\Exception\DBALException;
20+
use Drift\DBAL\Exception\TableNotFoundException;
1921
use Drift\DBAL\Result;
2022
use PgAsync\Client;
23+
use PgAsync\ErrorException;
2124
use React\EventLoop\LoopInterface;
2225
use React\Promise\Deferred;
2326
use React\Promise\PromiseInterface;
@@ -84,7 +87,9 @@ public function query(
8487
->executeStatement($sql, $parameters)
8588
->subscribe(function ($row) use (&$results) {
8689
$results[] = $row;
87-
}, null, function () use (&$results, $deferred) {
90+
}, function (ErrorException $exception) {
91+
$this->parseException($exception);
92+
}, function () use (&$results, $deferred) {
8893
$deferred->resolve($results);
8994
});
9095

@@ -94,4 +99,28 @@ public function query(
9499
return new Result($results);
95100
});
96101
}
102+
103+
/**
104+
* Parse exception.
105+
*
106+
* @param ErrorException $exception
107+
*
108+
* @throws DBALException
109+
*/
110+
private function parseException(ErrorException $exception)
111+
{
112+
$message = $exception->getMessage();
113+
$match = null;
114+
115+
if (
116+
preg_match('~^ERROR: table "(.*?)" does not exist.*$~', $message, $match) ||
117+
preg_match('~^ERROR: relation "(.*?)" does not exist.*$~', $message, $match)
118+
) {
119+
$tableName = $match[1];
120+
121+
throw TableNotFoundException::createByTableName($tableName);
122+
}
123+
124+
throw DBALException::createGeneric($message);
125+
}
97126
}

src/Driver/SQLiteDriver.php

+27
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
use Clue\React\SQLite\Factory;
2020
use Clue\React\SQLite\Result as SQLiteResult;
2121
use Drift\DBAL\Credentials;
22+
use Drift\DBAL\Exception\DBALException;
23+
use Drift\DBAL\Exception\TableNotFoundException;
2224
use Drift\DBAL\Result;
2325
use React\EventLoop\LoopInterface;
2426
use React\Promise\PromiseInterface;
27+
use RuntimeException;
2528

2629
/**
2730
* Class SQLiteDriver.
@@ -70,6 +73,30 @@ public function query(
7073
->query($sql, $parameters)
7174
->then(function (SQLiteResult $sqliteResult) {
7275
return new Result($sqliteResult->rows);
76+
})
77+
->otherwise(function (RuntimeException $exception) {
78+
$this->parseException($exception);
7379
});
7480
}
81+
82+
/**
83+
* Parse exception.
84+
*
85+
* @param RuntimeException $exception
86+
*
87+
* @throws DBALException
88+
*/
89+
private function parseException(RuntimeException $exception)
90+
{
91+
$message = $exception->getMessage();
92+
$match = null;
93+
94+
if (preg_match('~^no such table:\s*(.*?)$~', $message, $match)) {
95+
$tableName = $match[1];
96+
97+
throw TableNotFoundException::createByTableName($tableName);
98+
}
99+
100+
throw DBALException::createGeneric($message);
101+
}
75102
}

src/Exception/ConnectionException.php

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the DriftPHP Project
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*
9+
* Feel free to edit as you please, and have fun.
10+
*
11+
* @author Marc Morera <[email protected]>
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace Drift\DBAL\Exception;
17+
18+
use Exception;
19+
20+
/**
21+
* Class ConnectionException.
22+
*/
23+
class ConnectionException extends Exception
24+
{
25+
}

src/Exception/DBALException.php

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the DriftPHP Project
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*
9+
* Feel free to edit as you please, and have fun.
10+
*
11+
* @author Marc Morera <[email protected]>
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace Drift\DBAL\Exception;
17+
18+
use Exception;
19+
20+
/**
21+
* Class DBALException.
22+
*/
23+
class DBALException extends Exception
24+
{
25+
/**
26+
* Create generic.
27+
*
28+
* @param string $reason
29+
*
30+
* @return DBALException
31+
*/
32+
public static function createGeneric(string $reason)
33+
{
34+
return new DBALException($reason);
35+
}
36+
}
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the DriftPHP Project
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*
9+
* Feel free to edit as you please, and have fun.
10+
*
11+
* @author Marc Morera <[email protected]>
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace Drift\DBAL\Exception;
17+
18+
/**
19+
* Class TableNotFoundException.
20+
*/
21+
class TableNotFoundException extends DBALException
22+
{
23+
/**
24+
* Create by table name.
25+
*
26+
* @param string $tableName
27+
*
28+
* @return TableNotFoundException
29+
*/
30+
public static function createByTableName(string $tableName)
31+
{
32+
return new TableNotFoundException(sprintf('Table %s not found', $tableName));
33+
}
34+
}

tests/ConnectionTest.php

+24-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace Drift\DBAL\Tests;
1717

1818
use Drift\DBAL\Connection;
19+
use Drift\DBAL\Exception\TableNotFoundException;
1920
use Drift\DBAL\Result;
2021
use function Clue\React\Block\await;
2122
use PHPUnit\Framework\TestCase;
@@ -128,8 +129,6 @@ public function testQuery()
128129

129130
/**
130131
* Test multiple rows.
131-
*
132-
* @group lol
133132
*/
134133
public function testMultipleRows()
135134
{
@@ -179,4 +178,27 @@ public function testMultipleRows()
179178

180179
await($promise, $loop, self::MAX_TIMEOUT);
181180
}
181+
182+
/**
183+
* Test connection exception.
184+
*
185+
* @group lol
186+
*/
187+
public function testTableDoesntExistException()
188+
{
189+
$loop = $this->createLoop();
190+
$connection = $this->getConnection($loop);
191+
$promise = $this->dropInfrastructure($connection)
192+
->then(function (Connection $connection) {
193+
return $connection->insert('test', [
194+
'id' => '?',
195+
'field1' => '?',
196+
'field2' => '?',
197+
], ['1', 'val11', 'val12']);
198+
});
199+
200+
$this->expectException(TableNotFoundException::class);
201+
$this->expectExceptionMessage('Table test not found');
202+
await($promise, $loop);
203+
}
182204
}

tests/MysqlConnectionTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Drift\DBAL\Connection;
2020
use Drift\DBAL\Credentials;
2121
use Drift\DBAL\Driver\MysqlDriver;
22+
use Drift\DBAL\Exception\TableNotFoundException;
2223
use React\EventLoop\LoopInterface;
2324
use React\Promise\PromiseInterface;
2425

@@ -78,6 +79,8 @@ protected function dropInfrastructure(Connection $connection): PromiseInterface
7879
->queryBySQL('DROP TABLE test')
7980
->then(function () use ($connection) {
8081
return $connection;
82+
}, function (TableNotFoundException $exception) {
83+
// Silent pass
8184
});
8285
}
8386
}

tests/PostgreSQLConnectionTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Drift\DBAL\Connection;
2020
use Drift\DBAL\Credentials;
2121
use Drift\DBAL\Driver\PostgreSQLDriver;
22+
use Drift\DBAL\Exception\TableNotFoundException;
2223
use React\EventLoop\LoopInterface;
2324
use React\Promise\PromiseInterface;
2425

@@ -76,6 +77,8 @@ protected function dropInfrastructure(Connection $connection): PromiseInterface
7677
->queryBySQL('DROP TABLE test')
7778
->then(function () use ($connection) {
7879
return $connection;
80+
}, function (TableNotFoundException $exception) {
81+
// Silent pass
7982
});
8083
}
8184
}

tests/SQLiteConnectionTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Drift\DBAL\Connection;
2020
use Drift\DBAL\Credentials;
2121
use Drift\DBAL\Driver\SQLiteDriver;
22+
use Drift\DBAL\Exception\TableNotFoundException;
2223
use React\EventLoop\LoopInterface;
2324
use React\Promise\PromiseInterface;
2425

@@ -74,6 +75,8 @@ protected function dropInfrastructure(Connection $connection): PromiseInterface
7475
->queryBySQL('DROP TABLE test')
7576
->then(function () use ($connection) {
7677
return $connection;
78+
}, function (TableNotFoundException $exception) {
79+
// Silent pass
7780
});
7881
}
7982
}

0 commit comments

Comments
 (0)