protected function normalize($data) { foreach ($this->toDriverColumns as $meta) { list($column, $nativeType) = $meta; if ($data[$column] !== NULL) { $data[$column] = $this->driver->convertToPhp($data[$column], $nativeType); } } foreach ($this->toIntColumns as $column) { if ($data[$column] !== NULL) { $data[$column] = (int) $data[$column]; } } foreach ($this->toFloatColumns as $column) { if ($data[$column] !== NULL) { $data[$column] = (double) $data[$column]; } } foreach ($this->toBoolColumns as $column) { if ($data[$column] !== NULL) { $data[$column] = (bool) $data[$column]; } } foreach ($this->toStringColumns as $column) { if ($data[$column] !== NULL) { $data[$column] = (string) $data[$column]; } } foreach ($this->toDateTimeColumns as $column) { if ($data[$column] !== NULL) { $data[$column] = (new DateTime($data[$column]))->setTimezone($this->applicationTimeZone); } } return $data; }
/** * Pings a database connection and tries to reconnect it if it is broken. * @return bool */ public function ping() { try { $this->connected || $this->connect(); return $this->driver->ping(); } catch (DriverException $e) { return FALSE; } }
/** * @param string $type * @param mixed $value * @return string */ public function processModifier($type, $value) { switch (gettype($value)) { case 'string': switch ($type) { case 'any': case 's': case '?s': return $this->driver->convertToSql($value, IDriver::TYPE_STRING); case 'i': case '?i': if (!preg_match('#^-?[1-9][0-9]*+\\z#', $value)) { break; } return (string) $value; case 'table': case 'column': if ($value === '*') { $this->throwWrongModifierException($type, $value, "{$type}[]"); } return $this->identifiers->{$value}; case 'raw': return $value; } break; case 'integer': switch ($type) { case 'any': case 'i': case '?i': return (string) $value; } break; case 'double': if (is_finite($value)) { // database can not handle INF and NAN switch ($type) { case 'any': case 'f': case '?f': return ($tmp = json_encode($value)) . (strpos($tmp, '.') === FALSE ? '.0' : ''); } } break; case 'boolean': switch ($type) { case 'any': case 'b': case '?b': return $this->driver->convertToSql($value, IDriver::TYPE_BOOL); } break; case 'NULL': switch ($type) { case 'any': case '?s': case '?i': case '?f': case '?b': case '?dt': case '?dts': case '?di': return 'NULL'; } break; case 'object': if ($value instanceof \DateTimeImmutable || $value instanceof \DateTime) { switch ($type) { case 'any': case 'dt': case '?dt': return $this->driver->convertToSql($value, IDriver::TYPE_DATETIME); case 'dts': case '?dts': return $this->driver->convertToSql($value, IDriver::TYPE_DATETIME_SIMPLE); } } elseif ($value instanceof \DateInterval) { switch ($type) { case 'any': case 'di': case '?di': return $this->driver->convertToSql($value, IDriver::TYPE_DATE_INTERVAL); } } elseif (method_exists($value, '__toString')) { switch ($type) { case 'any': case 's': case '?s': return $this->driver->convertToSql((string) $value, IDriver::TYPE_STRING); } } break; case 'array': switch ($type) { // micro-optimizations case 'any': return $this->processArray("any[]", $value); case 'i[]': $i = count($value); while ($i-- && is_int($value[$i])) { } if ($i >= 0) { break; } // fallback to processArray return '(' . implode(', ', $value) . ')'; case 's[]': foreach ($value as &$subValue) { if (!is_string($subValue)) { break 2; } // fallback to processArray $subValue = $this->driver->convertToSql($subValue, IDriver::TYPE_STRING); } return '(' . implode(', ', $value) . ')'; case 'column[]': foreach ($value as &$subValue) { if (!is_string($subValue)) { break 2; } // fallback to processArray $subValue = $this->identifiers->{$subValue}; } return '(' . implode(', ', $value) . ')'; // normal // normal case 'and': case 'or': return $this->processWhere($type, $value); case 'values': return $this->processValues($type, $value); case 'values[]': return $this->processMultiValues($type, $value); case 'set': return $this->processSet($type, $value); case 'ex': return $this->process($value); } if (substr($type, -1) === ']') { $baseType = trim($type, '[]?'); if (isset($this->modifiers[$baseType]) && $this->modifiers[$baseType][1]) { return $this->processArray($type, $value); } } } $baseType = trim($type, '[]?'); $typeNullable = $type[0] === '?'; $typeArray = substr($type, -2) === '[]'; if (!isset($this->modifiers[$baseType])) { throw new InvalidArgumentException("Unknown modifier %{$type}."); } elseif ($typeNullable && !$this->modifiers[$baseType][0] || $typeArray && !$this->modifiers[$baseType][1]) { throw new InvalidArgumentException("Modifier %{$baseType} does not have %{$type} variant."); } elseif ($typeArray) { $this->throwInvalidValueTypeException($type, $value, 'array'); } elseif ($value === NULL && !$typeNullable && $this->modifiers[$baseType][0]) { $this->throwWrongModifierException($type, $value, "?{$type}"); } elseif (is_array($value) && !$typeArray && $this->modifiers[$baseType][1]) { $this->throwWrongModifierException($type, $value, "{$type}[]"); } else { $this->throwInvalidValueTypeException($type, $value, $this->modifiers[$baseType][2]); } }