Skip to content

Commit

Permalink
Merge 3bd8ff6 into 7d4f79d
Browse files Browse the repository at this point in the history
  • Loading branch information
klapuch committed Oct 24, 2020
2 parents 7d4f79d + 3bd8ff6 commit 3a8d835
Show file tree
Hide file tree
Showing 68 changed files with 586 additions and 2,033 deletions.
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ sudo: required

services:
- postgresql
- redis-server

addons:
postgresql: 9.5
postgresql: 10

language: php

php:
- 7.3
- 7.4

before_install:
- composer self-update
Expand All @@ -24,11 +23,11 @@ before_script:
- psql -U postgres storage < ./Tests/fixtures/schema.sql

script:
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]]; then vendor/bin/phing ci; else vendor/bin/phing; fi
- vendor/bin/phing ci

after_script:
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]]; then wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar && php coveralls.phar --verbose --config Tests/.coveralls.yml; fi
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]]; then php coveralls.phar --verbose --config Tests/.coveralls.yml; fi
- wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar && php coveralls.phar --verbose --config Tests/.coveralls.yml
- php coveralls.phar --verbose --config Tests/.coveralls.yml

after_failure:
- for i in $(find Tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done
57 changes: 0 additions & 57 deletions Core/BuiltQuery.php

This file was deleted.

16 changes: 5 additions & 11 deletions Core/CachedConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,24 @@
* Cached database connection
*/
class CachedConnection implements Connection {
/** @var \Klapuch\Storage\Connection */
private $origin;
private Connection $origin;

/** @var \SplFileInfo */
private $temp;
private \SplFileInfo $temp;

public function __construct(Connection $origin, \SplFileInfo $temp) {
$this->origin = $origin;
$this->temp = $temp;
}

public function prepare($statement): \PDOStatement {
public function prepare(string $statement): \PDOStatement {
return new CachedPDOStatement(
$this->origin->prepare($statement),
$statement,
$this->temp
$this->temp,
);
}

public function exec(string $statement): void {
$this->origin->exec($statement);
}

public function schema(): Schema {
return new CachedSchema($this, $this->temp);
}
}
}
97 changes: 59 additions & 38 deletions Core/CachedPDOStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,19 @@

namespace Klapuch\Storage;

use Klapuch\Lock;

final class CachedPDOStatement extends \PDOStatement {
private const NAMESPACE = 'postgres_column_meta';

/** @var mixed[] */
private static $cache = [];
private \PDOStatement $origin;

/** @var \PDOStatement */
private $origin;
private string $statement;

/** @var string */
private $statement;
private \SplFileInfo $temp;

/** @var \SplFileInfo */
private $temp;
/** @var array<string, array<mixed, mixed>> */
private static array $cache = [];

public function __construct(
\PDOStatement $origin,
string $statement,
\SplFileInfo $temp
) {
public function __construct(\PDOStatement $origin, string $statement, \SplFileInfo $temp) {
$this->origin = $origin;
$this->statement = $statement;
$this->temp = $temp;
Expand All @@ -34,25 +25,23 @@ public function execute($inputParameters = null): bool {
return $this->origin->execute(...func_get_args());
}

public function fetch(
$fetchStyle = null,
$cursorOrientation = \PDO::FETCH_ORI_NEXT,
$cursorOffset = 0
): array {
return $this->origin->fetch(...func_get_args()) ?: [];
/**
* @return mixed[]
*/
public function fetch($fetchStyle = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0): array {
$row = $this->origin->fetch(...func_get_args());
return $row === false ? [] : $row;
}

public function fetchAll(
$fetchStyle = null,
$fetchArgument = null,
$ctorArgs = null
): array {
/**
* @return mixed[]
*/
public function fetchAll($fetchStyle = null, $fetchArgument = null, $ctorArgs = null): array {
return (array) $this->origin->fetchAll(...func_get_args());
}

/**
* @param int $columnNumber
* @return mixed
* @return int|string|false|null
*/
public function fetchColumn($columnNumber = 0) {
return $this->origin->fetchColumn(...func_get_args());
Expand All @@ -62,23 +51,55 @@ public function columnCount(): int {
return $this->origin->columnCount();
}

/**
* @param mixed $column
* @return array<string, array<mixed, mixed>>
*/
public function getColumnMeta($column): array {
$dir = implode(DIRECTORY_SEPARATOR, [$this->temp->getPathname(), self::NAMESPACE, md5($this->statement)]);
$filename = sprintf('%s/%d.php', $dir, $column);
if (isset(self::$cache[$filename][$column])) {
return self::$cache[$filename][$column];
}
if (!is_file($filename)) {
(new Lock\Semaphore($filename))->synchronized(function () use ($dir, $column, $filename): void {
if (!is_file($filename)) {
@mkdir($dir, 0777, true); // @ directory may exists
if (@file_put_contents($filename, sprintf('<?php return %s;', var_export($this->origin->getColumnMeta($column), true))) === false) {
throw new \RuntimeException(sprintf('File is "%s" is not writable', $filename));
}
}
});
if (!is_dir($dir) && !@mkdir($dir, 0777, true)) {
throw new \RuntimeException('Can not create directory.');
}
$this->cache(new \SplFileInfo($filename), self::raw($this->origin->getColumnMeta($column)));
self::$cache[$filename][$column] = require $filename;
return self::$cache[$filename][$column];
}
}

private function cache(\SplFileInfo $file, string $data): void
{
if (!$file->isFile()) {
$lock = sprintf('%s.lock', $file->getPathname());
$handle = fopen($lock, 'c+');
if ($handle === false || !flock($handle, LOCK_EX)) {
throw new \RuntimeException(
\sprintf('Unable to create or acquire exclusive lock on file "%s".', $lock),
);
}
if (!$file->isFile()) {
$temp = sprintf('%s.temp', $file->getPathname());
if (@file_put_contents($temp, $data) === false) {
throw new \RuntimeException(sprintf('Can not write to file "%s".', $temp));
}
rename($temp, $file->getPathname()); // atomic replace
if (function_exists('opcache_invalidate')) {
opcache_invalidate($file->getPathname(), true);
}
}
flock($handle, LOCK_UN);
fclose($handle);
@unlink($lock); // intentionally @ - file may become locked on Windows
}
}

/**
* @param mixed[] $data
*/
private static function raw(array $data): string
{
return sprintf('<?php return %s;', var_export($data, true));
}
}
91 changes: 0 additions & 91 deletions Core/CachedSchema.php

This file was deleted.

4 changes: 2 additions & 2 deletions Core/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

interface Connection {
public function prepare(string $statement): \PDOStatement;

public function exec(string $statement): void;
public function schema(): Schema;
}
}
Loading

0 comments on commit 3a8d835

Please sign in to comment.