Skip to content

Commit 74614b5

Browse files
committed
feat: Add JoinHelperTrait and enhance NamingResolver for join constant generation
1 parent 22fbdcc commit 74614b5

4 files changed

Lines changed: 115 additions & 65 deletions

File tree

src/Config.php

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -231,71 +231,6 @@ public function getNamingConfig(): array
231231
return $this->config['output']['naming'] ?? []; /////
232232
}
233233

234-
public function getNamingProfileConfig(string $profile = 'conventional'): array
235-
{
236-
return match ($profile) {
237-
'conventional' => [
238-
'strategy' => 'full',
239-
'table_concat_style' => 'literal',
240-
'separator' => 'double',
241-
'casing' => 'uppercase',
242-
'enum_prefix' => 'ev__',
243-
'fk_prefix' => 'fk__',
244-
],
245-
'concise' => [
246-
'strategy' => 'abbr',
247-
'table_concat_style' => 'literal',
248-
'separator' => 'single',
249-
'casing' => 'lowercase',
250-
'enum_prefix' => 'ev__',
251-
'fk_prefix' => 'fk__',
252-
],
253-
'compact' => [
254-
'strategy' => 'abbr',
255-
'table_concat_style' => 'concatenated',
256-
'separator' => 'single',
257-
'casing' => 'lowercase',
258-
'enum_prefix' => 'ev__',
259-
'fk_prefix' => 'fk_',
260-
],
261-
'alias' => [
262-
'strategy' => 'alias',
263-
'table_concat_style' => 'literal',
264-
'separator' => 'single',
265-
'casing' => 'lowercase',
266-
'enum_prefix' => 'ev__',
267-
'fk_prefix' => 'fk__',
268-
],
269-
'uppercase' => [
270-
'strategy' => 'full',
271-
'table_concat_style' => 'literal',
272-
'separator' => 'double',
273-
'casing' => 'uppercase',
274-
'enum_prefix' => 'EV__',
275-
'fk_prefix' => 'FK__',
276-
],
277-
'lowercase' => [
278-
'strategy' => 'full',
279-
'table_concat_style' => 'literal',
280-
'separator' => 'single',
281-
'casing' => 'lowercase',
282-
'enum_prefix' => 'ev__',
283-
'fk_prefix' => 'fk_',
284-
],
285-
default => [
286-
'strategy' => 'full',
287-
'table_concat_style' => 'literal',
288-
'separator' => 'double',
289-
'casing' => 'uppercase',
290-
'enum_prefix' => 'ev__',
291-
'fk_prefix' => 'fk__',
292-
],
293-
};
294-
}
295-
296-
297-
298-
299234
public function hasConnectionCallback(): bool
300235
{
301236
return !empty($this->get('database.connection'));

src/Generators/FileClassGenerator.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Eril\TblClass\Generators;
44

55
use Eril\TblClass\Config;
6+
use Eril\TblClass\Generators\Traits\JoinHelperTrait;
67
use Eril\TblClass\Resolvers\NamingResolver;
78
use Eril\TblClass\Schema\SchemaReaderInterface;
89
use RuntimeException;
@@ -19,6 +20,8 @@
1920
*/
2021
class FileClassGenerator extends Generator
2122
{
23+
use JoinHelperTrait;
24+
2225
private const SEPARATOR = " ";
2326
private NamingResolver $naming;
2427

@@ -139,6 +142,11 @@ private function generateTblClass(array $tables, array $foreignKeys): string
139142
}
140143
}
141144

145+
// --------------------------------------------------
146+
// Helpers
147+
// --------------------------------------------------
148+
$out .= $this->generateJoinHelper($foreignKeys);
149+
142150
$out .= "\n}\n";
143151

144152
return $out;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace Eril\TblClass\Generators\Traits;
4+
5+
trait JoinHelperTrait
6+
{
7+
protected function generateJoinHelper(array $foreignKeys): string
8+
{
9+
if (empty($foreignKeys)) {
10+
return '';
11+
}
12+
13+
$out = "\n";
14+
$out .= " /** JOIN helpers (auto-generated from foreign keys) */\n";
15+
16+
foreach ($foreignKeys as $fk) {
17+
18+
$constName = $this->naming->getOnJoinConstName(
19+
$fk['from_table'],
20+
$fk['to_table']
21+
);
22+
23+
// $constName = "on__{$fkConst}";
24+
$expr = "{$fk['from_table']}.{$fk['from_column']} = {$fk['to_table']}.{$fk['to_column']}";
25+
26+
$out .= " /** JOIN ON: `{$fk['from_table']}` → `{$fk['to_table']}` */";
27+
$out .= " public const {$constName} = '{$expr}';\n";
28+
}
29+
30+
$out .= $this->generateCallStatic();
31+
32+
return $out;
33+
}
34+
35+
private function generateCallStatic(): string
36+
{
37+
return <<<PHP
38+
39+
public static function __callStatic(string \$name, array \$args): string
40+
{
41+
if (str_starts_with(\$name, 'on__') && defined("self::\$name")) {
42+
\$e = constant("self::\$name");
43+
[\$fA, \$tA] = \$args + [null, null];
44+
if (!\$fA && !\$tA) return \$e;
45+
[\$f, \$t] = explode('__', substr(\$name, 4), 2);
46+
return str_replace([\$f . '.', \$t . '.'], [\$fA ? \$fA . '.' : \$f . '.', \$tA ? \$tA . '.' : \$t . '.'], \$e);
47+
}
48+
if (defined("self::" . strtoupper(\$name))) {
49+
return (\$a = \$args[0] ?? null) ? "\$name AS \$a" : \$name;
50+
}
51+
throw new \\BadMethodCallException("Undefined Tbl helper: \$name");
52+
}
53+
54+
PHP;
55+
}
56+
57+
private static function callStatic(string $name, array $args): string
58+
{
59+
// JOIN helper: on__from__to('f','t')
60+
if (str_starts_with($name, 'on__') && defined("self::" . $name)) {
61+
$expr = constant("self::" . $name);
62+
63+
// aliases: [from, to]
64+
[$fromAlias, $toAlias] = $args + [null, null];
65+
66+
if (!$fromAlias && !$toAlias) {
67+
return $expr;
68+
}
69+
70+
// replace table names by aliases
71+
[$from, $to] = explode('__', substr($name, 4), 2);
72+
73+
if ($fromAlias) {
74+
$expr = str_replace($from . '.', $fromAlias . '.', $expr);
75+
}
76+
77+
if ($toAlias) {
78+
$expr = str_replace($to . '.', $toAlias . '.', $expr);
79+
}
80+
81+
return $expr;
82+
}
83+
84+
// TABLE helper: Tbl::users('u') → "users AS u"
85+
if (defined("self::" . strtoupper($name))) {
86+
$alias = $args[0] ?? null;
87+
return $alias ? "$name AS $alias" : $name;
88+
}
89+
90+
throw new \BadMethodCallException("Undefined Tbl helper: {\$name}");
91+
}
92+
}

src/Resolvers/NamingResolver.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function __construct(array $naming = [])
2626
'strategy' => 'full',
2727
'separator' => 'double',
2828
'fk_prefix' => 'fk__',
29+
'join_prefix' => 'on__',
2930
'enum_prefix' => 'enum__',
3031
], $naming);
3132

@@ -131,6 +132,20 @@ public function getForeignKeyConstName(string $fromTable, string $toTable): stri
131132
return $this->applyCasing($this->config['fk_prefix'] . $from . $this->separator() . $to);
132133
}
133134

135+
public function getOnJoinConstName(string $fromTable, string $toTable): string
136+
{
137+
$strategy = $this->config['strategy'] == 'short' ? 'full' : $this->config['strategy'];
138+
$from = $this->resolveTablePart($fromTable, $strategy);
139+
$to = $this->resolveTablePart($toTable, $strategy);
140+
141+
if ($this->isConcatenated()) {
142+
$from = $this->concat($from);
143+
$to = $this->concat($to);
144+
}
145+
146+
return $this->applyCasing($this->config['join_prefix'] . $from . $this->separator() . $to);
147+
}
148+
134149
// ==========================================================
135150
// CORE LOGIC
136151
// ==========================================================

0 commit comments

Comments
 (0)