It can't access files that should have been created
Closed this issue · 6 comments
Version: dev-master
Bug Description
It throws failed to open stream: No such file or directory in \database-explorer\vendor\nette\caching\src\Caching\Storages\FileStorage.php on 137 line
. It creates a _Nette.Database.Structure.0f6c8930e1b455996fff524bc1a51b4b
folder and a _07414f4e15ca943e6cde032dec85d92f
file inside that folder. But for some reason, it doesn't create the other folder and file and tries to access it afterwards.
Steps To Reproduce
The only think I've done was to create the following index.php file.
<?php
include('vendor/autoload.php');
use Nette\Database\Connection;
$tempDir = "./cache/database-explorer";
$storage = new Nette\Caching\Storages\FileStorage($tempDir);
$connection = new Nette\Database\Connection("pgsql:host=localhost;dbname=DBNAME;options='--client_encoding=utf8'", "postgres", "PASSWORD");
$structure = new Nette\Database\Structure($connection, $storage);
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$context = new Nette\Database\Context($connection, $structure, $conventions, $storage);
$rows = $context->table('notifications');
foreach ($rows as $row) {
echo $row->timestamp;
}
Expected Behavior
No errors.
Possible Solution
Only evaluating the library. I really like the simplicity of the idea behind it. Congrats to the developers that came up with it.
So, exactly 2 years later I came back to give it another try and the same error occurs. Different PC, PHP version, but same error. Is this project maintained yet?
Changing FileStorage.php:137 to:
$handle = @fopen($cacheFile, 'c+b'); // added '@'
makes the error go away, but I guess we lose the cache.
am also receiving the same error, and the only way I can suppress the error is by turning off the E_WARNING every time I use the explore functionality which I personally think it's a bad idea, is there a workaround to suppress the error without hiding all warnings and or without losing the cache, here is my implementation
<?php
use Nette\Database\Explorer;
use Nette\Database\Structure;
use Nette\Database\Connection;
use Nette\Caching\Storages\FileStorage;
use Nette\Database\Conventions\DiscoveredConventions;
class DB{
private $storage;
private $structure;
private $conventions;
function __construct(){
$this->storage = new FileStorage('cache/db');
$this->structure = new Structure($this->conn(), $this->storage);
$this->conventions = new DiscoveredConventions($this->structure);
}
function conn(){
$engine = config('db_engine');
switch ($engine):
case 'mysql':
$hostname = config('db_host');
$username = config('db_user');
$password = config('db_pass');
$database = config('db_name');
$connector = "mysql:host=$hostname;dbname=$database";
return new Connection(
$connector, $username, $password
); break;
endswitch;
}
function explore(){
error_reporting(E_ALL & ~E_WARNING);
return new Explorer($this->conn(), $this->structure, $this->conventions, $this->storage);
}
}
Couldn't the problem be the use of relative path? I.e. use for example FileStorage(__DIR__ . '/cache/db')
Couldn't the problem be the use of relative path? I.e. use for example
FileStorage(__DIR__ . '/cache/db')
I don't think that's the case because
- with
FileStorage(__DIR__ . '/cache/db')
the error isDirectory '/myRoot/project\core/cache/db' not found
and the error occurs from the constructor, and this is because the cache folder is on the project basepath and DIR is relative to the execution file meanwhile cache folder is at'/myRoot/project\cache/db
public function __construct(string $dir, ?Journal $journal = null)
{
if (!is_dir($dir)) {
throw new Nette\DirectoryNotFoundException("Directory '$dir' not found."); # <<< error is thrown on this line
}
$this->dir = $dir;
$this->journal = $journal;
if (mt_rand() / mt_getrandmax() < static::$gcProbability) {
$this->clean([]);
}
}
- with
FileStorage('cache/db');
everything works fine, the cache folders and files are also created successfully, the error occurs while trying to lock the cache filefopen(cache/db/_Nette.Database.cacheCode/_cacheRef): Failed to open stream: No such file or directory
public function lock(string $key): void
{
$cacheFile = $this->getCacheFile($key);
if (!is_dir($dir = dirname($cacheFile))) {
@mkdir($dir); // @ - directory may already exist
}
$handle = fopen($cacheFile, 'c+b'); # <<< error happens here
if (!$handle) {
return;
}
$this->locks[$key] = $handle;
flock($handle, LOCK_EX);
}