compileComponents($query), function ($value) { return (string) $value !== ''; } ) ) ) . ';'; } /** * Compile query components. * * @param BuilderAbstract $query Builder * * @return array Parsed query components * * @since 1.0.0 */ abstract protected function compileComponents(BuilderAbstract $query) : array; /** * Get date format. * * @return string * * @since 1.0.0 */ public function getDateFormat() : string { return 'Y-m-d H:i:s'; } /** * Get table prefix. * * @return string * * @since 1.0.0 */ public function getTablePrefix() : string { return $this->tablePrefix; } /** * Set table prefix. * * @param string $prefix Table prefix * * @since 1.0.0 */ public function setTablePrefix(string $prefix) /* : void */ { $this->tablePrefix = $prefix; } /** * Expressionize elements. * * @param array $elements Elements * @param string $prefix Prefix for table * * @return string * * @since 1.0.0 */ protected function expressionizeTableColumn(array $elements, string $prefix = '') : string { $expression = ''; foreach ($elements as $key => $element) { if (is_string($element) && $element !== '*') { if (strpos($element, '.') === false) { $prefix = ''; } $expression .= $this->compileSystem($element, $prefix) . ', '; } elseif (is_string($element) && $element === '*') { $expression .= '*, '; } elseif ($element instanceof \Closure) { $expression .= $element() . ', '; } elseif ($element instanceof BuilderAbstract) { $expression .= $element->toSql() . ', '; } else { throw new \InvalidArgumentException(); } } return rtrim($expression, ', '); } /** * Expressionize elements. * * @param array $elements Elements * @param string $prefix Prefix for table * * @return string * * @since 1.0.0 */ protected function expressionizeTable(array $elements, string $prefix = '') : string { $expression = ''; foreach ($elements as $key => $element) { if (is_string($element) && $element !== '*') { $expression .= $this->compileSystem($element, $prefix) . ', '; } elseif (is_string($element) && $element === '*') { $expression .= '*, '; } elseif ($element instanceof \Closure) { $expression .= $element() . ', '; } elseif ($element instanceof BuilderAbstract) { $expression .= $element->toSql() . ', '; } else { throw new \InvalidArgumentException(); } } return rtrim($expression, ', '); } /** * Compile system. * * A system is a table, a sub query or special keyword. * * @param array|string $system System * @param string $prefix Prefix for table * * @return string * * @since 1.0.0 */ protected function compileSystem($system, string $prefix = '') : string { // todo: this is a bad way to handle select count(*) which doesn't need a prefix. Maybe remove prefixes in total? $identifier = $this->systemIdentifier; foreach ($this->specialKeywords as $keyword) { if (strrpos($system, $keyword, -strlen($system)) !== false) { $prefix = ''; $identifier = ''; } } // todo: move remaining * test also here not just if .* but also if * (should be done in else?) if (count($split = explode('.', $system)) === 2) { $system = $split[1] === '*' ? $split[1] : $this->compileSystem($split[1]); return $this->compileSystem($prefix . $split[0]) . '.' . $system; } return $identifier . $prefix . $system . $identifier; } }