prepare($query); } catch (PDOException $ex) { $keyword = explode(' ', $query, 2)[0]; throw new DocumentException( sprintf("Error executing %s statement: [%s] %s", $keyword, Configuration::dbConn()->errorCode(), Configuration::dbConn()->errorInfo()[2]), previous: $ex); } foreach ($parameters as $key => $value) { if ($debug) echo "
Binding $value to $key\n
"; $dataType = match (true) { is_bool($value) => PDO::PARAM_BOOL, is_int($value) => PDO::PARAM_INT, is_null($value) => PDO::PARAM_NULL, default => PDO::PARAM_STR }; $stmt->bindValue($key, $value, $dataType); } if ($debug) echo '
SQL: ' . $stmt->queryString . '
'; try { if ($stmt->execute()) return $stmt; } catch (PDOException $ex) { $keyword = explode(' ', $query, 2)[0]; throw new DocumentException( sprintf("Error executing %s statement: [%s] %s", $keyword, $stmt->errorCode(), $stmt->errorInfo()[2]), previous: $ex); } $keyword = explode(' ', $query, 2)[0]; throw new DocumentException("Error executing $keyword statement: " . $stmt->errorCode()); } /** * Execute a query that returns a list of results (lazy) * * @template TDoc The domain type of the document to retrieve * @param string $query The query to be executed * @param array $parameters Parameters to use in executing the query * @param Mapper $mapper Mapper to deserialize the result * @return DocumentList The items matching the query * @throws DocumentException If any is encountered */ public static function list(string $query, array $parameters, Mapper $mapper): DocumentList { return DocumentList::create($query, $parameters, $mapper); } /** * Execute a query that returns an array of results (eager) * * @template TDoc The domain type of the document to retrieve * @param string $query The query to be executed * @param array $parameters Parameters to use in executing the query * @param Mapper $mapper Mapper to deserialize the result * @return TDoc[] The items matching the query * @throws DocumentException If any is encountered */ public static function array(string $query, array $parameters, Mapper $mapper): array { return iterator_to_array(self::list($query, $parameters, $mapper)->items()); } /** * Execute a query that returns one or no results (returns false if not found) * * @template TDoc The domain type of the document to retrieve * @param string $query The query to be executed (will have "LIMIT 1" appended) * @param array $parameters Parameters to use in executing the query * @param Mapper $mapper Mapper to deserialize the result * @return Option A `Some` instance if the item is found, `None` otherwise * @throws DocumentException If any is encountered */ public static function single(string $query, array $parameters, Mapper $mapper): Option { try { $stmt = &self::runQuery("$query LIMIT 1", $parameters); return ($first = $stmt->fetch(PDO::FETCH_ASSOC)) ? Some::create($mapper->map($first)) : None::create(); } finally { $stmt = null; } } /** * Execute a query that does not return a value * * @param string $query The query to execute * @param array $parameters Parameters to use in executing the query * @throws DocumentException If any is encountered */ public static function nonQuery(string $query, array $parameters): void { try { $stmt = &self::runQuery($query, $parameters); } finally { $stmt = null; } } /** * Execute a query that returns a scalar value * * @template T The scalar type to return * @param string $query The query to retrieve the value * @param array $parameters Parameters to use in executing the query * @param Mapper $mapper The mapper to obtain the result * @return mixed|false|T The scalar value if found, false if not * @throws DocumentException If any is encountered */ public static function scalar(string $query, array $parameters, Mapper $mapper): mixed { try { $stmt = &self::runQuery($query, $parameters); return ($first = $stmt->fetch(PDO::FETCH_NUM)) ? $mapper->map($first) : false; } finally { $stmt = null; } } }