1unitedpower: funktionalität in Konstruktoren ähnlicher Klassen besser machen???

Beitrag lesen

das sehe ich anders. Das ist keine Frage der beteiligten Operanden, sondern eine Frage der SQL Generierung. Der Query-Builder verwendet Spaltennamen und Literale, denen es im Sinne von Separation-of-Concerns egal sein sollte, ob inline-Werte oder prepare verwendet wird - das sollte komplett und transparent vom der SQL Generierung behandelt werden.

Ja, da gehe ich mit. In meinem Beispiel sind AST und CodeGenierung gekoppelt. Man kann sie entkoppeln, indem man den Knoten Getter verpasst und die toSQL-Methoden auslagert. Entweder in eine große Funktion mit einem riesigen if-else-Konstrukt, oder in jeweils eizelne Funktionen. Also, zum Beipsiel so:

final class Between implements BooleanValue {

    private NumericalValue $value;

    private NumericalValue $min;

    private NumericalValue $max;

    public function __construct(NumericalValue $value, NumericalValue $min, NumericalValue $max)
    {
        $this->value = $value;
        $this->min = $min;
        $this->max = $max;
    }

    public function value() : NumericalValue
    {
        return $this->value;
    }

    public function min() : NumericalValue
    {
        return $this->min;
    }

    public function max() : NumericalValue
    {
        return $this->max;
    }

}
final class Generator {

    public static function between(Between $node) : string
    {
        $value = Generator::number($node->value());
        $min = Generator::number($node->min());
        $max = Generator::number($node->max());
        return " $value BETWEEN $min AND $max ";
    }
    
    public static function number(NumericalValue $node) : string
    {
        if ($node instanceof NumberLiteral) {
            return (string)$node->value();
        } elseif ($node instanceof NumberPlaceholder) {
            return " ? ";
        } elseif ($node instanceof NumberColumn) {
            return Generator::column($node);
        }
    }

    // usw.
}

Statt einer einzelnen Generator-Klasse könnte man auch für jeden Knoten-Typen jeweils eine Generator-Klasse haben mit einem gemeinsamen Interface.