Skip to content

Commit

Permalink
[wip] custom table query methods
Browse files Browse the repository at this point in the history
  • Loading branch information
dpanta94 committed Nov 13, 2024
1 parent 4872ed8 commit 43d5f81
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/Common/Integrations/Custom_Table_Abstract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* Abstract for Custom Tables.
*
* @since TDB
*
* @package TEC\Common\Integrations
*/

namespace TEC\Common\Integrations;

use TEC\Common\StellarWP\Schema\Tables\Contracts\Table;

/**
* Class Integration_Abstract
*
* @since TBD
*
* @package TEC\Common\Integrations
*/
abstract class Custom_Table_Abstract extends Table {
use Traits\Custom_Table_Query_Methods;

/**
* @inheritDoc
*/
abstract protected function get_definition();
}
153 changes: 153 additions & 0 deletions src/Common/Integrations/Traits/Custom_Table_Query_Methods.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php
/**
* Provides query methods common to all custom tables.
*
* @since TBD
*
* @package TEC\Controller\Tables;
*/

namespace TEC\Common\Integrations\Traits;

use Generator;
use TEC\Common\StellarWP\DB\DB;
use Tribe__Cache as Cache;
use Tribe__Cache_Listener as Cache_Listener;

/**
* Trait Custom_Table_Query_Methods.
*
* @since TBD
*
* @package TEC\Controller\Tables;
*/
trait Custom_Table_Query_Methods {
/**
* Truncates the table.
*
* @since TBD
*
* @return bool|int The number of rows affected, or `false` on failure.
*/
public static function truncate() {
DB::query( 'SET FOREIGN_KEY_CHECKS = 0;' );
$deleted = DB::query(
DB::prepare(
'DELETE FROM %i',
static::table_name( true )
)
);
DB::query( 'SET FOREIGN_KEY_CHECKS = 1;' );

return $deleted;
}

/**
* Fetches all the rows from the table using a batched query.
*
* @since TBD
*
* @param int $batch_size The number of rows to fetch per batch.
* @param string $output The output type of the query, one of OBJECT, ARRAY_A, or ARRAY_N.
* @param string $where_clause The optional WHERE clause to use.
*
* @return Generator<array<string, mixed>> The rows from the table.
*/
public static function fetch_all( int $batch_size = 50, string $output = OBJECT, string $where_clause = '' ): Generator {
$fetched = 0;
$total = null;
$offset = 0;

do {
// On first iteration, we need to set the SQL_CALC_FOUND_ROWS flag.
$sql_calc_found_rows = 0 === $fetched ? 'SQL_CALC_FOUND_ROWS' : '';

$batch = DB::get_results(
DB::prepare(
"SELECT {$sql_calc_found_rows} * FROM %i {$where_clause} ORDER BY id LIMIT %d, %d",
static::table_name( true ),
$offset,
$batch_size
),
$output
);

// We need to get the total number of rows, only after the first batch.
$total ??= DB::get_var( 'SELECT FOUND_ROWS()' );
$fetched += count( $batch );

yield from $batch;
} while ( $fetched < $total );
}

/**
* Inserts multiple rows into the table.
*
* @since TBD
*
* @param array<mixed> $entries The entries to insert.
*
* @return bool|int The number of rows affected, or `false` on failure.
*/
public static function insert_many( array $entries ) {
$columns = array_keys( $entries[0] );
$prepared_columns = implode(
', ',
array_map(
static fn( string $column ) => "`$column`",
$columns
)
);
$prepared_values = implode(
', ',
array_map(
static function ( array $entry ) use ( $columns ) {
return '(' . implode( ', ', array_map( static fn( $e ) => DB::prepare( '%s', $e ), $entry ) ) . ')';
},
$entries
)
);

return DB::query(
DB::prepare(
"INSERT INTO %i ({$prepared_columns}) VALUES {$prepared_values}",
static::table_name( true ),
)
);
}

/**
* Fetches all the rows from the table using a batched query and a WHERE clause.
*
* @since TBD
*
* @param string $where_clause The WHERE clause to use.
* @param int $batch_size The number of rows to fetch per batch.
* @param string $output The output type of the query, one of OBJECT, ARRAY_A, or ARRAY_N.
*
* @return Generator<array<string, mixed>> The rows from the table.
*/
public static function fetch_all_where( string $where_clause, int $batch_size = 50, string $output = OBJECT ): Generator {
return static::fetch_all( $batch_size, $output, $where_clause );
}

/**
* Fetches the first row from the table using a WHERE clause.
*
* @since TBD
*
* @param string $where_clause The prepared WHERE clause to use.
* @param string $output The output type of the query, one of OBJECT, ARRAY_A, or ARRAY_N.
*
* @return array|object|null The row from the table, or `null` if no row was found.
*/
public static function fetch_first_where( string $where_clause, string $output = OBJECT ) {
return DB::get_row(
DB::prepare(
"SELECT * FROM %i {$where_clause} LIMIT 1",
static::table_name( true )
),
$output
);
}
}

0 comments on commit 43d5f81

Please sign in to comment.