-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathQueryCollectionFactory.php
More file actions
123 lines (101 loc) · 2.64 KB
/
QueryCollectionFactory.php
File metadata and controls
123 lines (101 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
namespace Gt\Database\Query;
use DirectoryIterator;
use Gt\Database\Connection\Driver;
use Gt\Database\Database;
use SplFileInfo;
class QueryCollectionFactory {
protected Driver $driver;
protected string $basePath;
/** @var array<string, QueryCollection> */
protected array $queryCollectionCache;
public function __construct(Driver $driver) {
$this->driver = $driver;
$this->basePath = $this->driver->getBaseDirectory();
$this->queryCollectionCache = [];
}
public function create(string $name):QueryCollection {
if(!isset($this->queryCollectionCache[$name])) {
$this->queryCollectionCache[$name] = $this->findQueryCollection(
$name,
$this->driver,
);
}
return $this->queryCollectionCache[$name];
}
public function directoryExists(string $name):bool {
return !is_null($this->locateDirectory($name));
}
/**
* Case-insensitive attempt to match the provided directory name with a
* directory within the basePath.
* @param string $name Name of the QueryCollection
* @return string Absolute path to directory
*/
protected function locateDirectory(string $name):?string {
$parts = [$name];
foreach(Database::COLLECTION_SEPARATOR_CHARACTERS as $char) {
if(!strstr($name, $char)) {
continue;
}
$parts = explode($char, $name);
break;
}
return $this->recurseLocateDirectory($parts);
}
/** @param array<string> $parts */
protected function recurseLocateDirectory(
array $parts,
?string $basePath = null
):?string {
$part = array_shift($parts);
if(is_null($basePath)) {
$basePath = $this->basePath;
}
if(!is_dir($basePath)) {
throw new BaseQueryPathDoesNotExistException($basePath);
}
foreach(new DirectoryIterator($basePath) as $fileInfo) {
if($fileInfo->isDot()) {
continue;
}
$basename = $fileInfo->getBasename(".php");
if(strtolower($part) === strtolower($basename)) {
$realPath = $fileInfo->getRealPath();
if(empty($parts)) {
return $realPath;
}
return $this->recurseLocateDirectory(
$parts,
$realPath
);
}
}
return null;
}
protected function getDefaultBasePath():string {
return getcwd();
}
private function findQueryCollection(
string $name,
Driver $driver,
):QueryCollection {
$path = $this->locateDirectory($name);
if($path && is_dir($path)) {
$this->queryCollectionCache[$name] = new QueryCollectionDirectory(
$path,
$driver,
);
}
elseif($path && is_file($path)) {
$this->queryCollectionCache[$name] = new QueryCollectionClass(
$path,
$driver,
);
}
else {
throw new QueryCollectionNotFoundException($name);
}
return $this->queryCollectionCache[$name];
}
}