Skip to content

Commit a8c8d26

Browse files
authored
Merge pull request #24 from clue-labs/relative-paths
Resolve relative paths to SQLite database files in Factory
2 parents 6fbb033 + 5075fb3 commit a8c8d26

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ $factory->open('users.db')->then(function (DatabaseInterface $db) {
8484
});
8585
```
8686

87+
The `$filename` parameter is the path to the SQLite database file or
88+
`:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an
89+
empty string can be given to create a private, temporary on-disk database.
90+
Relative paths will be resolved relative to the current working directory,
91+
so it's usually recommended to pass absolute paths instead to avoid any
92+
ambiguity.
93+
94+
```php
95+
$promise = $factory->open(__DIR__ . '/users.db');
96+
```
97+
8798
The optional `$flags` parameter is used to determine how to open the
8899
SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`.
89100

@@ -145,6 +156,17 @@ Depending on your particular use case, you may prefer this method or the
145156
underlying `open()` method which resolves with a promise. For many
146157
simple use cases it may be easier to create a lazy connection.
147158

159+
The `$filename` parameter is the path to the SQLite database file or
160+
`:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an
161+
empty string can be given to create a private, temporary on-disk database.
162+
Relative paths will be resolved relative to the current working directory,
163+
so it's usually recommended to pass absolute paths instead to avoid any
164+
ambiguity.
165+
166+
```php
167+
$$db = $factory->openLazy(__DIR__ . '/users.db');
168+
```
169+
148170
The optional `$flags` parameter is used to determine how to open the
149171
SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`.
150172

src/Factory.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ public function __construct(LoopInterface $loop)
6767
* });
6868
* ```
6969
*
70+
* The `$filename` parameter is the path to the SQLite database file or
71+
* `:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an
72+
* empty string can be given to create a private, temporary on-disk database.
73+
* Relative paths will be resolved relative to the current working directory,
74+
* so it's usually recommended to pass absolute paths instead to avoid any
75+
* ambiguity.
76+
*
77+
* ```php
78+
* $promise = $factory->open(__DIR__ . '/users.db');
79+
* ```
80+
*
7081
* The optional `$flags` parameter is used to determine how to open the
7182
* SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`.
7283
*
@@ -85,6 +96,7 @@ public function __construct(LoopInterface $loop)
8596
*/
8697
public function open($filename, $flags = null)
8798
{
99+
$filename = $this->resolve($filename);
88100
return $this->useSocket ? $this->openSocketIo($filename, $flags) : $this->openProcessIo($filename, $flags);
89101
}
90102

@@ -135,6 +147,17 @@ public function open($filename, $flags = null)
135147
* underlying `open()` method which resolves with a promise. For many
136148
* simple use cases it may be easier to create a lazy connection.
137149
*
150+
* The `$filename` parameter is the path to the SQLite database file or
151+
* `:memory:` to create a temporary in-memory database. As of PHP 7.0.10, an
152+
* empty string can be given to create a private, temporary on-disk database.
153+
* Relative paths will be resolved relative to the current working directory,
154+
* so it's usually recommended to pass absolute paths instead to avoid any
155+
* ambiguity.
156+
*
157+
* ```php
158+
* $db = $factory->openLazy(__DIR__ . '/users.db');
159+
* ```
160+
*
138161
* The optional `$flags` parameter is used to determine how to open the
139162
* SQLite database. By default, open uses `SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE`.
140163
*
@@ -162,7 +185,7 @@ public function open($filename, $flags = null)
162185
*/
163186
public function openLazy($filename, $flags = null, array $options = [])
164187
{
165-
return new LazyDatabase($filename, $flags, $options, $this, $this->loop);
188+
return new LazyDatabase($this->resolve($filename), $flags, $options, $this, $this->loop);
166189
}
167190

168191
private function openProcessIo($filename, $flags = null)
@@ -318,4 +341,16 @@ private function which($bin)
318341
}
319342
return null;
320343
}
344+
345+
/**
346+
* @param string $filename
347+
* @return string
348+
*/
349+
private function resolve($filename)
350+
{
351+
if ($filename !== '' && $filename !== ':memory:' && !\preg_match('/^\/|\w+\:\\\\/', $filename)) {
352+
$filename = \getcwd() . \DIRECTORY_SEPARATOR . $filename;
353+
}
354+
return $filename;
355+
}
321356
}

tests/FactoryTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,69 @@ public function testLoadLazyWithIdleOptionsReturnsDatabaseWithIdleTimeApplied()
2828

2929
$this->assertEquals(10.0, $value);
3030
}
31+
32+
public function testLoadLazyWithAbsolutePathWillBeUsedAsIs()
33+
{
34+
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
35+
$factory = new Factory($loop);
36+
37+
$db = $factory->openLazy(__DIR__ . '/users.db');
38+
39+
$ref = new ReflectionProperty($db, 'filename');
40+
$ref->setAccessible(true);
41+
$value = $ref->getValue($db);
42+
43+
$this->assertEquals(__DIR__ . '/users.db', $value);
44+
}
45+
46+
public function testLoadLazyWithMemoryPathWillBeUsedAsIs()
47+
{
48+
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
49+
$factory = new Factory($loop);
50+
51+
$db = $factory->openLazy(':memory:');
52+
53+
$ref = new ReflectionProperty($db, 'filename');
54+
$ref->setAccessible(true);
55+
$value = $ref->getValue($db);
56+
57+
$this->assertEquals(':memory:', $value);
58+
}
59+
60+
public function testLoadLazyWithEmptyPathWillBeUsedAsIs()
61+
{
62+
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
63+
$factory = new Factory($loop);
64+
65+
$db = $factory->openLazy('');
66+
67+
$ref = new ReflectionProperty($db, 'filename');
68+
$ref->setAccessible(true);
69+
$value = $ref->getValue($db);
70+
71+
$this->assertEquals('', $value);
72+
}
73+
74+
public function testLoadLazyWithRelativePathWillBeResolvedWhenConstructingAndWillNotBeAffectedByChangingDirectory()
75+
{
76+
$original = getcwd();
77+
if ($original === false) {
78+
$this->markTestSkipped('Unable to detect current working directory');
79+
}
80+
81+
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
82+
$factory = new Factory($loop);
83+
84+
$db = $factory->openLazy('users.db');
85+
86+
chdir('../');
87+
88+
$ref = new ReflectionProperty($db, 'filename');
89+
$ref->setAccessible(true);
90+
$value = $ref->getValue($db);
91+
92+
chdir($original);
93+
94+
$this->assertEquals($original . DIRECTORY_SEPARATOR . 'users.db', $value);
95+
}
3196
}

0 commit comments

Comments
 (0)