示例#1
0
 /**
  * @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->convertStringToSql($value);
                 case 'i':
                 case '?i':
                     if (!preg_match('#^-?[1-9][0-9]*+\\z#', $value)) {
                         break;
                     }
                     return (string) $value;
                 case '_like':
                     return $this->driver->convertLikeToSql($value, -1);
                 case 'like_':
                     return $this->driver->convertLikeToSql($value, 1);
                 case '_like_':
                     return $this->driver->convertLikeToSql($value, 0);
                 case 'column':
                     if ($value === '*') {
                         return '*';
                     }
                     // intential pass-through
                 // intential pass-through
                 case 'table':
                     return $this->identifiers->{$value};
                 case 'blob':
                     return $this->driver->convertBlobToSql($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->convertBoolToSql($value);
             }
             break;
         case 'NULL':
             switch ($type) {
                 case 'any':
                 case '?s':
                 case '?i':
                 case '?f':
                 case '?b':
                 case '?dt':
                 case '?dts':
                 case '?di':
                 case '?blob':
                     return 'NULL';
             }
             break;
         case 'object':
             if ($value instanceof \DateTimeImmutable || $value instanceof \DateTime) {
                 switch ($type) {
                     case 'any':
                     case 'dt':
                     case '?dt':
                         return $this->driver->convertDateTimeToSql($value);
                     case 'dts':
                     case '?dts':
                         return $this->driver->convertDateTimeSimpleToSql($value);
                 }
             } elseif ($value instanceof \DateInterval) {
                 switch ($type) {
                     case 'any':
                     case 'di':
                     case '?di':
                         return $this->driver->convertDateIntervalToSql($value);
                 }
             } elseif (method_exists($value, '__toString')) {
                 switch ($type) {
                     case 'any':
                     case 's':
                     case '?s':
                         return $this->driver->convertStringToSql((string) $value);
                     case '_like':
                         return $this->driver->convertLikeToSql($value, -1);
                     case 'like_':
                         return $this->driver->convertLikeToSql($value, 1);
                     case '_like_':
                         return $this->driver->convertLikeToSql($value, 0);
                 }
             }
             break;
         case 'array':
             switch ($type) {
                 // micro-optimizations
                 case 'any':
                     return $this->processArray("any[]", $value);
                 case 'i[]':
                     foreach ($value as $v) {
                         if (!is_int($v)) {
                             break 2;
                         }
                         // fallback to processArray
                     }
                     return '(' . implode(', ', $value) . ')';
                 case 's[]':
                     foreach ($value as &$subValue) {
                         if (!is_string($subValue)) {
                             break 2;
                         }
                         // fallback to processArray
                         $subValue = $this->driver->convertStringToSql($subValue);
                     }
                     return '(' . implode(', ', $value) . ')';
                     // normal
                 // normal
                 case 'column[]':
                 case 'table[]':
                     $subType = substr($type, 0, -2);
                     foreach ($value as &$subValue) {
                         $subValue = $this->processModifier($subType, $subValue);
                     }
                     return implode(', ', $value);
                 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]);
     }
 }