async->queryMultiple() */ final readonly class AsyncDatabaseAdapter { public function __construct( private ConnectionInterface $connection, private AsyncService $asyncService ) { } /** * Execute query asynchronously */ public function query(string $sql, array $parameters = []): AsyncPromise { return $this->asyncService->promise( fn () => $this->connection->query($sql, $parameters) ); } /** * Execute queryOne asynchronously */ public function queryOne(string $sql, array $parameters = []): AsyncPromise { return $this->asyncService->promise( fn () => $this->connection->queryOne($sql, $parameters) ); } /** * Execute queryScalar asynchronously */ public function queryScalar(string $sql, array $parameters = []): AsyncPromise { return $this->asyncService->promise( fn () => $this->connection->queryScalar($sql, $parameters) ); } /** * Execute queryColumn asynchronously */ public function queryColumn(string $sql, array $parameters = []): AsyncPromise { return $this->asyncService->promise( fn () => $this->connection->queryColumn($sql, $parameters) ); } /** * Execute statement asynchronously */ public function execute(string $sql, array $parameters = []): AsyncPromise { return $this->asyncService->promise( fn () => $this->connection->execute($sql, $parameters) ); } /** * Execute multiple queries in parallel */ public function queryMultiple(array $queries): array { $operations = []; foreach ($queries as $key => $queryData) { $sql = $queryData['sql'] ?? $queryData; $params = $queryData['params'] ?? []; $operations[$key] = fn () => $this->connection->query($sql, $params); } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Parallel data aggregation from multiple tables */ public function aggregate(array $namedQueries): array { $operations = []; foreach ($namedQueries as $name => $queryData) { $operations[$name] = function () use ($queryData) { try { $sql = $queryData['sql'] ?? $queryData; $params = $queryData['params'] ?? []; $method = $queryData['method'] ?? 'query'; $result = match($method) { 'queryOne' => $this->connection->queryOne($sql, $params), 'queryColumn' => $this->connection->queryColumn($sql, $params), 'queryScalar' => $this->connection->queryScalar($sql, $params), default => $this->connection->query($sql, $params), }; return [ 'success' => true, 'data' => $result, 'error' => null, ]; } catch (\Exception $e) { return [ 'success' => false, 'data' => null, 'error' => $e->getMessage(), ]; } }; } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Batch insert operations */ public function batchInsert(string $table, array $columns, array $rows, int $batchSize = 100): array { if (empty($rows)) { return []; } $batches = array_chunk($rows, $batchSize); $placeholders = '(' . str_repeat('?,', count($columns) - 1) . '?)'; $operations = []; foreach ($batches as $i => $batch) { $operations["batch_$i"] = function () use ($table, $columns, $batch, $placeholders) { $values = str_repeat($placeholders . ',', count($batch) - 1) . $placeholders; $sql = "INSERT INTO `$table` (`" . implode('`, `', $columns) . "`) VALUES $values"; $params = []; foreach ($batch as $row) { $params = array_merge($params, array_values($row)); } return $this->connection->execute($sql, $params); }; } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Batch update operations */ public function batchUpdate(string $table, array $updates, string $keyColumn = 'id', int $batchSize = 50): array { if (empty($updates)) { return []; } $batches = array_chunk($updates, $batchSize); $operations = []; foreach ($batches as $i => $batch) { $operations["batch_$i"] = function () use ($table, $batch, $keyColumn) { $affected = 0; foreach ($batch as $update) { $keyValue = $update[$keyColumn]; unset($update[$keyColumn]); $setParts = []; $params = []; foreach ($update as $column => $value) { $setParts[] = "`$column` = ?"; $params[] = $value; } $params[] = $keyValue; $sql = "UPDATE `$table` SET " . implode(', ', $setParts) . " WHERE `$keyColumn` = ?"; $affected += $this->connection->execute($sql, $params); } return $affected; }; } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Parallel read-ahead for related data */ public function readAhead(array $queries, ?Duration $timeout = null): array { $timeout ??= Duration::fromSeconds(10); $operations = []; foreach ($queries as $key => $queryData) { $operations[$key] = function () use ($queryData, $timeout) { return $this->asyncService->withTimeout(function () use ($queryData) { $sql = $queryData['sql'] ?? $queryData; $params = $queryData['params'] ?? []; $method = $queryData['method'] ?? 'query'; return match($method) { 'queryOne' => $this->connection->queryOne($sql, $params), 'queryColumn' => $this->connection->queryColumn($sql, $params), 'queryScalar' => $this->connection->queryScalar($sql, $params), default => $this->connection->query($sql, $params), }; }, $timeout); }; } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Parallel replica queries (if ReadWriteConnection is used) */ public function queryReplicas(string $sql, array $parameters = []): array { if (! ($this->connection instanceof ReadWriteConnection)) { // Fallback to single query return [$this->connection->query($sql, $parameters)]; } $readConnections = $this->connection->getReadConnections(); if (count($readConnections) <= 1) { return [$this->connection->query($sql, $parameters)]; } $operations = []; foreach ($readConnections as $i => $readConnection) { $operations["replica_$i"] = fn () => $readConnection->query($sql, $parameters); } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Transaction with timeout */ public function transactionWithTimeout(callable $callback, ?Duration $timeout = null): mixed { $timeout ??= Duration::fromSeconds(30); return $this->asyncService->withTimeout(function () use ($callback) { $this->connection->beginTransaction(); try { $result = $callback($this->connection); $this->connection->commit(); return $result; } catch (\Exception $e) { $this->connection->rollback(); throw $e; } }, $timeout); } /** * Parallel table statistics collection */ public function getTableStats(array $tables): array { $operations = []; foreach ($tables as $table) { $operations[$table] = function () use ($table) { try { $stats = []; // Row count $stats['row_count'] = $this->connection->queryScalar( "SELECT COUNT(*) FROM `$table`" ); // Table size (MySQL specific) $sizeResult = $this->connection->queryOne( "SELECT ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) AS size_mb, DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE table_schema = DATABASE() AND table_name = ?", [$table] ); $stats['size_mb'] = $sizeResult['size_mb'] ?? 0; $stats['data_size'] = $sizeResult['DATA_LENGTH'] ?? 0; $stats['index_size'] = $sizeResult['INDEX_LENGTH'] ?? 0; return $stats; } catch (\Exception $e) { return ['error' => $e->getMessage()]; } }; } $results = $this->asyncService->parallel($operations); return $results->await(); } /** * Get statistics */ public function getStats(): array { return [ 'async_enabled' => true, 'async_stats' => $this->asyncService->getStats(), ]; } }