Skip to content

Commit 7a71ad9

Browse files
committed
Implement and use basic PDOStatement APIs
1 parent 77e052e commit 7a71ad9

File tree

5 files changed

+417
-32
lines changed

5 files changed

+417
-32
lines changed

tests/WP_PDO_MySQL_On_SQLite_PDO_API_Tests.php

Lines changed: 204 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,128 @@ public function test_connection(): void {
1616
}
1717

1818
public function test_query(): void {
19-
$result = $this->driver->query( 'SELECT 1' );
19+
$result = $this->driver->query( "SELECT 1, 'abc'" );
2020
$this->assertInstanceOf( PDOStatement::class, $result );
21-
$this->assertEquals( 1, $result->fetchColumn() );
21+
$this->assertSame(
22+
array(
23+
1 => 1,
24+
0 => 1,
25+
'abc' => 'abc',
26+
),
27+
$result->fetch( PDO::FETCH_BOTH )
28+
);
29+
}
30+
31+
/**
32+
* @dataProvider data_pdo_fetch_methods
33+
*/
34+
public function test_query_with_fetch_mode( $query, $mode, $expected ): void {
35+
$stmt = $this->driver->query( $query, $mode );
36+
$result = $stmt->fetch();
37+
if ( is_object( $expected ) ) {
38+
$this->assertInstanceOf( get_class( $expected ), $result );
39+
$this->assertEquals( $expected, $result );
40+
} else {
41+
$this->assertSame( $expected, $result );
42+
}
43+
44+
$this->assertFalse( $stmt->fetch() );
45+
}
46+
47+
public function test_query_fetch_mode_not_set(): void {
48+
$result = $this->driver->query( 'SELECT 1' );
49+
$this->assertSame(
50+
array(
51+
'1' => 1,
52+
0 => 1,
53+
),
54+
$result->fetch()
55+
);
56+
$this->assertFalse( $result->fetch() );
57+
}
58+
59+
public function test_query_fetch_mode_invalid_arg_count(): void {
60+
$this->expectException( ArgumentCountError::class );
61+
$this->expectExceptionMessage( 'PDO::query() expects exactly 2 arguments for the fetch mode provided, 3 given' );
62+
$this->driver->query( 'SELECT 1', PDO::FETCH_ASSOC, 0 );
63+
}
64+
65+
public function test_query_fetch_default_mode_allow_any_args(): void {
66+
$expected_result = array(
67+
array(
68+
1 => 1,
69+
0 => 1,
70+
),
71+
);
72+
73+
$result = $this->driver->query( 'SELECT 1' );
74+
$this->assertSame( $expected_result, $result->fetchAll() );
75+
76+
$result = $this->driver->query( 'SELECT 1', null );
77+
$this->assertSame( $expected_result, $result->fetchAll() );
78+
79+
$result = $this->driver->query( 'SELECT 1', null, 1 );
80+
$this->assertSame( $expected_result, $result->fetchAll() );
81+
82+
$result = $this->driver->query( 'SELECT 1', null, 'abc' );
83+
$this->assertSame( $expected_result, $result->fetchAll() );
84+
85+
$result = $this->driver->query( 'SELECT 1', null, 1, 2, 'abc', array(), true );
86+
$this->assertSame( $expected_result, $result->fetchAll() );
87+
}
88+
89+
public function test_query_fetch_column_invalid_arg_count(): void {
90+
$this->expectException( ArgumentCountError::class );
91+
$this->expectExceptionMessage( 'PDO::query() expects exactly 3 arguments for the fetch mode provided, 2 given' );
92+
$this->driver->query( 'SELECT 1', PDO::FETCH_COLUMN );
93+
}
94+
95+
public function test_query_fetch_column_invalid_colno_type(): void {
96+
$this->expectException( TypeError::class );
97+
$this->expectExceptionMessage( 'PDO::query(): Argument #3 must be of type int, string given' );
98+
$this->driver->query( 'SELECT 1', PDO::FETCH_COLUMN, '0' );
99+
}
100+
101+
public function test_query_fetch_class_not_enough_args(): void {
102+
$this->expectException( ArgumentCountError::class );
103+
$this->expectExceptionMessage( 'PDO::query() expects at least 3 arguments for the fetch mode provided, 2 given' );
104+
$this->driver->query( 'SELECT 1', PDO::FETCH_CLASS );
105+
}
106+
107+
public function test_query_fetch_class_too_many_args(): void {
108+
$this->expectException( ArgumentCountError::class );
109+
$this->expectExceptionMessage( 'PDO::query() expects at most 4 arguments for the fetch mode provided, 5 given' );
110+
$this->driver->query( 'SELECT 1', PDO::FETCH_CLASS, '\stdClass', array(), array() );
111+
}
112+
113+
public function test_query_fetch_class_invalid_class_type(): void {
114+
$this->expectException( TypeError::class );
115+
$this->expectExceptionMessage( 'PDO::query(): Argument #3 must be of type string, int given' );
116+
$this->driver->query( 'SELECT 1', PDO::FETCH_CLASS, 1 );
117+
}
118+
119+
public function test_query_fetch_class_invalid_class_name(): void {
120+
$this->expectException( TypeError::class );
121+
$this->expectExceptionMessage( 'PDO::query(): Argument #3 must be a valid class' );
122+
$this->driver->query( 'SELECT 1', PDO::FETCH_CLASS, 'non-existent-class' );
123+
}
124+
125+
public function test_query_fetch_class_invalid_constructor_args_type(): void {
126+
$this->expectException( TypeError::class );
127+
$this->expectExceptionMessage( 'PDO::query(): Argument #4 must be of type ?array, int given' );
128+
$this->driver->query( 'SELECT 1', PDO::FETCH_CLASS, 'stdClass', 1 );
129+
}
130+
131+
public function test_query_fetch_into_invalid_arg_count(): void {
132+
$this->expectException( ArgumentCountError::class );
133+
$this->expectExceptionMessage( 'PDO::query() expects exactly 3 arguments for the fetch mode provided, 2 given' );
134+
$this->driver->query( 'SELECT 1', PDO::FETCH_INTO );
135+
}
136+
137+
public function test_query_fetch_into_invalid_object_type(): void {
138+
$this->expectException( TypeError::class );
139+
$this->expectExceptionMessage( 'PDO::query(): Argument #3 must be of type object, int given' );
140+
$this->driver->query( 'SELECT 1', PDO::FETCH_INTO, 1 );
22141
}
23142

24143
public function test_exec(): void {
@@ -92,4 +211,87 @@ public function test_rollback_no_active_transaction(): void {
92211
$this->expectExceptionCode( 0 );
93212
$this->driver->rollBack();
94213
}
214+
215+
public function test_fetch_default(): void {
216+
// Default fetch mode is PDO::FETCH_BOTH.
217+
$result = $this->driver->query( "SELECT 1, 'abc', 2" );
218+
$this->assertSame(
219+
array(
220+
1 => 1,
221+
0 => 1,
222+
'abc' => 'abc',
223+
'2' => 2,
224+
),
225+
$result->fetch()
226+
);
227+
}
228+
229+
/**
230+
* @dataProvider data_pdo_fetch_methods
231+
*/
232+
public function test_fetch( $query, $mode, $expected ): void {
233+
$stmt = $this->driver->query( $query );
234+
$result = $stmt->fetch( $mode );
235+
if ( is_object( $expected ) ) {
236+
$this->assertInstanceOf( get_class( $expected ), $result );
237+
$this->assertEquals( $expected, $result );
238+
} else {
239+
$this->assertSame( $expected, $result );
240+
}
241+
}
242+
243+
public function data_pdo_fetch_methods(): Generator {
244+
// PDO::FETCH_BOTH
245+
yield 'PDO::FETCH_BOTH' => array(
246+
"SELECT 1, 'abc', 2, 'two' as `2`",
247+
PDO::FETCH_BOTH,
248+
array(
249+
1 => 1, // int
250+
0 => 1, // int
251+
'abc' => 'abc',
252+
'2' => 'two',
253+
'3' => 'two',
254+
),
255+
);
256+
257+
// PDO::FETCH_NUM
258+
yield 'PDO::FETCH_NUM' => array(
259+
"SELECT 1, 'abc', 2, 'two' as `2`",
260+
PDO::FETCH_NUM,
261+
array( 1, 'abc', 2, 'two' ),
262+
);
263+
264+
// PDO::FETCH_ASSOC
265+
yield 'PDO::FETCH_ASSOC' => array(
266+
"SELECT 1, 'abc', 2, 'two' as `2`",
267+
PDO::FETCH_ASSOC,
268+
array(
269+
'1' => 1, // int
270+
'abc' => 'abc',
271+
'2' => 'two',
272+
),
273+
);
274+
275+
// PDO::FETCH_NAMED
276+
yield 'PDO::FETCH_NAMED' => array(
277+
"SELECT 1, 'abc', 2, 'two' as `2`",
278+
PDO::FETCH_NAMED,
279+
array(
280+
'1' => 1, // int
281+
'abc' => 'abc',
282+
'2' => array( 2, 'two' ),
283+
),
284+
);
285+
286+
// PDO::FETCH_OBJ
287+
yield 'PDO::FETCH_OBJ' => array(
288+
"SELECT 1, 'abc', 2, 'two' as `2`",
289+
PDO::FETCH_OBJ,
290+
(object) array(
291+
'1' => 1, // int
292+
'abc' => 'abc',
293+
'2' => 'two',
294+
),
295+
);
296+
}
95297
}

0 commit comments

Comments
 (0)