Skip to content

Commit 8b1baad

Browse files
committed
Fixed prepare value bug and added bool testing
1 parent c6b4eea commit 8b1baad

2 files changed

Lines changed: 380 additions & 1 deletion

File tree

src/Schema/Traits/Custom_Table_Query_Methods.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,9 @@ public static function update_many( array $entries ): bool {
388388
$value = $value->format( 'Y-m-d H:i:s' );
389389
}
390390

391-
$set_statement[] = $database::prepare( "`{$column}` = %s", $value );
391+
[ $value, $placeholder ] = self::prepare_value_for_query( $column, $value );
392+
393+
$set_statement[] = $database::prepare( "`{$column}` = {$placeholder}", $value );
392394
}
393395

394396
$set_statement = implode( ', ', $set_statement );
Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
<?php
2+
3+
namespace StellarWP\Schema\Tests\Columns;
4+
5+
use StellarWP\Schema\Tests\SchemaTestCase;
6+
use StellarWP\Schema\Columns\Boolean_Column;
7+
use StellarWP\Schema\Columns\Blob_Column;
8+
use StellarWP\Schema\Columns\Column_Types;
9+
use StellarWP\Schema\Columns\PHP_Types;
10+
use StellarWP\Schema\Register;
11+
use StellarWP\Schema\Tables\Contracts\Table;
12+
use StellarWP\Schema\Tables\Table_Schema;
13+
use StellarWP\Schema\Collections\Column_Collection;
14+
use StellarWP\Schema\Columns\ID;
15+
use StellarWP\Schema\Columns\String_Column;
16+
17+
class BooleanBlobColumnClassTest extends SchemaTestCase {
18+
/**
19+
* @before
20+
*/
21+
public function drop_tables() {
22+
$this->get_column_types_test_table()->drop();
23+
}
24+
25+
/**
26+
* Get a table using Boolean_Column and Blob_Column classes directly.
27+
*/
28+
public function get_column_types_test_table(): Table {
29+
return new class extends Table {
30+
const SCHEMA_VERSION = '3.0.0';
31+
protected static $base_table_name = 'column_class_test';
32+
protected static $group = 'test_v3';
33+
protected static $schema_slug = 'test-v3-column-class';
34+
35+
public static function get_schema_history(): array {
36+
$table_name = static::table_name( true );
37+
$callable = function() use ( $table_name ) {
38+
$columns = new Column_Collection();
39+
40+
// Primary key
41+
$columns[] = ( new ID( 'id' ) )
42+
->set_length( 11 )
43+
->set_type( Column_Types::INT );
44+
45+
// Using Boolean_Column class
46+
$columns[] = ( new Boolean_Column( 'active_flag' ) )
47+
->set_default( true );
48+
49+
$columns[] = ( new Boolean_Column( 'published_flag' ) )
50+
->set_default( false );
51+
52+
$columns[] = ( new Boolean_Column( 'featured_flag' ) )
53+
->set_nullable( true );
54+
55+
// Using different Boolean column types
56+
$columns[] = ( new Boolean_Column( 'bit_flag' ) )
57+
->set_type( Column_Types::BIT );
58+
59+
$columns[] = new Boolean_Column( 'boolean_flag' );
60+
61+
// Using Blob_Column class with different types
62+
$columns[] = ( new Blob_Column( 'tiny_data' ) )
63+
->set_type( Column_Types::TINYBLOB );
64+
65+
$columns[] = ( new Blob_Column( 'blob_data' ) )
66+
->set_nullable( true );
67+
68+
$columns[] = ( new Blob_Column( 'medium_data' ) )
69+
->set_type( Column_Types::MEDIUMBLOB );
70+
71+
$columns[] = ( new Blob_Column( 'long_data' ) )
72+
->set_type( Column_Types::LONGBLOB );
73+
74+
// Blob column with JSON PHP type
75+
$columns[] = ( new Blob_Column( 'json_blob_data' ) )
76+
->set_type( Column_Types::BLOB )
77+
->set_php_type( PHP_Types::JSON );
78+
79+
$columns[] = ( new Blob_Column( 'string_blob_data' ) )
80+
->set_type( Column_Types::BLOB )
81+
->set_php_type( PHP_Types::STRING );
82+
83+
// Regular column for reference
84+
$columns[] = ( new String_Column( 'name' ) )
85+
->set_length( 255 );
86+
87+
return new Table_Schema( $table_name, $columns );
88+
};
89+
90+
return [
91+
static::SCHEMA_VERSION => $callable,
92+
];
93+
}
94+
};
95+
}
96+
97+
/**
98+
* Test Boolean_Column class instantiation and configuration.
99+
*
100+
* @test
101+
*/
102+
public function should_create_boolean_columns_with_proper_types() {
103+
$column = new Boolean_Column( 'test_bool' );
104+
105+
// Test default type is BOOLEAN
106+
$this->assertEquals( Column_Types::BOOLEAN, $column->get_type() );
107+
108+
// Test PHP type is BOOL
109+
$this->assertEquals( PHP_Types::BOOL, $column->get_php_type() );
110+
111+
// Test different boolean types
112+
$column->set_type( Column_Types::BIT );
113+
$this->assertEquals( Column_Types::BIT, $column->get_type() );
114+
}
115+
116+
/**
117+
* Test Blob_Column class instantiation and configuration.
118+
*
119+
* @test
120+
*/
121+
public function should_create_blob_columns_with_proper_types() {
122+
$column = new Blob_Column( 'test_blob' );
123+
124+
// Test default type is BLOB
125+
$this->assertEquals( Column_Types::BLOB, $column->get_type() );
126+
127+
// Test PHP type is BLOB
128+
$this->assertEquals( PHP_Types::BLOB, $column->get_php_type() );
129+
130+
// Test different blob types
131+
$column->set_type( Column_Types::MEDIUMBLOB );
132+
$this->assertEquals( Column_Types::MEDIUMBLOB, $column->get_type() );
133+
134+
// Test JSON PHP type
135+
$column->set_php_type( PHP_Types::JSON );
136+
$this->assertEquals( PHP_Types::JSON, $column->get_php_type() );
137+
}
138+
139+
/**
140+
* Test table creation with column classes.
141+
*
142+
* @test
143+
*/
144+
public function should_create_table_with_column_classes() {
145+
$table = $this->get_column_types_test_table();
146+
Register::table( $table );
147+
148+
$this->assertTrue( $table->exists() );
149+
150+
// Verify columns exist
151+
$columns = $table::get_columns();
152+
$this->assertNotNull( $columns->get( 'active_flag' ) );
153+
$this->assertNotNull( $columns->get( 'published_flag' ) );
154+
$this->assertNotNull( $columns->get( 'featured_flag' ) );
155+
$this->assertNotNull( $columns->get( 'bit_flag' ) );
156+
$this->assertNotNull( $columns->get( 'boolean_flag' ) );
157+
$this->assertNotNull( $columns->get( 'tiny_data' ) );
158+
$this->assertNotNull( $columns->get( 'blob_data' ) );
159+
$this->assertNotNull( $columns->get( 'json_blob_data' ) );
160+
}
161+
162+
/**
163+
* Test data operations with Boolean_Column defaults.
164+
*
165+
* @test
166+
*/
167+
public function should_respect_boolean_column_defaults() {
168+
global $wpdb;
169+
170+
$table = $this->get_column_types_test_table();
171+
Register::table( $table );
172+
173+
// Insert with minimal data to test defaults
174+
$data = [
175+
'name' => 'Test Defaults',
176+
'tiny_data' => 'tiny',
177+
'medium_data' => 'medium',
178+
'long_data' => 'long',
179+
'json_blob_data' => json_encode( [ 'test' => 'data' ] ),
180+
];
181+
182+
$result = $table::insert( $data );
183+
$this->assertNotFalse( $result );
184+
185+
$insert_id = $wpdb->insert_id;
186+
$retrieved = $table::get_by_id( $insert_id );
187+
188+
// active_flag default is true
189+
$this->assertTrue( $retrieved['active_flag'] );
190+
191+
// published_flag default is false
192+
$this->assertFalse( $retrieved['published_flag'] );
193+
194+
// featured_flag is nullable and should be null
195+
$this->assertNull( $retrieved['featured_flag'] );
196+
}
197+
198+
/**
199+
* Test JSON storage in Blob columns.
200+
*
201+
* @test
202+
*/
203+
public function should_handle_json_in_blob_columns() {
204+
global $wpdb;
205+
206+
$table = $this->get_column_types_test_table();
207+
Register::table( $table );
208+
209+
$complex_json = [
210+
'nested' => [
211+
'array' => [ 1, 2, 3 ],
212+
'object' => [ 'key' => 'value' ],
213+
'boolean' => true,
214+
'null' => null,
215+
],
216+
'special_chars' => 'Test with "quotes" and \'apostrophes\'',
217+
'unicode' => '测试 テスト тест',
218+
];
219+
220+
$data = [
221+
'name' => 'JSON Test',
222+
'active_flag' => true,
223+
'published_flag' => false,
224+
'tiny_data' => 'tiny',
225+
'medium_data' => 'medium',
226+
'long_data' => 'long',
227+
'json_blob_data' => $complex_json, // Pass as array, should be encoded
228+
];
229+
230+
$result = $table::insert( $data );
231+
$this->assertNotFalse( $result );
232+
233+
$insert_id = $wpdb->insert_id;
234+
$retrieved = $table::get_by_id( $insert_id );
235+
236+
// json_blob_data should be decoded back to array
237+
$this->assertIsArray( $retrieved['json_blob_data'] );
238+
$this->assertEquals( $complex_json['nested']['array'], $retrieved['json_blob_data']['nested']['array'] );
239+
$this->assertEquals( $complex_json['special_chars'], $retrieved['json_blob_data']['special_chars'] );
240+
$this->assertEquals( $complex_json['unicode'], $retrieved['json_blob_data']['unicode'] );
241+
}
242+
243+
244+
/**
245+
* Test querying with different Boolean column types.
246+
*
247+
* @test
248+
*/
249+
public function should_query_different_boolean_types() {
250+
$table = $this->get_column_types_test_table();
251+
Register::table( $table );
252+
253+
// Insert test data
254+
$test_data = [
255+
[
256+
'name' => 'All True',
257+
'active_flag' => true,
258+
'published_flag' => true,
259+
'featured_flag' => true,
260+
'bit_flag' => 1,
261+
'boolean_flag' => true,
262+
'tiny_data' => 'a',
263+
'medium_data' => 'a',
264+
'long_data' => 'a',
265+
'json_blob_data' => '{}',
266+
],
267+
[
268+
'name' => 'All False',
269+
'active_flag' => false,
270+
'published_flag' => false,
271+
'featured_flag' => false,
272+
'bit_flag' => 0,
273+
'boolean_flag' => false,
274+
'tiny_data' => 'b',
275+
'medium_data' => 'b',
276+
'long_data' => 'b',
277+
'json_blob_data' => '{}',
278+
],
279+
[
280+
'name' => 'Mixed',
281+
'active_flag' => true,
282+
'published_flag' => false,
283+
'featured_flag' => null,
284+
'bit_flag' => 1,
285+
'boolean_flag' => false,
286+
'tiny_data' => 'c',
287+
'medium_data' => 'c',
288+
'long_data' => 'c',
289+
'json_blob_data' => '{}',
290+
],
291+
];
292+
293+
foreach ( $test_data as $data ) {
294+
$table::insert( $data );
295+
}
296+
297+
// Query by different boolean columns
298+
$active_results = $table::get_all_by( 'active_flag', true );
299+
$this->assertCount( 2, $active_results ); // "All True" and "Mixed"
300+
301+
$bit_true_results = $table::get_all_by( 'bit_flag', 1 );
302+
$this->assertCount( 2, $bit_true_results );
303+
304+
$boolean_false_results = $table::get_all_by( 'boolean_flag', false );
305+
$this->assertCount( 2, $boolean_false_results ); // "All False" and "Mixed"
306+
307+
// Test nullable featured_flag
308+
$featured_true = $table::get_all_by( 'featured_flag', true );
309+
$this->assertCount( 1, $featured_true );
310+
$this->assertEquals( 'All True', $featured_true[0]['name'] );
311+
}
312+
313+
/**
314+
* Test update operations with Boolean and Blob columns.
315+
*
316+
* @test
317+
*/
318+
public function should_update_boolean_and_blob_columns() {
319+
global $wpdb;
320+
321+
$table = $this->get_column_types_test_table();
322+
Register::table( $table );
323+
324+
// Insert initial data
325+
$initial = [
326+
'name' => 'Update Test',
327+
'active_flag' => true,
328+
'published_flag' => false,
329+
'bit_flag' => 1,
330+
'boolean_flag' => true,
331+
'tiny_data' => 'initial_tiny',
332+
'blob_data' => 'initial_blob',
333+
'medium_data' => 'initial_medium',
334+
'long_data' => 'initial_long',
335+
'json_blob_data' => json_encode( [ 'version' => 1 ] ),
336+
];
337+
338+
$table::insert( $initial );
339+
$insert_id = $wpdb->insert_id;
340+
341+
// Update with new values
342+
$update = [
343+
'id' => $insert_id,
344+
'active_flag' => false,
345+
'published_flag' => true,
346+
'bit_flag' => 0,
347+
'boolean_flag' => false,
348+
'blob_data' => 'updated_blob_' . str_repeat( 'X', 1000 ),
349+
'json_blob_data' => json_encode( [ 'version' => 2, 'updated' => true ] ),
350+
];
351+
352+
$result = $table::update_single( $update );
353+
$this->assertTrue( $result );
354+
355+
// Retrieve and verify
356+
$updated = $table::get_by_id( $insert_id );
357+
358+
// Check boolean updates
359+
$this->assertFalse( $updated['active_flag'] );
360+
$this->assertTrue( $updated['published_flag'] );
361+
$this->assertFalse( $updated['bit_flag'] );
362+
$this->assertFalse( $updated['boolean_flag'] );
363+
364+
// Check blob updates
365+
$this->assertStringContainsString( 'updated_blob_', $updated['blob_data'] );
366+
$this->assertStringContainsString( str_repeat( 'X', 1000 ), $updated['blob_data'] );
367+
368+
// Check JSON blob update
369+
$json_data = $updated['json_blob_data'];
370+
$this->assertEquals( 2, $json_data['version'] );
371+
$this->assertTrue( $json_data['updated'] );
372+
373+
// Check unchanged values
374+
$this->assertEquals( 'initial_tiny', $updated['tiny_data'] );
375+
$this->assertEquals( 'initial_medium', $updated['medium_data'] );
376+
}
377+
}

0 commit comments

Comments
 (0)