} * @return string * @author Christian Fraß */ function conjunction( array $expressions ) : string { return ( implode( ' AND ', array_map( function (string $expression) : string { return sprintf('(%s)', $expression); }, $expressions ) ) ); } /** * @param array $expressions {list} * @return string * @author Christian Fraß */ function disjunction( array $expressions ) : string { return ( implode( ' OR ', array_map( function (string $expression) : string { return sprintf('(%s)', $expression); }, $expressions ) ) ); } /** * expression to check if two sets (~ 1 column tables) are equal (in their elements, not in their order) * warning: won't work for empty sets * * @author Christian Fraß */ function set_equal( string $set1, string $set2 ) : string { // (x \ y) ∪ (y \ x) = {} return sprintf( '(NOT EXISTS (SELECT value FROM (%s) WHERE NOT (value IN (%s)) UNION SELECT value FROM (%s) WHERE NOT (value IN (%s))))', $set1, $set2, $set2, $set1 ); } /** * @param mixed $value * @param \Closure $escape * @return string * @author Christian Fraß */ function format( $value, \Closure $escape = null ) : string { if ($escape === null) { $escape = ( function ($x) { $replacements = [ '\'' => '\'\'', ';' => '\\;', ]; $y = $x; foreach ($replacements as $from => $to) { $y = str_replace($from, $to, $y); } return $y; } ); } if ($value === null) { return 'NULL'; } else { $type = gettype($value); switch ($type) { case 'boolean': { return ($value ? 'TRUE' : 'FALSE'); break; } case 'integer': { return sprintf('%d', $value); break; } case 'float': case 'double': { return sprintf('%.4f', $value); break; } case 'string': { return sprintf('\'%s\'', $escape($value)); break; } case 'array': { return sprintf( '(%s)', implode( ',', array_map( function ($element) : string { return format($element); }, ( empty($value) ? ['___DUMMY_VALUE___'] : $value ) ) ) ); } default: { throw (new \Exception(sprintf('unhandled type "%s" of value %s', $type, json_encode($value)))); break; } } } }