diff --git a/README.md b/README.md index cd413f6..ce96baf 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,17 @@ $factory->open('users.db')->then(function (DatabaseInterface $db) { }); ``` +The `$filename` parameter is the path to the SQLite database file or +`:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an +empty string can be given to create a private, temporary on-disk database. +Relative paths will be resolved relative to the current working directory, +so it's usually recommended to pass absolute paths instead to avoid any +ambiguity. + +```php +$promise = $factory->open(__DIR__ . '/users.db'); +``` + The optional `$flags` parameter is used to determine how to open the SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`. @@ -145,6 +156,17 @@ Depending on your particular use case, you may prefer this method or the underlying `open()` method which resolves with a promise. For many simple use cases it may be easier to create a lazy connection. +The `$filename` parameter is the path to the SQLite database file or +`:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an +empty string can be given to create a private, temporary on-disk database. +Relative paths will be resolved relative to the current working directory, +so it's usually recommended to pass absolute paths instead to avoid any +ambiguity. + +```php +$$db = $factory->openLazy(__DIR__ . '/users.db'); +``` + The optional `$flags` parameter is used to determine how to open the SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`. diff --git a/src/Factory.php b/src/Factory.php index ad5c7f8..c8212d5 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -67,6 +67,17 @@ public function __construct(LoopInterface $loop) * }); * ``` * + * The `$filename` parameter is the path to the SQLite database file or + * `:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an + * empty string can be given to create a private, temporary on-disk database. + * Relative paths will be resolved relative to the current working directory, + * so it's usually recommended to pass absolute paths instead to avoid any + * ambiguity. + * + * ```php + * $promise = $factory->open(__DIR__ . '/users.db'); + * ``` + * * The optional `$flags` parameter is used to determine how to open the * SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`. * @@ -85,6 +96,7 @@ public function __construct(LoopInterface $loop) */ public function open($filename, $flags = null) { + $filename = $this->resolve($filename); return $this->useSocket ? $this->openSocketIo($filename, $flags) : $this->openProcessIo($filename, $flags); } @@ -135,6 +147,17 @@ public function open($filename, $flags = null) * underlying `open()` method which resolves with a promise. For many * simple use cases it may be easier to create a lazy connection. * + * The `$filename` parameter is the path to the SQLite database file or + * `:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an + * empty string can be given to create a private, temporary on-disk database. + * Relative paths will be resolved relative to the current working directory, + * so it's usually recommended to pass absolute paths instead to avoid any + * ambiguity. + * + * ```php + * $db = $factory->openLazy(__DIR__ . '/users.db'); + * ``` + * * The optional `$flags` parameter is used to determine how to open the * SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`. * @@ -162,7 +185,7 @@ public function open($filename, $flags = null) */ public function openLazy($filename, $flags = null, array $options = []) { - return new LazyDatabase($filename, $flags, $options, $this, $this->loop); + return new LazyDatabase($this->resolve($filename), $flags, $options, $this, $this->loop); } private function openProcessIo($filename, $flags = null) @@ -318,4 +341,16 @@ private function which($bin) } return null; } + + /** + * @param string $filename + * @return string + */ + private function resolve($filename) + { + if ($filename !== '' && $filename !== ':memory:' && !\preg_match('/^\/|\w+\:\\\\/', $filename)) { + $filename = \getcwd() . \DIRECTORY_SEPARATOR . $filename; + } + return $filename; + } } diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 66fa5e2..7d0cf91 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -28,4 +28,69 @@ public function testLoadLazyWithIdleOptionsReturnsDatabaseWithIdleTimeApplied() $this->assertEquals(10.0, $value); } + + public function testLoadLazyWithAbsolutePathWillBeUsedAsIs() + { + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $factory = new Factory($loop); + + $db = $factory->openLazy(__DIR__ . '/users.db'); + + $ref = new ReflectionProperty($db, 'filename'); + $ref->setAccessible(true); + $value = $ref->getValue($db); + + $this->assertEquals(__DIR__ . '/users.db', $value); + } + + public function testLoadLazyWithMemoryPathWillBeUsedAsIs() + { + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $factory = new Factory($loop); + + $db = $factory->openLazy(':memory:'); + + $ref = new ReflectionProperty($db, 'filename'); + $ref->setAccessible(true); + $value = $ref->getValue($db); + + $this->assertEquals(':memory:', $value); + } + + public function testLoadLazyWithEmptyPathWillBeUsedAsIs() + { + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $factory = new Factory($loop); + + $db = $factory->openLazy(''); + + $ref = new ReflectionProperty($db, 'filename'); + $ref->setAccessible(true); + $value = $ref->getValue($db); + + $this->assertEquals('', $value); + } + + public function testLoadLazyWithRelativePathWillBeResolvedWhenConstructingAndWillNotBeAffectedByChangingDirectory() + { + $original = getcwd(); + if ($original === false) { + $this->markTestSkipped('Unable to detect current working directory'); + } + + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $factory = new Factory($loop); + + $db = $factory->openLazy('users.db'); + + chdir('../'); + + $ref = new ReflectionProperty($db, 'filename'); + $ref->setAccessible(true); + $value = $ref->getValue($db); + + chdir($original); + + $this->assertEquals($original . DIRECTORY_SEPARATOR . 'users.db', $value); + } }